C程序设计实践——实验指导

一、课程的总体目标和具体要求

总体目标:

  1. 利用C语言和程序设计方法编制程序,借助计算机解决问题的基本能力。(支撑毕业能力要求1)
  2. 独立解决文本处理、数学上的一些问题,编写较规范化的代码。(支撑毕业能力要求3)
  3. 综合运用数学和程序设计方法,设计有实用背景和一定规模的应用问题的解决方案,可在较短计划时间内实现核心代码,撰写实验报告。(支撑毕业能力要求3)
  4. 选择、运用工具构建实验、项目并熟练进行程序编辑、调试、运行得到结果。(支撑毕业能力要求4)

具体要求:
1.了解和使用Turbo C和Visual C++6.0的集成开发环境
2.理解C语言的程序结构
3.熟练掌握输入输出等交互方式
4.体会将待处理的问题转换为算法描述,学会发现规律,并编程实现
5.体会用计算机进行数学计算的特点
6.熟练掌握选择结构流程控制
7.熟练掌握不同的条件控制语句,体会其应用方法
8.熟练掌握循环结构流程控制
9.熟练掌握选择结构与循环结构的嵌套
10.掌握一维数组和二维数组的定义、赋值和输入输出方法
11.掌握主要的数组有关的算法
12.学会进行矩阵运算
13.字符处理及字符数组的使用
14.掌握函数的定义与使用
15.理解函数的参数传递方式,掌握函数传值及传址方法
16.掌握指针的概念和使用方法
17.比较指针操作与数组操作的一致性
18.体会指针在字符串操作中的应用
19.学习C语言中复杂数据类型的定义和使用方法
20.学习应用位运算
21.学会测试程序,发现非语法方面的错误
22.学习考虑边界条件,学习从用户角度思考问题
23.查找资料,自学图形设计相关内容
24.完成有实用背景的应用程序的设计、编程、调试全过程并撰写实验报告

二、实验环境

计算机的硬件环境:
目前各实验室使用的PC兼容机或品牌机,均能满足该课的实验要求。
计算机的软件环境:
在Windows 操作系统环境下,使用Turbo C或Visual C++6.0可视化程序语言。
Turbo C是一个常用的、最基本的C语言工具,一般简称TC。它为C语言开发提供了操作便利的集成环境。源程序的输入、修改、调试及运行都可以在TC集成环境下完成,非常方便有效。TC系统非常小巧,但功能齐全。它主要支持DOS环境,因此在操作中无法使用鼠标,更多的需要通过键盘操纵菜单或快捷键完成。
C++是一个面向对象的程序设计(OOP)语言,是C语言的进一步发展,已成为当今最流行的一种程序设计语言。Visual C++6.0是Windows环境下最主要的应用开发系统之一,它是C++语言的集成开发环境,也可以很好地进行C语言应用程序的开发。

三、实验内容及主要设计思路、算法原理

第一部分 基本程序

1. 第一天内容

讲解内容:
选择结构:if语句、switch语句;
循环结构:while语句、do_while语句、for语句;
函数:函数的定义、函数说明、函数的调用。
重点讲解函数的设计思路。
练习内容:

1.1

编写一个函数fun,然后设计主函数调用函数fun。函数fun的功能是:求两数平方根之和,作为函数值返回。例如:输入12和20,输出结果为: y = 7.936238。

#include<stdio.h>
#include<math.h>
double fun(int m,int n)
{
    
    
	double s;
	s=sqrt(m)+sqrt(n);
	return s;
}
void main()
{
    
    
	int a,b;
	printf("请输入两个要求平方根的数:");
	scanf("%d%d",&a,&b);
	printf("%lf",fun(a,b));
}

1.2

编写一个函数fun,然后设计主函数调用函数fun。函数fun的功能是:计算正整数num的各位上的数字之积。例如,若输入:252,则输出应该是:20。若输入:202,则输出应该是:0。

#include<stdio.h>
int fun(int x)
{
    
    
    int a=1;
	while(x)
	{
    
    
	    a *= (x % 10);
		x /= 10;
	}
	return a;
}
void main()
{
    
    
     int p;
	 printf("请输入一个整数:");
	 scanf("%d",&p);
	 printf("%d\n",fun(p));
}

1.3

编写一个函数fun,然后设计主函数调用函数fun。函数fun的功能是:通过某种方式实现两个变量值的交换。例如变量a中的值原为5,b中的值原为3,程序运行后a中的值为3,b中的值为5。

#include<stdio.h>
void fun(int *a,int *b)
{
    
    
     int p;
	 p=*a;
	 *a=*b;
	 *b=p;	 
}
void main()
{
    
    
     int x,y;
	 printf("请输入要交换的两个数:");
	 scanf("%d %d",&x,&y);
     printf("交换前:");
     printf("%d %d\n",x,y);
	 fun(&x,&y);
     printf("交换后:");
	 printf("%d %d\n",x,y);
}

1.4

编写一个函数fun,然后设计主函数调用函数fun。函数fun的功能是:求出两个非零正整数的最大公约数(考虑递归和非递归两种方法,任选一种实现),并作为函数值返回。再设计一个函数,函数的功能是计算两个非零正整数的最小公倍数。

#include<stdio.h>
int fun(int u,int v)
{
    
    
	int y,t,s;
	s=u*v;
	if(u<v)
	{
    
    
	     t=u;
		 u=v;
		 v=t;
	}
	while(v)
	{
    
    
	    y=u%v;
		u=v;
		v=y;
	}
	return u;
}

int fun_(int x,int y)
{
    
    
    return x*y/fun(x,y);
}
void main()
{
    
    
     int x,y;
     printf("请输入两个数:");//求最大公因数与最小公倍数//
	 scanf("%d %d",&x,&y);
     printf("最大公因数:");
	 printf("MAX:%d\n",fun(x,y));
     printf("最小公倍数:");
	 printf("min:%d\n",fun_(x,y));
}

5. 用下述公式求π的近似值,直到最后一项的绝对值小于指定的数(参数num)为止:

Π/4≈1-1/3 + 1/5- 1/7+……
例如,若输入值为0.0001,则程序的输出3.1414。

#include<math.h>
#include<stdio.h>
float fun(float num)
{
    
    
	int s;
float n,t,pi;
t=1; pi=0; n=1; s=1;
while(fabs(t)>=num)
{
    
    
   pi=pi+t;
   n=n+2;
   s=-s;
   t=s/n;
   
} pi=pi*4;
return pi;
}
 void main()
{
    
    
	float n1,n2;
     /*	clrscr ();*/
	printf("Enter a float number:");
	scanf("%f",&n1);
	n2=fun(n1);
	printf("%6.4f\n",n2);
}

2. 第二天内容

讲解内容:进制转换的基本设计思想,循环结构程序设计的一般规律,用程序实现数学表达的方法。
练习内容:

2.1

请编写函数float fun(float x, int m),它的功能是:将浮点数x保留m位小数(m不大于6),第m+1位四舍五入。例如,输入123.456,保留2位小数应输出123.46(或123.459999)。

