扫雷练习: 在10*10矩阵中,随机出现10个X
1#include<stdio.h>
2#include<time.h>
3int main(){
4 int row=0,col=0,cnt=0;
5 char arr[10][10]={0};
6 srand(time(0));
7 do{ //找到一个随机的存储区
8 row=rand()%10;
9 col=rand()%10;
10 if(arr[row][col]==0){
11 //随机存储区不是地雷
12 arr[row][col]=-1;
13 cnt++;
14 }
15 }while(cnt<10);
16 for(row=0;row<=9;row++){
17 for(col=0;col<=9;col++){
18 if(arr[row][col]==0){
19 printf("O");
20 }
21 else if(arr[row][col]==-1){
22 printf("X");
23 }
24 }
25 printf("\n");
26 }
27 return 0;
28 }
扫雷游戏全码:
1#include<stdio.h>
2 #include<time.h>
3int main(){
4 int row=0,col=0,cnt=0,i=0;
5 int map[10][10]={0};
6 intdelta[][2]={-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};
7 srand(time(0));
8 do{
9 row=rand()%10;
10 col=rand()%10;
11 if(map[row][col]==0){
12 map[row][col]=-1;
13 cnt++;
14 }
15 }while(cnt<10);
16 for(row=0;row<=9;row++){
17 for(col=0;col<=9;row++){
18 if(map[row][col]==-1){
19 continue;
20 }
21 for(i=0;i<=7;i++){
22 //依次处理周围的八个格子
23 int tmp_row=row+delta[i][0];
24 inttmp_col=col+delta[i][1];
25 //忽略不在地图里的格子
26 if(tmp_row<0||tmp_row>9){
27 continue;
28 }
29 if(tmp_col<0||tmp_col>9){
30 continue;
31 }
32 //如果周围的某个格子里是地雷,就把当前格子里的数字加一
33 if(map[tmp_row][tmp_col]==-1){
34 map[row][col]++;
35 }
36 }
37
38 }
39 }
40 for(row=0;row<=9;row++){
41 for(col=0;col<=9;col++){
42 if(map[row][col]==0){
43 printf("O");
44 }
45 else if(map[row][col]==-1){
46 printf("X");
47 }
48 else {
49 printf("%d",map[row][col]);
50 }
51 }
52 printf("\n");
53 }
54 return 0;
55 }
函数:C语言程序中可以用分组的方式管理语句
每个语句分组叫做一个函数
多函数程序执行模式有如下特点:
整个程序的执行时间被分解成几段,每段时间被分给一个函数使用
任何两个时间段不能互相重叠,并且所有时间段必须连续
如果函数A在工作过程中把一段时间分配给函数B使用,则函数B在使用完所有时间之后必须把后面的时间还给函数A
如果函数A把时间分配给函数B,则它们之间存在函数调用关系
其中函数A叫做调用函数,函数B叫做被调用函数
函数调用关系有时间范围,只有被调用函数工作期间,函数调用关系才存在
在程序中使用函数调用语句产生调用关系
不可以跨函数使用变量,不同函数里的变量可以重名
如果一个函数多次运行,则每次运行的时候内部变量对应的存储区有可能不同
Volatile关键字可以用来声明变量,使用这个关键字声明的变量每次取数的时候都可以得到存储区里真正的数字。(防止别的程序往这个变量里放数字改变值)
函数调用过程中通常伴随着两个函数之间的数据传递
数据传递存在两个完全不同的方向,可能从调用函数向被调用函数传递,也可能从被调用函数向调用函数传递
任何一个方向的数据传递都需要使用被调用函数提供的存储区
只能从被调用函数向调用函数传递一个数据,且只能在被调用函数结束时才能传递这个数据
这个数据叫做被调用函数的返回值
函数的返回值必须记录在被调用函数提供的一个专门的存储区里,应该把这个存储区的类型名称写在函数名称前
在被调用函数里使用return关键字向这个存储区里存放返回值
调用函数直接把函数调用语句当数字使用就可以得到被调用函数的返回值
练习:编写函数,从键盘得到两个整数,计算它们的和并把结果传递给调用函数
1#include<stdio.h>
2int sum(void){
3 int num=0,num1=0,he=0;
4 printf("请输入两个数字: ");
5 scanf("%d%d",&num,&num1);
6 he=num+num1;
7 return he;
8
9 }
10int main(){
11 int num=sum();
12 printf("和是%d\n",num);
13
14 return 0;
15 }
如果被调用函数里没有使用return关键字指定返回值,则存放返回值的存储区里的内容是随机的
这个存储区不能用来长期存放数字,调用函数得到返回值以后立刻使用或者转存到其它存储区里
函数名称前写void表示函数没有提供用来存放返回值的存储区
如果函数名称前什么都没写,在C89规范里表示函数提供了一个整数类型存储区用来存放返回值,C99规范里不允许这样
被调用函数不能使用数组存放返回值
调用函数可以一次向被调用函数传递多个不同类型的数据,被调用函数需要提供多个存储区存放这些数据
可以用一组变量表示这些存储区,这组变量必须声明在函数名称后面的小括号里
void print(int num,int num1)
这些变量叫做形式参数,小括号里的内容统称为形式参数列表
形式参数列表是用逗号连接的多个变量声明语句,每个形式参数的类型名称都不能省略
函数调用语句里需要为每个形式参数提供一个对应的数据,这些数据叫实际参数
函数调用的时候计算机把实际参数记录到对应的形式参数里,被调用函数可以从形式参数里获得实际参数的数值
1#include<stdio.h>
2void print(int num,int num1){
3 printf("%d%d",num,num1);
4 }
5int main(){
6 int a=0,b=0;
7 printf("请输入两个数字:");
8 scanf("%d%d",&a,&b);
9 print(a,b);
10 return 0;
11 }
num、num1是形参, a、b是实参
所有能当数字使用的内容都可以当做实际参数使用
函数名称后面的小括号里写void表示函数不需要从调用函数得到任何数字
如果小括号里什么都没写,表示函数可以提供任意多个任意类型的形式参数
练习:编写函数,从调用函数得到两个整数,计算它们的和,并把结果传递给调用函数
1#include<stdio.h>
2int add(int a,int b){
3 return a+b;
4}
5int main(){
6 int num=0,num1=0;
7 printf("请输入两个整数:");
8 scanf("%d%d",&num,&num1);
9 printf("求和结果是%d\n",add(num,num1));
10 return 0;
11}
练习:编写函数解决鸡兔同笼的问题
从调用函数得到头和脚的数量,然后计算出兔子的数量并传递给调用函数
1#include<stdio.h>
2int rabbit(int heads,int legs){
3 int i;
4 for(i=0;i<=heads;i++){
5 if(4*i+2*(heads-i)==legs)
6 return i;
7 }
8 }
9}
10int main(){
11 int heads=0,legs=100,num=0;
12 printf("请输入头和脚的数量:");
13 scanf("%d%d",&heads,&legs);
14 num=rabbit(heads,legs);
15 printf("兔子有%d只,鸡有%d只\n",num,40-num);
16 return 0;
17 }
练习:在屏幕上打印
1*9=9
2*8=16
3*7=21
4*6=24
5*5=25 每次函数执行打印一次内容
1#include<stdio.h>
2int print(int a,int b){
3 printf("%dX%d=%d\n",a,b,a*b);
4 }
5int main(){
6 int i=0,sum=0;
7 int num1=1,num2=9;
8 for(i=0;i<=4;i++){
9 print(num1,num2);
10 num1++;
11 num2--;
12 }
13 return 0;
14 }