目录
一维数组
二维数组
数组越界
数组作为函数参数
数组的应用实例1:三子棋
数组的应用实例2:扫雷游戏
数组练习
- 数组如果初始化,可以不指定数组大小。并且数组大小不能传入一个变量。
- 数组是一组相同类型元素的组合:int类型数组只能存储int类型、char类型数组只能存储char类型
- 数组在内存方面存储的时候,数组中元素的内存地址是连续的。
- 所有的数组都是拿“首元素的内存地址”作为整个数组对象的内存地址。
数组中首元素的内存地址作为整个数组对象的内存地址。
- 数组中每一个元素都是有下标的,下标从零开始,以1递增。最后一个元素的下标:数组长度-1
下标非常重要,我们对数组中元素进行“存取”的时候,都要通过下标来进行
一维数组的创建和初始化
#include
#include
int main()
{
//一维数组的定义及初始化
//数据元素类型 数组名[常量/常量表达式]={}; //C99之前,[]中必须是一个常量,不能使用变量。
//C99语法:变长数组:数组的大小可以是变量。不建议这样使用
//int n = 3;
//int arr[n];
//完全初始化
//int arr[10] = {1,2,3,4,5,6,7,8,9,};
//不完全初始化,其余值为0。
//int arr[10] = {1,2,3,4,5};
//这也是不完全初始化,我们只是为下标为1的元素初始化值为10,其他默认初始化值为0。
//int arr[10] = {10};
//数组创建时,可以不指定数组大小,但是需要初始化。此时,数组根据其初始化元素个数来确定其大小。
//int arr[] ={1,2,3,4,5}; //等同于int arr[5] ={1,2,3,4,5};
//字符数组的初始化
//char ch1[5] ={'d','o','g'}; //其中存储的是'd','o','g','\0','\0'
//char ch2[] ={'d','o','g'}; //其中存储的是'd','o','g'
//因为字符串是以\0结尾的,所以如果是以字符串为值初始化,则这个\0也会存储到字符数组中
//char ch3[5] = "cat"; //其中存储的是'c','a','t','\0','\0' 最后面这个0是默认补充的
//char ch4[] = "cat"; //其中存储的是'c','a','t','\0' ,数组大小为4
//以下两种数组初始化的区别
char ch5[] ="dog";
char ch6[] ={'d','o','g'};
//以%s形式打印,遇到\0才会停止打印
printf("%s\n",ch5);//dog //ch5数组中存储了dog'\0',当打印时碰到\0,就会停止
printf("%s\n",ch6);//dogdog //ch6数组中只存储了dog,打印完dog不会停止,直到碰见\0才会停止打印
//求字符串长度也是,碰到\0才停止。
printf("%d\n",strlen(ch5)); //3
printf("%d\n",strlen(ch6)); //6,这里的6是个随机值。什么时候碰到\0,什么时候停止计算长度。
return 0;
一维数组的使用
//数组的大小需要通过计算:数组总大小/一个数组元素大小 = 数组大小。
//数组中元素下标从0开始,到(数组大小-1)结束。使用下标引用,也就是[]访问数组元素。
#include
int main()
{
//数组的不完全初始化
int arr[10] = {0};
//计算数组的元素个数
int sz = sizeof (arr)/sizeof (arr[0]);
//对数组中某个元素赋值,需要通过数组下标访问。
int i;
for( i=0 ; i<10 ; i++)
{
arr[i] = i;
printf("%d ",arr[i]); //0 1 2 3 4 5 6 7 8 9
}
return 0;
}
一维数组在内存中的存储
一维数组在内存中是连续存放的。并且随着数组下标的增长,地址是由低到高变化的。·
//%p —— 按地址的格式打印,内存地址以十六进制存储的。
//%x —— 打印十六进制。
//%p与%x的区别:%x会省略掉前面的0,%p不会省略。
int main()
{
//一维数组在内存中是连续存放的。并且随着数组下标的增长,地址是由低到高变化的。
int arr[10] = {0};
int i;
for(i=0 ; i<10 ; i++)
{
printf("&arr[%d] = %p\n",i,&arr[i]);
}
//这里每个数组元素的内存地址差4,是因为int类型占4个字节。
//&arr[0] = 000000d0819ff800
//&arr[1] = 000000d0819ff804
//&arr[2] = 000000d0819ff808
//&arr[3] = 000000d0819ff80c
//&arr[4] = 000000d0819ff810
//&arr[5] = 000000d0819ff814
//&arr[6] = 000000d0819ff818
//&arr[7] = 000000d0819ff81c
//&arr[8] = 000000d0819ff820
//&arr[9] = 000000d0819ff824
return 0;
}
使用指针变量
#include
int main()
{
int arr[10] = {1,3,5,7,9,11,13,15,17,19};
int* p = arr; //数组名是数组首元素的地址
int i;
for(i=0 ; i<10 ; i++)
{
//*p 解引用
printf("%d ",*p); //1 2 3 4 5 6 7 8 9 10
//因为p是指针变量,又是int类型,所以一次跳4个。如果是char类型指针,则+1指每次跳一个。
p ++;
}
return 0;
二维数组的创建和初始化
//二维数组是一个特殊的一维数组,特殊在这个一维数组中的每一个元素都是一个数组。
#include
int main()
{
//二维数组的完全初始化。[0][0-3]:1、2、3、4 , [1][0-3]:5、6、7、8 [2][0-3]:9、10、11、12
//int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
//不完全初始化。没有初始化的赋值0。如果是字符数组,则赋值'\0'。
//[0][0-3]:1、2、3、4 , [1][0-3]:5、6、7、0 [2][0-3]:0、0、0、0
//int arr[3][4] ={1,2,3,4,5,6,7};
//二维数组如果在定义的同时初始化,是可以省略行的,也就是第一个[]里的值。它可以根据初始化的内容,来补全[]。
// 这里就是arr[2][4] ,因为是有六个元素,[2]够用,所以是[2][4]。如果里面有9个元素,则补全为[3][4]
//[0][0-3]:1、2、3、4 , [1][0-3]:5、6、0、0
//int arr[][4] = {1,2,3,4,5,6};
//这样初始化,其元素值:
//[0][0-3]:1、2、0、0 , [1][0-3]:3、4、0、0 [2][0-3]:5、6、0、0
//int arr[3][4] = {{1,2},{3,4},{5,6}};
return 0;
}
二维数组的使用
/*
关于二维数组中元素的:读和改
a[二维数组中一维数组的下标][二维数组中的一维数组中的元素下标]
a[0][0]:表示第一个一维数组中的第一个元素。
a[3][100]:表示第四个一维数组中的第101个元素。
对于a[3][100]来说,其中a[3]是一个整体,[100]是前面a[3]直接结束的结果然后再下标100,
*/
#include
int main()
{
int arr[3][4] ={0};
int i,j;
for(i=0 ; i < 3 ; i++)
{
for(j=0 ; j<4 ; j++)
{
arr[i][j] = i*4 + j +1;
printf("%d ",arr[i][j]);
//1 2 3 4
//5 6 7 8
//9 10 11 12
}
printf("\n");
}
return 0;
}
二维数组在内存中的存储
#include
int main()
{
int arr[3][4] ={0};
int i,j;
for(i=0 ; i < 3 ; i++)
{
for(j=0 ; j<4 ; j++)
{
printf("arr[%d][%d] = %p\n",i,j,&arr[i][j]);
}
printf("\n");
}
//arr[0][0] = 000000fb643ffc00
//arr[0][1] = 000000fb643ffc04
//arr[0][2] = 000000fb643ffc08
//arr[0][3] = 000000fb643ffc0c
//
//arr[1][0] = 000000fb643ffc10
//arr[1][1] = 000000fb643ffc14
//arr[1][2] = 000000fb643ffc18
//arr[1][3] = 000000fb643ffc1c
//
//arr[2][0] = 000000fb643ffc20
//arr[2][1] = 000000fb643ffc24
//arr[2][2] = 000000fb643ffc28
//arr[2][3] = 000000fb643ffc2c
return 0;
}
解引用
#include
int main()
{
int arr[3][4] = {{1,2},{3,4},{5,6}};
int i,j;
int* p = &arr[0][0]; //这里的&arr[0][0]等同于arr,因为数组存储的是首元素的地址
for(i=0 ; i < 12 ; i++)
{
printf("%d ",*p); //1 2 0 0 3 4 0 0 5 6 0 0
p++;
}
return 0;
}
#include
/*
* 数组的下标是有范围限制的。数组下标从0开始,如果有n个元素,最后一个元素的下标就是n-1
* 如果是使用[]方法数组下标时,小于0或>n-1了,就发生数组越界。
* C语言本身没有做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,也不意味着程序就是正确的。
* 所以我们在写程序时,最好自己检查一下引用是否越界。
*/
int main()
{
int arr[] = {1,2,3,4,5};
int i;
for(i=0 ; i<=10 ; i++)
{
//从5之后的数字都不是我们定义的数组中的数据,数组越界之后会取出的值不可预料。所以要做好检查。
printf("%d ",arr[i]); //1 2 3 4 5 32759 0 7 -641728848 78 990385215
}
return 0;
}
函数的形参定义成数组也可以、定义成指针变量也可以。
- 数组作为函数参数传参时,实际传入的是数组名,而数组名是数组中首个元素的地址。所以说实际上传进去的是个指针
数组名
/*
* 数组名是首元素的地址
*
* 例外:
* 1. sizeof(数组名) 在这个方法中,我们传入的数组名,代表整个数组。所以这个方法计算的是整个数组的大小,单位:字节。
* 2. &数组名 加了&的数组名表示整个数组,取出的是整个数组的地址。
*/
#include
int main()
{
int arr[10] = {0};
//1. 在sizeof方法中,数组名代表整个数组
int sz = sizeof (arr);
printf("%d\n",sz); //40
//这三个都是00000022165ffc30。 arr与&arr[0]都代表数组首元素。&arr代表整个数组
//printf("%p\n",&arr[0]);
//printf("%p\n",arr);
//printf("%p\n",&arr);
//让他们加1,看区别
printf("%p\n",arr); //000000b6953ffcf0
printf("%p\n",arr+1); //000000b6953ffcf4
printf("%p\n",&arr); //000000b6953ffcf0 十进制是:784,188,046,576
printf("%p\n",&arr+1); //000000b6953ffd18 十进制是:784,188,046,616
//可以看出 arr+1,只加了4个字节;而&arr+1,加了40个字节。
return 0;
}
冒泡排序
/*
冒泡排序算法
1、每一次循环结束之后,都要找出最大的数据,放到参与比较的这堆数据的最右边。(冒出最大的那个气泡)
2、核心:
拿着左边的数字和右边的数字比对,当 左边 > 右边 的时候,交换位置。
原始数据:
3,2,7,6,8
第一次循环:(最大的跑到最右边)
2,3,7,6,8 3和2比较,2<3,所以2和3交换位置
2,3,7,6,8 虽然不需要交换位置:但是3和7还是需要比较一次
2,3,6,7,8 6<7 6和7交换位置
2,3,6,7,8 虽然不需要交换位置:但是7和8还是需要比较一次
经过第一次循环,此时剩下参与比较的数据:2,3,6,7
第二次循环
2,3,6,7 2和3比较,不需要交换位置
2,3,6,7 3和6比较,不需要交换位置
2,3,6,7 6和7比较,不需要交换位置
经过第二次循环,此时剩下参与比较的数据:2,3,6
第三次循环
2,3,6 2和3比较,不需要交换位置
2,3,6 3和6比较,不需要交换位置
经过第三次循环,此时剩下参与比较的数据:2,3
第四次循环
2,3 2和3比较,不需要交换位置
原始数据:9 8 10 7 6 0 11
第一次循环:
8 9 10 7 6 0 11 第1次比较后:交换
8 9 10 7 6 0 11 第2次比较后:不交换
8 9 7 10 6 0 11 第3次比较后:交换
8 9 7 6 10 0 11 第4次比较后:交换
8 9 7 6 0 10 11 第5次比较后:交换
8 9 7 6 0 10 11 第6次比较后:不交换
最终冒出的最大数据在右边:11
经过第一次循环,此时剩下参与比较的数据: 8 9 7 6 0 10
第二次循环
8 9 7 6 0 10 第1次比较后:不交换
8 7 9 6 0 10 第2次比较后:交换
8 7 6 9 0 10 第3次比较后:交换
8 7 6 0 9 10 第4次比较后:交换
8 7 6 0 9 10 第5次比较后:不交换
最终冒出的最大数据在右边:10
经过第二次循环,此时剩下参与比较的数据: 8 7 6 0 9
第三次循环
7 8 6 0 9 第1次比较后:交换
7 6 8 0 9 第2次比较后:交换
7 6 0 8 9 第3次比较后:交换
7 6 0 8 9 第4次比较后:不交换
最后冒出的最大数据在右边:9
经过第三次循环,此时剩下参与比较的数据:7 6 0 8
第四次循环
6 7 0 8 第1次比较后:交换
6 0 7 8 第2次比较后:交换
6 0 7 8 第3次比较后:不交换
最后冒出的最大数据在右边:8
经过第四次循环,此时剩下参与比较的数据:6 0 7
第五次循环
0 6 7 第1次比较后:交换
0 6 7 第2次比较后:不交换
最后冒出的最大数据在右边:7
经过第五次循环,此时剩下参与比较的数据:0 6
第六次循环
0 6 第1次比较后:不交换
//7条数据比6次
//6条数据比5次
//5条数据比4次
//4条数据比3次
//3条数据比2次
//2条数据比1次
*/
#include
void bubble_sort(int arr[],int length)
{
int i = 0;
int j = 0;
//10条数据要循环9次,每次经过9次判断。 n条数据,循环n-1次,判断n-1次
//数组长度是:length。要循环n-1次,所以这里是length-1
for(i=length-1 ; i > 0 ; i--)
{
for(j=0 ; jarr[j+1])
{
int temp;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
int main()
{
int arr[] = {9,8,10,6,2,11,23,18,42,16};
int sz = sizeof(arr)/sizeof(arr[0]);
//冒泡排序——将较大的数字放到右边
bubble_sort(arr,sz); //数组传参的时候,传递的是首元素的地址。
int i;
for (i = 0; i
在此项目的实现中,遗留问题:
- 电脑下棋太随机,有点笨,需要更改其电脑下棋实现来使他聪明一点
- 此项目中对三子棋的判断条件解了耦合,也就是说,如果是5行5列,或其他行其他列。我们的判断条件也不会有问题。(仅是行数和列数相同的时候,不相同的时候判断条件还比较多,可以自行修改实现)
game.h 游戏的函数声明
//关于游戏相关的函数声明,符号声明,头文件的包含。
#ifndef FIRST_GAME_H
#define FIRST_GAME_H
//头文件的包含
#include
#include
#include
#define ROW 3
#define COL 3
//声明InitBoard()初始化函数
void InitBoard(char board[ROW][COL],int row,int col);
//声明DisplayBoard()函数
void DisplayBoard(char board[ROW][COL],int row,int col);
//声明playerMove()函数 ,第一个[]中的内容可以省略
void playerMove(char board[][COL],int row,int col);
//声明computerMove()
void computerMove(char board[ROW][COL],int row,int col);
//声明isWin()
char isWin(char board[][COL],int row,int col);
#endif //FIRST_GAME_H
game.c 游戏函数实现
//游戏相关的函数实现
//包含头文件
#include "game.h"
//InitBoard()函数的实现
void InitBoard(char board[ROW][COL],int row,int col)
{
int i,j;
for ( i=0 ; i =1 && x<=row && y>=1 && y<=col)
{
//玩家通过坐标进行下棋,如1 1就对应数组里的0 0 。如果为' '空,则说明没有被占用
if(board[x-1][y-1] ==' ')
{
board[x-1][y-1] = '*';
//每人只能下一次棋,所以下棋后退出循环
break;
}
else
{
printf("该位置已有棋子,请重下棋子。\n");
}
}
else
{
printf("输入的坐标不合法,请重新输入。\n");
}
}
}
//电脑下棋
void computerMove(char board[ROW][COL],int row,int col)
{
printf("电脑(#)下棋:\n");
//可能取的这个随机坐标,已经有值了,所以我们把它放入循环
while(1)
{
//电脑随机走 ,其x与y都需要0~2的随机值。我们使用rand()%3就可以得到这个范围。这里使用row与col,解耦合。
int x = rand()%row;
int y = rand()%col;
if(board[x][y] == ' ')
{
board[x][y] = '#';
//只有当下棋了之后,结束循环
break;
}
}
}
//判断局势
// 返回*表示玩家获胜、返回#表示电脑获胜、返回C表示游戏继续、返回Q表示平局
char isWin(char board[][COL],int row,int col)
{
int i,j;
int flag = 1;
//每一行或每一列、每个对角线判断后都需要将flag重置为1
//如果有一个为空,就说明还不到获胜的点,所以如果为空,也返回flag=0
//判断三行
for(i=0 ; i0 ;j++,i--)
{
if( board[i][j] == ' ' || (board[i][j] != board[i-1][j+1]))
{
flag = 0;
}
}
if(flag == 1){
//这里出了循环,而且是右对角线,取右上角
return board[col-1][0];
}
//到这里,说明没有出现胜利的。判断棋盘是否为空
for(i=0 ; i|
test.c 游戏测试
//测试游戏逻辑
#include "game.h"
void menu()
{
printf("**------ GAME:三子棋 -------**\n");
printf("**----- 输入1开始游戏 -------**\n");
printf("**------- 输入0退出 --------**\n");
printf("**-------------------------**\n");
}
void game()
{
//二维数组存储棋子。 ROW与COL是常量,定义在game.h头文件中
char board[ROW][COL];
//初始化棋盘,所有棋子为空格。
InitBoard(board,ROW,COL);
//打印棋盘:打印二维数组
DisplayBoard(board,ROW,COL);
char ret = 'C';
if(rand()%5 == 0)
{
//如果这里是1,则电脑先下棋。
//电脑下棋
printf("电脑:这次我先走两步,给你一点难度!");
computerMove(board,ROW,COL);
computerMove(board,ROW,COL);
//下棋后打印
DisplayBoard(board,ROW,COL);
}
while (ret == 'C')
{
//玩家下棋
playerMove(board,ROW,COL);
//下棋后打印
DisplayBoard(board,ROW,COL);
//下棋后判断,是否玩家获胜
ret = isWin(board,ROW,COL);
if(ret == '*' || ret == 'Q')
{
break;
}
//电脑下棋
computerMove(board,ROW,COL);
//下棋后打印
DisplayBoard(board,ROW,COL);
//下棋后判断,是否电脑获胜
ret = isWin(board,ROW,COL);
if(ret == '#' || ret == 'Q')
{
break;
}
}
if(ret == '*')
{
printf("YOU ARE WIN !!\n");
}
else if(ret == '#')
{
printf("电脑 WIN !!\n");
}
else
{
printf("~平局~1\n");
}
}
int main()
{
int input = 0;
//使用时间戳初始化种子,*5增大时间间隔
srand((unsigned int)time(NULL) *5);
do
{
menu();
printf("请输入:");
scanf("%d",&input);
switch (input) {
case 1:
printf("游戏开始。以行数、列数来指定下棋坐标,如1 1表示第一行第一列\n");
game();
break;
case 0:
printf("已退出游戏");
break;
default:
printf("输入有误,请重新输入!");
}
}while(input);
return 0;
}
在此项目的实现中,遗留问题:
- 在其他扫雷游戏中,如果点击了一个点,这个点周围只要没有雷,会把这个坐标周围8个点没有雷的都展现出来。并且将这个点周围的八个点周围的雷数量扫出来,并显示在该点位置。并继续判断这8个点周围有没有雷(在这里注意,在判断八个点周围是不是雷的的时候,已经判断过的会被重复判断。我们要进行限制,判断过的不再判断),直到所有未知区域旁边已经挖开的点都存储的是雷的数量的时候,才停止。
这就是在扫雷游戏中,如果点了一个点,就会展开一大片的原因。
直到这一圈周围都有雷的时候就不会再展开
思路:使用递归。
- 并且在其他扫雷中,如果你觉得这个地方是雷,可以右击鼠标进行标记。
当选择坐标之后,提供选项,是挖雷还是将其标记为雷
game.h 游戏函数的声明
#ifndef FIRST_GAME_H
#define FIRST_GAME_H
#include
#include
#include
//定义雷的数量
#define NUM_MINE 10
//虽然我们的数组大小是11*11的,但是我们在布置雷的时候,还是一个9*9的范围,这里这样定义更方便使用。
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//声明初始化数组的函数声明
void initBoard(char board[ROWS][COLS],int rows, int cols,char set);
//声明打印数组的函数声明
void printBoard(char board[ROWS][COLS],int row,int col);
//布置雷函数声明
void setMine(char board[ROWS][COLS],int row,int col);
//排查雷
void findMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);
#endif //FIRST_GAME_H
game.c 游戏函数的实现
#include "game.h"
//初始化数组 函数的实现
void initBoard(char board[ROWS][COLS],int rows, int cols,char set)
{
int i,j;
for(i=0 ; i=1 && x<=row && y>=1 && y<=col)
{
//如果坐标合法,就进行判断
if(mine[x][y] == '1')
{
printf("很遗憾,你挖到了雷,被炸死了呢(^_^) \n");
//打印雷数组
printBoard(mine,row,col);
//结束循环
break;
}
else
{
//判断是不是已经挖开了
if(show[x][y] != '#')
{
printf("这里已经挖开了,重新挖!\n");
//如果已经挖开了就跳出本次循环。
continue;
}
//如果没有挖开,才进行判断
//如果不是雷,则统计周围有几个雷。因为雷是在mine数组中,传进入,以x,y为坐标点查找周围的雷
int count = mineCount(mine,x,y);
//放入show数组中。
//因为count是一个int类型变量,而这里我们要存储为char类型。
//在ASCII编码表中,'0'对应48,'1'对应49,'2'对应50,'3'对应51....
//所以我们只要将取来的count加上一个'0'就可以得到char类型数据
//如'3'对应51,'0'对应48。 3+'0' = 58,就是'3'
show[x][y] = count+'0';
//存入数组后,打印排查数组
printBoard(show,row,col);
//如果我们排出一个位置,则win+1。直到win =row*col - NUM_MINE时,就排完雷了
win++;
}
}
else
{
printf("输入的坐标不合法,请重新输入。\n");
}
}
//循环结束之后,判断win是不是row*col - NUM_MINE,如果是,则表示排雷成功,然后打印雷区。
if(win == row*col - NUM_MINE)
{
printf("雷排完啦 Nice,You are Thor!!\n");
//打印雷区
printBoard(mine,row,col);
}
}
test.c 扫雷游戏的测试
/*
* 扫雷逻辑:点一个位置,以这个点为中心,周围的八个块中有几个雷,这个位置就显示数字几。
* 第一步:布置雷
* - 创建一个9*9的二维数组,来存储布置的雷。比如随机创建了10个雷
* - 是雷的地方,存储字符'1';不是雷的地方,存储字符'0'
*
* 第二步:排查雷
* - 如果排查出了雷,那我们要放数字1。此时与存放雷的'1'就产生了冲突。
* 此时,可以将存放的雷存储为*,不是雷的存储为#,排查出的雷存储为1。但是在打印的时候要一个一个判断,太麻烦了。
* - 我们可以在创建一个数组,其中专门存放排查出的信息,打印时只打印这个数组。
* 比如点了一个位置,这个位置周围有两个雷,这个位置就存放2。
*
* 所以就是创建了两个数组:
* - 一个数组存储布置的雷; 一个数组存储排除出雷的信息。
* - 类型都是char,这样打印的时候以%c打印就可以了。
*
* - 我们如果要扫四个角,那么可能会出现数组越界。
* - 所以我们定义存放排查信息的数组时,就可以定义大一点,9*9上下左右加一行。第二个数组就需要定义为11*11的二维数组
* - 为了更方便编写,我们可以将存放雷的数组也定义为11*11,这样就与另一个数组可以一一对应了。
* 而实际上我们布置雷的时候,还是在中间布置,不会不知道外围的一圈。
*/
#include "game.h"
void menu()
{
printf("**------ GAME:扫 雷 -------**\n");
printf("**----- 输入1开始游戏 -------**\n");
printf("**------- 输入0退出 --------**\n");
printf("**-------------------------**\n");
}
void game()
{
//定义数组,解耦合:将常量定义到头文件中。
char mine[ROWS][COLS] = {0}; //存放布置的雷
char show[ROWS][COLS] = {0}; //存放排查出雷的信息
//初始化数组函数
initBoard(mine,ROWS,COLS,'0');
initBoard(show,ROWS,COLS,'#');
//打印数组的函数。打印的时候我们只打印其中有雷的区域,没有的我们不打印。
//打印show数组,让玩家来挖雷。
printBoard(show,ROW,COL);
//布置雷:只在下标为1~9的区域布置雷
setMine(mine,ROW,COL);
//给我们自己看的雷区,用于验证。
//printBoard(mine,ROW,COL);
//排查雷:传入两个数组,因为是在1~9的范围排雷,所以传ROW与COL
findMine(mine,show,ROW,COL);
}
int main()
{
int input = 0;
//使用时间戳初始化种子,*5增大时间间隔
srand((unsigned int)time(NULL) *5);
do
{
menu();
printf("请输入:");
scanf("%d",&input);
switch (input) {
case 1:
printf("扫雷吧,少年!!\n");
game();
break;
case 0:
printf("已退出游戏");
break;
default:
printf("输入有误,请重新输入!\n");
}
}while(input);
return 0;
}
逆序数组元素并打印
#include
//
void reverse(int arr[],int sz)
{
//起始下标
int begin = 0;
//结束下标
int end = sz-1;
//第一个和最后一个交换,然后第二个跟倒数第二个交换
while(begin
两个数组一样大,交换其中的元素。
//交换两个数组中的元素
int main()
{
int arr1[] ={1,3,5,7,9};
int arr2[] ={2,4,6,8,10};
int sz = sizeof(arr1)/sizeof(arr1[0]);
int i;
for(i=0 ; i
编程实现,输入年份、月份,就可以输出这一年的这一个月有多少天
//编程实现,输入年份、月份,就可以输出这一年的这一个月有多少天
//闰年的2月是29天,其他年的2月是28天
//
#include
int main()
{
int year,month;
//我们在最前面加一个0,这样是几月,下标为几,就对应这个月的天数。
int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
//如果读取正确,则进入循环
printf("输入年份和月份:");
while (scanf("%d %d",&year,&month) != EOF)
{
int day = days[month];
if(year%4==0&&year%100!=0 || year%400 == 0)
{
if(month ==2)
{
day++;
}
}
printf("%d\n",day);
}
return 0;
}
在一个有序序列中插入数据,并且要求插入后还是有序的
/*
* 有一个有序数字序列,从小到大排列,将一个新输入的数据擦换如到序列中,保证插入新数后,序列仍然是升序。
* 输入:
* 第一行输入一个整数,0≤n≤50 ,也就是说最大是50个数。
* 第二行输入n个升序牌系列的整数,输入用空格分割的n个整数。
* 第三行输入要进行插入的一个整数。
*
* 输出,插入了数据后的有序排列的整数
*/
#include
int main()
{
//序列最多是50个数,算上要插入的数据,应该是最多51个数,所以下标定义为50
int arr[50] = {0};
//整数序列
int n;
printf("多少个数的序列(0≤n≤50):");
scanf("%d",&n);
int i;
printf("输入%d个数:",n);
for(i=0 ; i=0 ; i--)
{
//如果当前元素比要插入的数大,则将当前元素放到后面的那个位置。
//此时arr[i]所在位置就可以放别的元素了。每次循环的时候,这个位置都是为了放其他数字的。
if(arr[i]>m)
{
arr[i+1] = arr[i];
arr[i] = m;
}
else
{
//如果当前元素≤要插入的数,则将要插入的数放在这个数后面
//arr[i+1] = m;//如果放在循环内,则话要考虑当插入的数被所有的的数都要小的这种情况。
//放完之后,已经把数据插入了有序数列,就退出循环
//break;
//可以先跳出去,然后将要插入的数放在这个数后面。
//这样就算要插入的数要比所有的数小,也可以插进去。
break;
}
}
//如果当前元素≤要插入的数,则将要插入的数放在这个数后面
//如果要插入的数比所有的数都要小。也就是说i--之后i=-1了,跳出了循环
//则说明要插入的数比所有的数都小。此时arr[-1+1] = arr[0] ,arr[0]=m,就插进去了。
arr[i+1] = m;
//打印
printf("插入后:\n");
for(i=0 ; i