#include<stdio.h>
#include<math.h>
double fun(double m,int n)
{
    
    
     m*=pow(10,n);
	 if(m-(int)(m)>=0.5)
		 m++;
	 else
		 m=m-(m-(int)(m));
	 m=(int)m/(double)pow(10,n);
     return m;
}
void main()
{
    
    
     double m;
	 int n;
	 scanf("%lf",&m);
	 scanf("%d",&n);
	 printf("%lf",fun(m,n));
}

2.2

请编写一个函数unsigned fun ( unsigned w ), w是一个大于10的无符号整数,若w是n (n≥2)位的整数,函数求出w的后n-1位的数作为函数值返回。

#include<stdio.h>
#include<math.h>
unsigned fun(unsigned w)
{
    
    
     int n=0,t;
	 int m=w;
	 while(w)
	 {
    
    
	     n++;
		 t=w;
		 w/=10;
	 }
	 w=m-(t*pow(10,n-1));
	 return w;
}
void main()
{
    
    
     unsigned w;
	 scanf("%d",&w);
	 fun(w);
	 printf("%d",w);
}

2.3

编写一个函数fun,函数fun的功能是:从低位开始取出长整型变量s中偶数位上的数,依次构成一个新数放在t中。例如,当s中的数为:7654321时,t中的数为:642.

#include<stdio.h>
#include<math.h>
long fun(long s)
{
    
    
	long n=0,t1;
	long t;
     while(s)
	 {
    
    
	     s/=10;
		 t1=s%10;
		 s/=10;
		 t+=t1*pow(10,n);
		 n++;
	 }
	 return t;
}
void main()
{
    
    
     long s;
	 scanf("%ld",&s);
	 printf("%ld",fun(s));
}

2.4

将十进制正整数转换成k进制(2<=k<=9)数的数字输出。例如,若输入8和2,则应输出1000(即十进制数8转换成二进制表示1000)。


#include<stdio.h>
int main()
{
    
    
	int a,b,c=0,d=1;
	scanf("%d",&a);
	scanf("%d",&b);
	for(;a!=0;)
	{
    
    
		c=c+a%b*d;
		a=a/b;
		d=d*10;
	}
	printf("%d",c);
	return 0;
}

2.5

求出1!、3!、5!、…、k!(k是小于9的奇数)。例如:若k=7,则应输出: 1.00000 6.00000 120.00000 5040.00000。

#include<stdio.h>
void main()
{
    
    
    double k,d,s=1;
	printf("k是小于9的奇数:");
	scanf("%lf",&k);
	while(k>0)
	{
    
    
	   d=k;
	   s=1;
	   while(d)
	   {
    
    
           s*=d;
		   d--;
	   }
	   printf("%lf\n",s);   
	   k-=2;
	}
}

2.6

求 (此处a和n的值在1至9之间, 表示由n个a组成的整数)
例如,a=2,n=6,则以上表达式为:
s=222222-22222-2222-222-22-2
其和值是:197532。

#include<stdio.h>
void main()
{
    
    
     int i,j,s=0,t;
	 int a,n;
	 scanf("%d %d",&a,&n);
	 for(i=0;i<n;i++)
	 {
    
    
		 s+=a;
		 a=a*10;
	 }
	 t=s;
	 while(t)
	 {
    
    
		 t/=10;
	     s-=t;
	 }
	 printf("%d",s);
}

2.7

编写一个函数float fun(float eps),它的功能是:
根据如下公式计算e的值:1+1/1!+1/2!+1/3!+…+1/n!+…
其中的eps是指定的精度。

#include<stdio.h>
float fun(float eps)
{
    
    
     float e=1;
	 float i,j,s=1;
	 for(i=1;1/i>eps;i++)
	 {
    
    
		 i=j;
		 while(j)
		 {
    
    
		     s*=j;
			 j--;
		 }
	     e+=1/s;
	 }
     return e;
}
void main(){
    
    
    float h;
	scanf("%f",&h);
    printf("%f",fun(h));}

2.8

编写一个函数fun,然后设计主函数调用函数fun。
函数fun的功能是:统计不超过一个整数m(包括m且m>=3)的素数个数(不包括1和2)。

#include<stdio.h>
int fun(int s)
{
    
    
	int i,j,k;
	k=0;
	for(i=3;i<=s;i++)
	{
    
    
		for(j=2;j<i;j++)
		{
    
    
			if(i%j==0)
				break;
			if(j==i-1)
				k++;
		}
	}
	return k;
}
void main()
{
    
    
	int m;
	scanf("%d",&m);
	printf("%d",fun(m));
}

3. 第三天内容

讲解内容:指针的概念与运算、指针作函数的参数、一维数组的定义和引用、一维数组和指针的关系、字符数组作字符串变量、指向字符串常量的指针变量、字符串操作函数。重点讲解指针操作数组的思路。
练习内容:

3.1

编写一个函数len,其功能是计算出一个字符串中含有的所有字符个数(不使用库函数strlen)。

#include<stdio.h>
int len(char *s)
{
    
    
    int n=0;
	while(*s)
	{
    
    
	    n++;
		s++;
	}
	return n;
}

void main()
{
    
    
     char s[100];
	 gets(s);
	 printf("%d\n",len(s));
}

3.2

编写函数fun,函数的功能是:计算一个字符串s中的所含有的指定字符的个数,返回此值。
例如,输入字符串"Thisisastring",被查找字符为’i’,则应输出3。

#include<stdio.h>
int fun(char *s,char k)
{
    
    
	int n;
	n=0;
	while(*s)
	{
    
    
		if(*s==k)
			n++;
		s++;
	}
	return n;
}
void main()
{
    
    
	int s;
	char a[100],k;
	gets(a);
	scanf("%c",&k);
	s=fun(a,k);
	printf("%d",s);
}

3.3

编写程序,读入一个英文文本行,将其中每个单词的第一个字母改成大写,然后输出此文本行(这里的“单词”是指由空格隔开的字符串)。

#include<stdio.h>
#include<string.h>
void main()
{
    
    
	char a[100];
	int k,i;
	while(gets(a))
	{
    
    
		k=strlen(a);
		a[0]-=32;
		for(i=0;i<k;i++)
		{
    
    
			if(a[i]==' ')
				a[i+1]-=32;
			printf("%c",a[i]);
		}
		printf("\n");}}

3.4

编写函数fun,其功能是删除一个字符串中的所有空格。
例如,输入字符串"This is a string",则应输出"Thisisastring"。

#include<stdio.h>
void fun(char *s)
{
    
    
	char *p;
	while(*s)
	{
    
    
		if(*s==' ')
		{
    
    
			p=s;
			while(*p)
			{
    
    
				*p=*(p+1);
			p++;
			}
		}
		else
			s++;
	}}
void main()
{
    
    
	char a[100];
	gets(a);
	fun(a);
	puts(a);
}			

3.5

编写函数fun,函数fun 的功能是:将字符串a中的所有字符复制到字符串b中,要求每复制三个字符之后插入一个空格。

#include<stdio.h>
void fun(char *a,char *b)
{
    
    
	 int i;
     while(*a)
	 {
    
    
	      for(i=0;i<3;i++)
		  {
    
    
		      *b=*a;
			  if(*a='\0')
				  break;
			  a++;
			  b++;
		  }
		  while(*a!='\0')
		  {
    
    
		  *b=' ';
		  b++;
		  break;
		  }}}
void main()
{
    
    
     char a[100],b[100];
	 gets(a);
	 fun(a,b);
	 puts(b);
}

3.6

编写函数,函数fun的功能是:在字符串str中找出ASCII码值最大的字符,将其放在第一个位置上,并将该字符前的原字符向后顺序移动。

#include<stdio.h>
void fun(char *p)
{
    
    
    char max;
    int i=0,q;
    max=p[0];
    while(p[i])
    {
    
    
        if(max<p[i])
         {
    
    
            max=p[i];
           q=i;
        }
           i++;
    }
    while(q)
    {
    
    
        p[q]=p[q-1];
        q--;
    }
    p[0]=max;
}
void main(){
    
     
char str[80];
gets(str);
fun(str);
printf("移动后:");
puts(str);
}

3.7

编写函数,函数fun 的功能是:首先把b所指字符串中的字符按逆序存放,然后将a所指字符串中的字符和b所指字符串中的字符,按排列的顺序交叉合并到c所指数组中,过长的剩余字符接在c所指数组的尾部。
例如,当a所指字符串中的内容为“abcdefg”,b所指字符串中的内容为“1234”时,c所指数组中的内容应该为“a4b3c2d1efg”;而当a所指字符串中的内容为“1234”,b所指字符串中的内容为“abcdefg”时,c所指数组中的内容应该为“1g2f3e4dcba”。

#include<stdio.h>
#include<string.h>
void fun(char *a,char *b,char *c)
{
    
    
    int i,j,n,k;
    int p;
    char t;
    k=0;
    j=strlen(b)-1;
    for(i=0;i<j;i++)
    {
    
    
        t=b[i];
        b[i]=b[j];
        b[j]=t;
        j--;
    }
    j=0;p=0;
    n=strlen(a)+strlen(b);
    for(i=0;i<=n;i++)
    {
    
    
        if(i%2==0)
        {
    
    
            if(a[j]!='\0')
            {
    
    
                c[k]=a[j];
                k++;
                j++;
            }
            if(a[j]=='\0')
            {
    
    
                c[k]=b[p];
                k++;
                p++;
            }
        }
        if(i%2==1)
        {
    
    
            if(b[p]!='\0')
            {
    
    
                c[k]=b[p];
                k++;
                p++;
            }
            if(b[p]=='\0')
            {
    
    
                c[k]=a[j];
                j++;
                k++;
            }}}}
void main()
{
    
    
    char a[100],b[100],c[100];
    gets(a);
    gets(b);
    fun(a,b,c);
    puts(c);
}

4. 第四天内容

讲解内容:选择排序法、冒泡排序法、简单插入排序法和查找与替换方法。引导学生考虑设计高效的算法。
练习内容:

4.1

用选择排序法对数组a的元素从小到大排序。例如,输入2 5 4 1 6 2 7 3 2 9 4,则应输出1 2 2 2 3 4 5 6 7 9。
选择排序法采取如下思想对数组a的元素从小到大排序:
将数组a的元素处理n-1次,第k次处理时仅处理前n-k个元素,方法是选择出这k个元素中的最大元素,并将其与这些元素中的最后一个交换。当然,也可以按每次选择最小元素的办法进行选择排序。

# include<stdio.h>
void sort(int *a,int n)
{
    
    
int i,j,t,m;
for (i = 0; i < n - 1; i++){
    
    
m = i;
for (j = i + 1; j < n; j++)
if ( *(a+j)<*(a+m) )
m = j;
if(i!=m)
{
    
    
t=*(a+i);
*(a+i)=*(a+m);
*(a+m)=t;}}}
void main()
{
    
    
int i,n,a[100];
printf("请输入数组个数n:");
scanf("%d",&n);
printf("请输入%d个元素:",n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,n);
for(i=0;i<n;i++)
printf("%-7d",a[i]);
}

4.2

下述程序中,函数fun的功能是:用冒泡法对6个字符串按由小到大的顺序进行排序。
冒泡排序基本思路:所谓“冒泡排序”,也称“起泡排序”或者“气泡排序”,是指这样的一种简单排序方法,若被排序的数组元素个数为N,可以对此数组做N-1次处理。
在第k次(k=0, 1, …, N-1)处理时,需比较前N-k个元素,方法是:连续从前到后比较相邻的两个元素,如果后面的元素小于前面的元素,则将二者交换,否则不变。
可见,每经过一次处理,至少此次被处理的N-k个元素中的最大元素被移到了本次处理的最后位置,而N-1次处理后就使所有的元素被排序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int maopao(int *a,int size)
{
    
    
int i,j,t;
if(size <= 0) return -1;
if(a == NULL ) return -1;
for(i=0;i<size-1;i++)
{
    
    
for(j=0;j<size -1 -i;j++)
{
    
    
if(a[j] > a[j+1])
{
    
    
t = a[j] ;
a[j] = a[j+1];
a[j+1] = t;}}}
return 0;
}

int main(int argc, const char *argv[])
{
    
    
int i ,ret,b[10]={
    
    0};
printf("从终端输入10个数:");
for(i=0;i<10;i++)
{
    
    
scanf("%d",&b[i]);
}
printf("数组的内容:");
for(i=0;i<10;i++)
{
    
    
printf("%4d",b[i]);
}
printf("\n");
printf("数组升序排列后:");
ret = maopao(b,10);
if(ret < 0 )
{
    
    
printf("maopao is error\n");
exit(-1);
}
for(i=0;i<10;i++)
{
    
    
printf("%4d",b[i]);
}
printf("\n");
return 0;
}

4.3

编写函数fun,函数fun的功能是:利用插入排序法对字符串中的字符按从小到大的顺序进行排序。
插入法的基本算法思路是:先对字符串中的头两个元素进行排序。然后把第三个字符插入到前两个字符中,插入后前三个字符依然有序;再把第四个字符插入到前三个字符中,……。待排序的字符串已在主函数中赋值。

#include<stdio.h>
#include<string.h>
#define N 80
void fun(char *a)
{
    
    
    int i,j,n;
	char ch;
	n=strlen(a);
	for(i=1;i<n;i++)
	{
    
    
	    ch=a[i];
		j=i-1;
		while((j>=0)&&(ch<a[j]))
		{
    
    
		    a[j+1]=a[j];
			j--;
		}
		a[j+1]=ch;
	}}
void main()
{
    
    
    char a[N];
	gets(a);
	fun(a);
	puts(a);
}

4.4

编写一个函数,其功能是统计一个子字符串在另一个字符串中出现的次数。例如,假定输入的字符串为"this is a string",子字符串为"is",则应输出2。
设计思路:

⑴分析参数与返回值。

本例中函数fun的参数的含义为:母字符串str和子字符串sub。该函数需要统计子字符串出现的个数,返回值是int类型,必然是统计后所得的出现次数值,观察main函数中的输出也能肯定这一点。

⑵整理编程思路。

编写该函数需要使用一个循环,循环中可以考虑通过一个字符类型的指针在str中由前到后移动,每次移动一个字符位,且将目前指针位置开始的m个字符与sub所包含的全部m个字符比较(假定sub的长度是m),若二者相同则说明子字符串在母字符串中出现一次,进行累计,否则不累计。无论如何,将指针再移到下一个字符位,进行下一次循环比较。

⑶细节考虑。

首先,为了实现两组m个字符的比较,一个可行的办法是写一个函数来实现,但程序不允许再编写其它函数,只能使用库函数或自己构成循环。能够使用的库函数是定义在string.h中的strstr,其函数原型如下:
char* strstr(char* str, char* sub)

#include<stdio.h>
int fun(char *a,char *b)
{
    
    
     char *p;
	 int n=0;
	 while(*a)
	 {
    
    
		 p=b;
		 if(*a==*p)
         {
    
     
	        while(*a==*p)
			{
    
    
		       a++;
			   p++;
			   if(*p=='\0')
			   {
    
    
			      n++;
			   }}}
		 else
		 {
    
    
		     a++;
		 }}
	 return n;
}
void main()
{
    
    
    char a[100],b[20];
	gets(a);
	gets(b);
	printf("%d\n",fun(a,b));
}

4.5

N个有序整数数列已放在一堆数组中。下述程序中的函数fun的功能是:利用折半查找算法查找整数m在数组中的位置。若找到返回其下标值;反之,返回-1
折半查找设计思想:折半查找也称为二分查找或二分检索,其基本思想是,在一个数组中查找某个值m是否存在时,每次查找前先确定数组中待查的范围:low和hitgh (low <high),然后把m与中间位置(mid)上元素的值进行比较。
如果m的值大于中间位置元素中的值,则下一次的查找范围放在中间位置之后的元素中;反之,下一次的查找范围落在中间位置之前的元素中。直到low>high,查找结束。

#include<stdio.h>
int fun(int *s,int m)
{
    
    
     int low=0,high,mid;
	 high=sizeof(s)/2;
	 mid=(low+high)/2;
	 while(1)
	 if(m>s[mid])
	 {
    
    
	     low=mid+1;
		 mid=(low+high)/2;}
	 else
		 if(m<s[mid])
		 {
    
    
		     high=mid-1;
			 mid=(low+high)/2;}
		 else
		 {
    
    
		   return mid;}
     return -1;
}
void main()
{
    
    
     int a[100];
	 int b,i;
	 for(i=0;i<10;i++)
		 scanf("%d",&a[i]);
	 scanf("%d",&b);
     printf("%d",fun(a,b));	 }

4.6

请编写函数int* fun(char* st),其中st是仅由字符a、b和c组成的字符串。
函数的功能是:统计字符串st中’a’、’b’和’c’的个数并分别存入不同的内存区,带回内存区的首地址。

#include<stdio.h>
int* fun(char *st,int a[3])
{
    
    
	while(*st)
	{
    
    
	      if(*st=='a')
		  {
    
    
		     a[0]++;
		  }
		  if(*st=='b')
		  {
    
    
		     a[1]++;
		  }
		  if(*st=='c')
		  {
    
    
		     a[2]++;
		  }
          st++;
	}
	return a;}
void main()
{
    
    
	char a[100];
	int b[3]={
    
    0,0,0};
	int i;
	int *p;
	gets(a);
	p=fun(a,b);
	for(i=0;i<3;i++)
		printf("%d,",*p++);
}

5. 第五天内容

讲解内容:二维数组的定义、引用与初始化、二维数组与指针的关系(二维数组的一维表示、对二维数组的约定、指向一维数组的指针变量、二维数组作函数的参数和用二维数组操作字符串)。
练习内容:

5.1

将数组x的元素倒置输出。例如,若输入1 2 3 4 5,则应输出5 4 3 2 1。

#include<stdio.h>
void main()
{
    
    
    int i,n,a[10];
    printf("请输入数组个数:");
    scanf("%d",&n);
    printf("请输入数组:");
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
        for(i=n-1;i>=0;i--)
            printf("%2d",a[i]);
}

5.2

请编写函数void fun ( int aa[ ], int x, int *n ),它的功能是:删除数组aa中所有与x相等的元素,数组元素个数由n传入。

#include<stdio.h>
void fun(int aa[],int x,int *n)
{
    
    
    int i,j;
     for(i=0;i<*n;i++)
   {
    
    
       if(aa[i]==x)
       {
    
    
           for(j=i;j<*n-1;j++)
            aa[j]=aa[j+1];
          (*n)--;
           i--;}}}
void main()
{
    
    
    int a[100],x;
    int n,i;
    printf("请输入数组元素个数:");
    scanf("%d",&n);
    printf("请输入数组:");
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
        printf("请输入删除的元素:");
        scanf("%d",&x);
            fun(a,x,&n);
            for(i=0;i<n;i++)
                printf("%2d",a[i]);
}

5.3

请编函数void fun(int *a, int *b),它的功能是:求出1到100之内被7或11整除的所有整数放在数组a中,通过n返回这些数的个数。

#include <stdio.h> 
void fun(int *a, int *b) 
{
    
     
    int i; 
    for (i = 1; i <=100; i++)
        if (i%7==0 || i%11==0)  
		{
    
    
			*a=i;
			a++;
			(*b)++;}} 
     
int main() 
{
    
     
    int i,n=0;
	int m[100];
	fun(m,&n);
	printf("%d\n",n);
	for(i=0;i<n;i++)
	printf("%d",m[i]);
	return 0; 
}

5.4

编写函数int fun (int lim, int aa[MAX] ),该函数的功能是求出小于lim的所有素数并放在aa数组中,该函数返回所求出素数的个数。然后编写主函数调用它。

#include<stdio.h>
int fun(int lim,int aa[100])
{
    
    
     int i,MAX=0,j;
     for(i=0;i<=lim;i++)
	 {
    
    
	       for(j=2;j<i;j++)
		   {
    
    
		       if(i%j==0)
				   break;
			   if(i==j+1)
			   {
    
    
				   aa[MAX]=i;
			       MAX++;
			   }}}
	 return MAX;
}
void main()
{
    
    
     int lim,aa[100];
	 scanf("%d",&lim);
	 printf("%d",fun(lim,aa));
}

5.5

输入一个3行3列矩阵的所有元素,然后输出对角线元素之和。

#include<stdio.h>
void main()
{
    
    
	int a[3][3];
	int i,j,s=0;
	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
		{
    
    
		    scanf("%d",&a[i][j]);
		}
	for(i=0;i<3;i++)
	{
    
    
	     s+=a[i][i];
	}
	printf("%d",s);
}

5.6

编写函数,其功能是:实现矩阵(3行3列)的转置(即行列互换)。

#include<stdio.h>
void main()
{
    
    
	int a[3][3],i,j;
	for(i=0;i<9;i++)
    scanf("%d",&a[0][0]+i);
	printf("原矩阵:\n");
	for(i=0;i<9;i++)
	{
    
    	printf("%2d",a[0][0]+i);   
	    if(i%3==2)
			printf("\n");
	}
	printf("转置后矩阵:\n");
	for(i=0;i<3;i++)
	{
    
    
		for(j=0;j<3;j++)
		{
    
    	printf("%2d",a[j][i]);
		    if(j==2)
			   printf("\n");
		}}}

6. 第六天内容

讲解内容:递归函数、动态内存管理、结构体类型的定义、结构体变量的定义、结构体变量的成员、整体引用结构体、结构体数据在函数间传递、结构体变量的初始化、结构体数组、结构体指针、单链表。重点讲解链表。
练习内容:

6.1

请编写函数int fun(double a[ ], int k, int m, double x),它的功能是:用递归方法在数组a中查找x是否出现,其中数组a的元素已按由大到小的次序排序,k和m是数组的最小和最大下标,函数采用二分查找算法,若找到则返回1,否则返回0。

#include<stdio.h>
#include<malloc.h>
typedef struct node
{
    
    
    int data;
    struct node *next;
}NODE;
#define LEN sizeof(NODE)
NODE *setup( )
{
    
    
    NODE *head =NULL, *p1,*p2;
    int n =0;
    p2 =(NODE *)malloc(LEN);
    p1 =p2;
    scanf("%d",&p1->data);
    while(p1->data)
    {
    
    
        n++;
        if(n==1) 
        {
    
    
            head =p1;
        }
        else
        {
    
    
            p2->next =p1;
            p2 = p1;
        }
        p1 =(NODE *)malloc(LEN);
        scanf("%d",&p1->data);
    }
    p2->next =NULL;
    return head;
}

int main()
{
    
    
    NODE *p;
    p = setup();
    while (p)
    {
    
    
        printf("%d,", p->data);
        p = p->next;}}

6.2

用递归法将一个整数n转换成字符串。例如,输入整数483,应输出字符串“483”。

#include<stdio.h>
void fun(int n)
{
    
    
	if(n/10==0)
	{
    
    
	     putchar('0'+n%10);
	}
	else
	{
    
    
	     fun(n/10);
		 putchar('0'+n%10);
	}}
void main()
{
    
    
     int m;
	 scanf("%d",&m);
	 fun(m);
}

6.3

编写一个函数,函数fun的功能是:输入一个整数x,计算x的平方和立方。
例如,输入10,则应输出a=10 a2=100 a3=1000。

#include<stdio.h>
void fun(int s)
{
    
    
	int i,a[2];
	a[0]=s*s;
	a[1]=s*s*s;
	for(i=0;i<2;i++)
		printf("%d\n",a[i]);
}
void main()
{
    
    
	int s;
	scanf("%d",&s);
	fun(s);
}

6.4

学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun,它的功能是:把分数最低的学生数据放在h所指的数组中,
注意:分数最低的学生可能不止一个,函数返回分数最低的学生的人数。

#include<stdio.h>
#define N 3
typedef struct Stu
{
    
    
   char xuehao[10];
   int score;
} Stu;
int fun (Stu *s, Stu * h)
{
    
    
  Stu min;
min = s[0];
int i,c=0;
for (i = 0; i < N; i++)
{
    
    
if (min.score > s[i].score)
min = s[i];
}
for (i = 0; i < N; i++)
{
    
    
if (s[i].score == min.score)
{
    
    
*(h + c) = s[i];
c++;}}
return c;
}
int main ()
{
    
    
Stu s[N] = {
    
     {
    
    "181203101", 97}, {
    
    "181203102", 96}, {
    
    "181203103", 98} };
Stu h[N];
int num,i;
num= fun (s, h);
printf ("The number is: %d\n", num);
for(i=0;i<num;i++)
   {
    
    
       printf("%s  %4d\n",h[i].xuehao,h[i].score);
    }}

6.5

建立一个单向链表,链表中的每个结点有一个int类型的数据域,输入0时标志链表建立过程结束。
例如,输入1 2 3 4 0,则应输出1,2,3,4,。

#include<stdio.h>
#include<malloc.h>
typedef struct node
{
    
    
    int data;
    struct node *next;
}NODE;
#define LEN sizeof(NODE)
NODE *setup( )
{
    
    
    NODE *head =NULL, *p1,*p2;
    int n =0;
    p2 =(NODE *)malloc(LEN);
    p1 =p2;
    scanf("%d",&p1->data);
    while(p1->data)
    {
    
    
        n++;
        if(n==1) 
        {
    
    
            head =p1;
        }
        else
        {
    
    
            p2->next =p1;
            p2 = p1;
        }
        p1 =(NODE *)malloc(LEN);
        scanf("%d",&p1->data);
    }
    p2->next =NULL;
    return head;
}

int main()
{
    
    
    NODE *p;
    p = setup();
    while (p)
    {
    
    
        printf("%d,", p->data);
        p = p->next;}}

第二部分 实用程序设计

讲解内容:采用c语言进行图形设计的方法和思路。
本部分包含了图形应用程序,Turbo C中提供了对图形支持,在c++环境中,通过安装插件实现对标准c图形设计方式的支持,采用c++环境的同学查找相应插件并完成安装,之后采用Turbo C同样的方式完成应用程序设计。
图形系统的有关信息和函数原型都定义于graphics.h中。
1、 初始设置
为了使屏幕能够显示图形,首先要调用initgraph()函数进行初始化,该函数有三个参数,分别对应显示器模式、分辨率、驱动程序路径。
例如:#include <graphics.h> /图形函数/
……
int GraphDriver = DETECT,GraphMode=0; /* DETECT表示自动检测显示器*/
initgraph(&GraphDriver,&GraphMode,"") ; /空串表示在当前路径下查找驱动程序/
……
closegraph();
结束图形程序时应调用closegraph()函数,释放为图形系统分配的资源,回到字符模式。
可以调用视口函数setviewport,在屏幕上开辟一块区域建立一个新的视口。
2、 颜色与填充
前景色设置函数setcolor(int color);
背景色设置函数setbkcolor(int color);
区域填充函数setfillstyle(int pattern,int color);
例如:setbkcolor(WHITE);
setcolor(BLUE);
setfillstyle(SOLID_FILL, RED);
3、 基本绘图函数
画直线函数line();
画圆函数circle();
画弧函数arc();
画矩形函数rectangle();
画多边形函数drawpoly()以及fillpoly(),后者为带填充的多边形。
设置线宽函数setlinestyle();
4、 在图形模式下输出文本
文本输出模式设置函数settextstyle();
文本输出函数outtext();
在指定位置输出文本outtextxy();
要求所有同学通过自学查找和掌握完成任务所需函数用法。
实验内容(下述内容任选其一):

1.时钟模拟程序设计

设计目标:设计一个时钟表盘,能及时读取系统的时间,并根据当前时间计算并绘制出在时钟表盘上时钟时针、分针和秒针的具体位置,形成时钟运转动画。
设计思路参考:
(1)以圆形、椭圆或矩形等绘制时钟边框,设计时钟指针图形(如采用不同宽度、颜色和长度的直线分别代表时针、分针、秒针)。
(2)读取系统时间,转换为时钟时针、分针、秒针当前位置,在屏幕上画出时钟指针,分别计算时针、分针、秒针移动一次所转动的角度,并据此分别计算下一个位置的坐标,按各自的时间间隔刷新时钟指针位置。
(3)以图形或文本方式完成时钟表盘数字绘制,并添加自己设计的个性化元素美化实现效果。

#include "pch.h"
#include <graphics.h>
#include <math.h>
#include <conio.h>
#define PI 3.141592654
void Draw_Dial();
void Draw_Hand(int hour, int minute, int secend); 
int main()
{
    
    
	initgraph(640, 480);
	Draw_Dial();
	setwritemode(R2_XORPEN);
	SYSTEMTIME time;
	while (!_kbhit())
	{
    
    
		GetLocalTime(&time);
		Draw_Hand(time.wHour, time.wMinute, time.wSecond); 
		Sleep(1000);Draw_Hand(time.wHour, time.wMinute, time.wSecond); 
	}
	closegraph();
	return 0;
}

void Draw_Dial()
{
    
    
	setcolor(GREEN);
	circle(320, 240, 160);
	circle(320, 240, 60)
	circle(320, 240, 2);
	setcolor(WHITE);
	int x, y;
	for (int i = 0; i < 60; i++)
	{
    
    
		x = 320 + int(145 * sin(PI * 2 * i / 60));
		y = 240 + int(145 * cos(PI * 2 * i / 60));
		if (i % 15 == 0)
			bar(x - 5, y - 5, x + 5, y + 5);
		else if (i % 5 == 0)
			circle(x, y, 3);
		else
			putpixel(x, y, WHITE);}}

void Draw_Hand(int hour, int minute, int second)
{
    
    
	double h_hour, h_minute, h_second;
	int x_hour, y_hour, x_minute, y_minute, x_second, y_second;
	h_second = second * 2 * PI / 60;
	h_minute = minute * 2 * PI / 60 + h_second / 60;
	h_hour = hour * 2 * PI / 12 + h_minute / 12;
	x_second = int(120 * sin(h_second)); y_second = int(120 * cos(h_second));
	x_minute = int(100 * sin(h_minute)); y_minute = int(100 * cos(h_minute));
	x_hour = int(70 * sin(h_hour)); y_hour = int(70 * cos(h_hour));
	setlinestyle(PS_SOLID, 2);
	setcolor(RED);
	line(320 + x_second, 240 - y_second, 320 - x_second / 3, 240 + y_second / 3);
	setlinestyle(PS_SOLID, 6); 
	setcolor(YELLOW);
	line(320 + x_minute, 240 - y_minute, 320 - x_minute / 5, 240 + y_minute / 5);
	setlinestyle(PS_SOLID, 7);
	setcolor(GREEN);
	line(320 + x_hour, 240 - y_hour, 320 - x_hour / 5, 240 + y_hour / 5);
}

2. 五子棋对战游戏设计

设计目标:实现利用计算机评判两个人五子棋比赛游戏、用C语言提供的图形库函数实现绘制五子棋棋盘,实现五子棋规则评判算法。
设计思路参考:

(A)五子棋对战游戏规则:

(1)对局双方各执一色棋子。
(2)空棋盘开局。
(3)黑先、白后,交替下子,每次只能下一子。
(4)棋子下在棋盘的空白点上,棋子下定后,不得向其它点移动,不得从棋盘上拿或拿起另落别处。
(5)黑方的第一枚棋子可下在棋盘任意交叉点上。
(6)当有一方先在行、列、或者斜线上连续下出连续5个棋子可以判定为胜局。

(B)游戏的基本流程为:

启动游戏,显示游戏参数设置界面,用户输入参数后进入游戏界面,显示棋盘及双方博弈过程,游戏过程中可选择退出游戏。判定一方获胜后结束本局游戏,可选择继续下一局或者退出游戏。

(C)设计实现思路及步骤

(1)游戏参数设置。定义游戏各项参数,如博弈双方用户名,背景色,先手方。
(2)棋盘绘制
棋盘设计为19×19矩形网格,设置背景颜色,设置棋盘网格线颜色,光标的初始位置在棋盘中间。游戏界面显示博弈双方名称和执子颜色,显示当前执子方。
(3)棋子绘制
设计黑白两色圆形棋子,做颜色填充,可以设计棋子大小。采用二维数组W[L][R]存储,数组的每个元素对应一个网格交叉点。每个数据元素的取值范围可定义为3个数值分别代表3种状态:空白、落黑子、落白子。
(4)落子
两色棋子轮流落子。用户单击鼠标(或按键)将光标移至空白的网格交叉点后再次单击(或按键)同一位置落子,落子后切换当前执子方。限制光标位置位于棋盘网格内。除了鼠标外落子方式也可选用按键操作,如:棋手1用Up、Down、Left、Right控制光标移动,回车键表示落子。棋手2用W、S、A、D控制光标移动,空格键表示落子。一旦接收到回车键或空格键,说明棋手落子,先判断是否是有效位置,也就是说已经有棋子的位置不能重叠落子
(5)输赢判定
落子成功后,马上判断以该位置为中心的八个方向:上、下、左、右、左上、左下、右上、右下是否有相同颜色的棋子连成五子,如果连成五子,则游戏结束,输出相应的信息。如果想退出游戏,可以按Esc键。

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define MAXIMUS 15       //定义棋盘大小
int p[MAXIMUS][MAXIMUS];       //存储对局信息
char buff[MAXIMUS*2+1][MAXIMUS*4+3];       //输出缓冲器
int Cx,Cy;         //当前光标位置
int Now;       //当前走子的玩家,1代表黑,2代表白
int wl,wp;      //当前写入缓冲器的列数和行数位置
char* showText;     //在棋盘中央显示的文字信息
int count;//回合数
char* Copy(char* strDest,const char* strSrc)     //修改过的字符串复制函数,会忽略末端的\0
{
    
    
char* strDestCopy = strDest;
while (*strSrc!='\0')
{
    
    
*strDest++=*strSrc++;
}
return strDestCopy;
}
void Initialize()       //初始化一个对局函数
{
    
    
int i,j;       //循环变量
showText="";        //重置显示信息
count=0;          //回合数归零
for(i=0;i<MAXIMUS;i++)           //重置对局数据
{
    
    
for(j=0;j<MAXIMUS;j++)
{
    
    
p[i][j]=0;}}
Cx=Cy=MAXIMUS/2;         //重置光标到中央
Now=1;       //重置当前为黑方
}
char* getStyle(int i,int j)       //获得棋盘中指定坐标交点位置的字符,通过制表符拼成棋盘
{
    
    
if(p[i][j]==1)     //1为黑子
return "●";
else if(p[i][j]==2)      //2为白子
return "○";
else if(i==0&&j==0)       //以下为边缘棋盘样式
return "┏";
else if(i==MAXIMUS-1&&j==0)
return "┓";
else if(i==MAXIMUS-1&&j==MAXIMUS-1)
return "┛";
else if(i==0&&j==MAXIMUS-1)
return "┗";
else if(i==0)
return "┠";
else if(i==MAXIMUS-1)
return "┨";
else if(j==0)
return "┯";
else if(j==MAXIMUS-1)
return "┷";
return "┼";       //中间的空位
}
char* getCurse(int i,int j){
    
           //获得指定坐标交点位置左上格的样式,通过制表符来模拟光标的显示
if(i==Cx){
    
    
if(j==Cy)
return "┏";
else if (j==Cy+1)
return "┗";
}
else if(i==Cx+1)
{
    
    
if(j==Cy)
return "┓";
else if (j==Cy+1)
return "┛";
}
return " ";          //如果不在光标附近则为空
}
void write(char* c)          //向缓冲器写入字符串
{
    
    
Copy(buff[wl]+wp,c);
wp+=strlen(c);
}
void ln()            //缓冲器写入位置提行
{
    
    
wl+=1;
wp=0;
}
void Display()             //将缓冲器内容输出到屏幕
{
    
    
int i,l=strlen(showText);             //循环变量,中间文字信息的长度
int Offset=MAXIMUS*2+2-l/2;           //算出中间文字信息居中显示所在的横坐标位置
if(Offset%2==1)            //如果位置为奇数,则移动到偶数,避免混乱
{
    
    
Offset--;
}
Copy(buff[MAXIMUS]+Offset,showText);           //讲中间文字信息复制到缓冲器
if(l%2==1)            //如果中间文字长度为半角奇数,则补上空格,避免混乱
{
    
    
*(buff[MAXIMUS]+Offset+l)=0x20;
}
system("cls");           //清理屏幕,准备写入
for(i=0;i<MAXIMUS*2+1;i++){
    
               //循环写入每一行
printf("%s",buff[i]);
if(i<MAXIMUS*2)             //写入完每一行需要换行
printf("\n");
}}
void Print()            //将整个棋盘算出并储存到缓冲器,然后调用Display函数显示出来
{
    
    
int i,j;           //循环变量
wl=0;
wp=0;
for(j=0;j<=MAXIMUS;j++)             //写入出交点左上角的字符,因为需要打印棋盘右下角,所以很以横纵各多一次循环
{
    
    
for(i=0;i<=MAXIMUS;i++)
{
    
    
write(getCurse(i,j));          //写入左上角字符
if(j==0||j==MAXIMUS)         //如果是棋上下盘边缘则没有连接的竖线,用空格填充位置
{
    
    
if(i!=MAXIMUS)
write(" ");
}
else            //如果在棋盘中间则用竖线承接上下
{
    
    
if(i==0||i==MAXIMUS-1)              //左右边缘的竖线更粗
write("┃");
else if(i!=MAXIMUS)            //中间的竖线
write("│");
}}
if(j==MAXIMUS)         //如果是最后一次循环,则只需要处理边侧字符,交点要少一排
{
    
    
break;
}
ln();            //提行开始打印交点内容
write(" ");           //用空位补齐位置
for(i=0;i<MAXIMUS;i++)          //按横坐标循环正常的次数
{
    
    
write(getStyle(i,j));           //写入交点字符
if(i!=MAXIMUS-1)              //如果不在最右侧则补充一个横线承接左右
{
    
    
if(j==0||j==MAXIMUS-1)
{
    
    
write("━");            //上下边缘的横线更粗
}
else
{
    
    
write("—");               //中间的横线
}}}
ln();              //写完一行后提行
}
Display();           //将缓冲器内容输出到屏幕
}
int Put(){
    
                 //在当前光标位置走子,如果非空,则返回0表示失败
if(p[Cx][Cy]==0)
{
    
    
p[Cx][Cy]=Now;              //改变该位置数据
return 1;             //返回1表示成功
}
else
{
    
    
return 0;}}
int Check()            //胜负检查,即判断当前走子位置有没有造成五连珠的情况
{
    
    
int w=1,x=1,y=1,z=1,i;           //累计横竖正斜反邪四个方向的连续相同棋子数目
for(i=1;i<5;i++)if(Cy+i<MAXIMUS&&p[Cx][Cy+i]==Now)w++;else break;       //向下检查
for(i=1;i<5;i++)if(Cy-i>0&&p[Cx][Cy-i]==Now)w++;else break;           //向上检查
if(w>=5)return Now;             //若果达到5个则判断当前走子玩家为赢家
for(i=1;i<5;i++)if(Cx+i<MAXIMUS&&p[Cx+i][Cy]==Now)x++;else break;      //向右检查
for(i=1;i<5;i++)if(Cx-i>0&&p[Cx-i][Cy]==Now)x++;else break;               //向左检查
if(x>=5)return Now;                      //若果达到5个则判断当前走子玩家为赢家
for(i=1;i<5;i++)if(Cx+i<MAXIMUS&&Cy+i<MAXIMUS&&p[Cx+i][Cy+i]==Now)y++;else break;           //向右下检查
for(i=1;i<5;i++)if(Cx-i>0&&Cy-i>0&&p[Cx-i][Cy-i]==Now)y++;else break;//向左上检查
if(y>=5)return Now;             //若果达到5个则判断当前走子玩家为赢家
for(i=1;i<5;i++)if(Cx+i<MAXIMUS&&Cy-i>0&&p[Cx+i][Cy-i]==Now)z++;else break;       //向右上检查
for(i=1;i<5;i++)if(Cx-i>0&&Cy+i<MAXIMUS&&p[Cx-i][Cy+i]==Now)z++;else break;       //向左下检查
if(z>=5)return Now;              //若果达到5个则判断当前走子玩家为赢家
return 0;               //若没有检查到五连珠,则返回0表示还没有玩家达成胜利
}
int RunGame()                 //进行整个对局,返回赢家信息(虽然有用上)
{
    
    
int input;          //输入变量
int victor;           //赢家信息
Initialize();         //初始化对局
while(1){
    
                //开始无限回合的死循环,直到出现胜利跳出
Print();            //打印棋盘
input=getch();           //等待键盘按下一个字符
if(input==27)           //如果是ESC则退出程序
{
    
    
exit(0);
}
else if(input==0x20)          //如果是空格则开始走子
{
    
    
if(Put())           //如果走子成功则判断胜负
{
    
    
victor=Check();
Now=3-Now;          //轮换当前走子玩家
count++;
if(victor==1)          //如果黑方达到胜利,显示提示文字并等待一次按键,返回胜利信息
{
    
    
showText="黑方获得了胜利!";
Print();
if(getch()==0xE0)
{
    
    
getch();
}
return Now;
}
else if(victor==2)      //如果白方达到胜利,显示提示文字并等待一次按键,返回胜利信息
{
    
    
showText="白方获得了胜利!";
Display();
if(getch()==0xE0)
{
    
    
getch();
}
return Now;
}else if(count==MAXIMUS*MAXIMUS)                       //                                          如果回合数达到了棋盘总量,即棋盘充满,即为平局
{
    
    
showText="平局!";
Display();
if(getch()==0xE0)
{
    
    
getch();
}
return 0;}}}
else if(input==0xE0)                    //如果按下的是方向键,会填充两次输入,第一次为0xE0表示按下的是控制键
{
    
    
input=getch();           //获得第二次输入信息
switch(input)              //判断方向键方向并移动光标位置
{
    
    
case 0x4B://
Cx--;
break;
case 0x48:
Cy--;
break;
case 0x4D:
Cx++;
break;
case 0x50:
Cy++;
break;
}
if(Cx<0)Cx=MAXIMUS-1;            //如果光标位置越界则移动到对侧
if(Cy<0)Cy=MAXIMUS-1;
if(Cx>MAXIMUS-1)Cx=0;
if(Cy>MAXIMUS-1)Cy=0;
}
}
}
int main()             //主函数
{
    
    
system("title 简易五子棋 ——施晓龙制作");            //设置标题
system("mode con cols=63 lines=32");             //设置窗口大小
system("color B1");                   //设置颜色
while(1){
    
                    //循环执行游戏
RunGame();
}}

3. 计算器程序的设计

设计目标:实现一个计算器功能的程序。能够用C语言提供的图形库函数绘制计算器界面、基本的运算程序、计算界面数据数据、运算符定位和刷新功能。
设计思路参考:
(1)初始化图形系统,定义视口,确定计算器在屏幕中的位置。
(2)以矩形等形状画出计算器外形,设计计算各按钮位置及输出区域位置和效果,将表示数字和运算符的符号以文本显示在对应按钮位置,接收输入,判断其内容是否合法并给出提示,若合法将对应信息显示在输出区域
(3)当输入为“等号”时,计算结果并将结果显示在输出口。
实现计算函数部分的伪C程序如下(入口:(left,top),左上角坐标。出口:最后一次计算的结果。):
double Computer(intleft,int top)
{ 核对屏幕位置,是否可容纳缺省的计算器尺寸;
保存计算器占用的屏幕画面;
画出计算器外形;
do
{ char str1[len],str2[len]; /两个数对应的串/
char popstr[长度]; /可存两串及一个运算符的数组/
double Data1,Data2; /由串转换后的两个数/
int Flag=0; /输入的数据个数,Flag=2时计算/
char oper; /运算符/
oper=接收按键;
if(oper是0 ̄9字符)
if(在数据的限定长度内)
将oper写入popstr;
else
不处理或响铃;
else
if(oper是非法字符)
不处理或响铃;
else /oper是运算符、或为=、或为/
{ if(oper==Esc)
中止并返回0;
else{ 测试popstr中的字符串;
if(是<数字串1><运算符><数字串2>形式)
{ 计算结果并显示;
if(输入为运算符)
{ strcpy(popstr,计算结果串);
将oper写入popstr;}}
else
if(是<数字串1>形式)
将oper写入popstr;
else
不处理或响铃;} }}while(终止条件);
return 最后计算结果;}

#include<stdio.h>
void main(void){
    
    //简易计算机的设计 
int c=1;
float operationA=0;
float operationB=0;
int isContinue=1;
while(isContinue){
    
    
printf("请选择你要进行的运算类型:1加法,2减法,3乘法,4除法\n");
scanf("%d",&c);
printf("请输入第一个运算数字:\t");
scanf("%f",&operationA);
printf("请输入第二个运算数字:\t");
scanf("%f",&operationB);
if(c==1){
    
    
printf("%f + %f = %f\n",operationA,operationB,operationA+operationB);
}else if(c==2){
    
    
printf("%f - %f = %f\n",operationA,operationB,operationA-operationB);
}else if(c==3){
    
    
printf("%f * %f = %f\n",operationA,operationB,operationA*operationB);
}else if(c==4){
    
    
while(operationB==0){
    
    
printf("除数不能为零!请重新输入第二个数:");
scanf("%f",&operationB);
}
printf("%f / %f = %f\n",operationA,operationB,operationA/operationB);
}else{
    
    
printf("请正确选择运算:");
} 
printf("\n\n");
printf("你是否还要继续进行运算:是:1 ? ?否:0 \n");
scanf("%d",&isContinue);
if(isContinue==0){
    
    
isContinue=0;
}}
printf("欢迎使用本计算机!");}

4.其它自选程序——扫雷

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
#include<string.h>
#define SIZE 10
#define N 35
char mine[12][12]={
    
    {
    
    0}};
int step=65;
void gotoxy(int x,int y)//坐标函数
{
    
    
    COORD pos ;
    pos.X = x ;
    pos.Y = y ;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE) , pos) ;
}
void color(int a)//颜色函数
{
    
    
    HANDLE hConsole = GetStdHandle((STD_OUTPUT_HANDLE)) ;
    SetConsoleTextAttribute(hConsole,a) ;
}
void init_mine()//初始化
{
    
    
    int count,x,y;

    for(count=0;count<N; )//设置雷区
    {
    
    
        x=rand()%10+1;
        y=rand()%10+1;
        if(!mine[y][x])
        {
    
    
            mine[y][x]=1;
            count++;
        }}
    gotoxy(3,0);
    for(x=1;x<=SIZE;x++)//设置行标号
    {
    
    
        color(13);
        printf("%d ",x);
    }
    for(x=1;x<=SIZE;x++)//设置列标号
    {
    
    
        gotoxy(0,x);
        printf("%d ",x);
    }
    for(y=1;y<=SIZE;y++)//初始化雷区
    {
    
    
        gotoxy(2,y);
        for(x=1;x<=SIZE;x++)
        {
    
    
            color(11);
            printf("□");
        }}
    gotoxy(45,0);//设置文字提示
    color(12);
    printf("扫雷-韩虹音制作");
    color(14);
    gotoxy(0,11);
    printf(" Input the position ( x , y )\n\n");
    color(11);
    printf("      Notice :when x=0 and y=0,the game is over!!!!");

}
void show_mine(int x,int y)
{
    
    
    int num;
    if(mine[y][x])//踩雷了
    {
    
    
        color(11);
        gotoxy(x*2,y);
        printf("●");
        gotoxy(22,10);
        for(y=1;y<11;y++)
            for(x=1;x<11;x++)
            {
    
    
                gotoxy(x*2,y);
                if(mine[y][x])
                    printf("●");
                else
                {
    
    
                    num=mine[y+1][x]+mine[y+1][x+1]+mine[y+1][x-1]+mine[y][x+1]+mine[y][x-1]+mine[y-1][x]+mine[y-1][x+1]+mine[y-1][x-1];
                    printf("%d ",num);
                }
            }
        printf("踩中雷区阵亡,请再接再厉!!!");
        exit(0);
    }
    else//未踩雷
    {
    
    
        num=mine[y+1][x]+mine[y+1][x+1]+mine[y+1][x-1]+mine[y][x+1]+mine[y][x-1]+mine[y-1][x]+mine[y-1][x+1]+mine[y-1][x-1];
        gotoxy(x*2,y);
        printf("%d ",num);
        gotoxy(53,9);
        printf("%d",--step);
    }}
main()
{
    
       char x,y,x1,y1;
    x1 = 'c';
    init_mine();                 初始化游戏界面,埋雷,初始化显示等
    gotoxy(23,11);              //移动光标到坐标23,21
    for(x=0,y=0;x1 !=0||y1 !=0;)
    {
    
    
        Sleep(1000);           //延时
        if(kbhit())//输入坐标
        {
    
    
            gotoxy(23,11);
            scanf("%d",&x1);
            gotoxy(27,11);
            scanf("%d",&y1);
            gotoxy(23,11);
            printf("(x , y )    ");
        }
        if(x1 >0 && x1 <11 && y1>0 && y1<11&&( x!=x1 || y!=y1))
        {
    
    
            y=y1;
            x=x1;
      show_mine(x,y); //检测有没有踩雷,如果踩雷显示雷,如果没有,显示周围雷的个数
        }
        if(!step)
        {
    
    
            gotoxy(10,5);
            printf("真棒!!您赢了!!");
        exit(0);
        }}
exit(0);
}

猜你喜欢

转载自blog.csdn.net/GodOuO/article/details/104051814