系统学习之C复习(4)数组-创新互联
数组:一组相同类型元素的合集。
我们提供的服务有:成都网站设计、成都网站制作、微信公众号开发、网站优化、网站认证、息烽ssl等。为超过千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的息烽网站制作公司int n = 10;
int arr[n] = {0};
但是 n 不可以变化
C99中引入了变长数组的概念,允许数组的大小用变量指定。
如果编译器不支持的C99中的变长数组,则不能使用
数组的初始化:在创建的时候赋值
不完全初始化:不赋值完,后续默认0;
int arr[] = {1,2,3,4} 不赋数组大小,系统默认分配。
int arr[10]; 数组不赋值系统分配随机值。
二:一维数组的使用 三:一维数组在内存中的存储打印数组中每个元素中的地址——%p (16进制)
#include
#include int main() { char arr1[10] = { 1,2,3,4,5,6,7,8,9,10 }; int i = 0; int sz = sizeof(arr1) / sizeof(arr1[0]); //计算数组元素个数。 for (i = 0; i< sz; i++) { printf("&arr1[%d] = %p\n", i, &arr1[i]); } return 0; }
一组数组在内存是连续的。随着数组下标的增加,地址由低到高。
用指针访问数组
#include#includeint main()
{
char arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
int sz = sizeof(arr1) / sizeof(arr1[0]); //计算数组元素个数。
char* p = &arr1[0];
for (i = 0; i< sz; i++)
{
printf("&arr1[%d] = %p<=====>%p\n", i, &arr1[i],p+i);
}
return 0;
}
四:二维数组的创建和初始化int arr[3][5]; //三行五列
int arr[3][5] = {{1,2},{3,4},{5,6}}; // 一个{}一行
可以省略行,不可以省略 列
int arr[][5] = {1,2,3,4,5,6,7}; //此时只有两行,系统自动发配行
int arr[][5] = {{1,2},{3,4},{5,6}}; //此时三行
五:二维数组的使用二维数组的访问:
int main()
{
//int arr[3][5] = {1,2,3,4,5,6,7}; //三行五列
int arr[][5] = { {1,2},{3,4},{5,6} };
int i = 0;
//for (i = 0; i< sizeof(arr) / arr[0]; i++)//0 1 2
for (i = 0; i< 3; i++)//0 1 2 行
{
int j = 0;
for (j = 0; j< 5; j++) //列
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
六:二维数组在内存中的存储和一维数组一样。连续的。 第一列的最后一位与第二列的第一位相连。
七:数组越界请程序员本身注意。
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
for(i=0;i<=10;i++) //此处越界,c语言本身不检查。
{
printf("%d ",arr[i]);
}
return 0;
}
八:数组作为函数参数
冒泡排序的错误方式三子棋冒泡排序
数字中2个相邻的元素进行比较,如果不满足顺序则交换。
距离
若: 9 8 7 6 5 4 3 2 1 排序为升序
第一次: 第二次:
8 9 7 6 5 4 3 2 1 0 7 8 6 5 4 3 2 1 0 9
8 7 9 6 5 4 3 2 1 0 7 6 8 5 4 3 2 1 0 9
8 7 6 9 5 4 3 2 1 0 ……
……
8 7 6 5 4 3 2 1 0 9
一趟冒泡排序搞定一个
int bubble_sort(int* arr) { int sz = sizeof(arr) / sizeof(arr[0]); int i = 0; for (i = 0; i< sz; i++) { //每一趟冒泡排序 int j = 0; for (j = 0; j< sz - 1 - i; j++) { if (arr[j] >arr[j + 1]) //交换 { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } } int main() { int arr[] = { 9,8,7,6,5,4,3,2,1,0 }; bubble_sort(arr); int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); for (i = 0; i< sz; i++) { printf("%d ", arr[i]); } return 0; } //此时 输出依旧依旧是9 8 7 6 5 4 3 2 1 0
经过调试,我们发现sz = 1;
首先,数组名是什么?
printf("%p\n",arr); printf("%p\n",&arr[0]); //这两者输出一致
数组名就是数组的首元素的地址;
有2个例外:
&数组名 与 sizeof(数组名),此时数组名不是数组首元素的地址,是代表整个数组
arr 与 &arr[0] 都是数组首元素地址, &arr是数组地址。
所以,函数中的 sz 计算的1;
修改:将sz的计算放到函数外计算,作为参数传进去。
int bubble_sort(int* arr, int sz) { int i = 0; //int sz = sizeof(arr) / sizeof(arr[0]); //因为传进来的是数组首元素地址,所以 sz = 1; //将此计算大小移出计算,作为参数传进来。 for (i = 0; i< sz; i++) { //每一趟冒泡排序 int j = 0; for (j = 0; j< sz - 1 - i; j++) { if (arr[j] >arr[j + 1]) //交换 { int tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } } int main() { int arr[] = { 9,8,7,6,5,4,3,2,1,0 }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz); int i = 0; // int sz = sizeof(arr) / sizeof(arr[0]); for (i = 0; i< sz; i++) { printf("%d ", arr[i]); } return 0; }
先 确定框架,
再 测试基本逻辑是否运行
最后编写game内容
首先 基本框架与逻辑
#define _CRT_SECURE_NO_WARNINGS 1 #include
#include "game.h" void menu() { printf("***************\n"); printf("**按1开始游戏**\n"); printf("**按0结束游戏**\n"); printf("***************\n"); } void game() { } int main() { int input = 0; do { menu(); printf("请选择:>"); scanf("%d", &input); switch(input) { case 1: game(); break; case 0: printf("退出游戏"); break; default: printf("请选择1or0\n"); break; } } while (input); return 0; } 然后 新建一个 game.h和game.c文件,进行模块化
游戏的内容都在game.c里面写,主函数调用即可。
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void InitBoard(char board[ROW][COL], int row, int col)//row 行 col 列 { int i = 0; for (i = 0; i< row; i++) { int j = 0; for (j = 0; j< col; j++) { board[i][j] = ' '; } } } void DisplayBoard(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i< row; i++) { int j = 0; printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]); printf("---|---|---\n"); } }
//这段代码的效果限制了 列的生成,倘若生成 10*10,那么依旧只显示3列。 为此,修改成如下
void DisplayBoard(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i< row; i++) { int j = 0; for (j = 0; j< col; j++) //每打印一个数据,后面跟一个 | { printf(" %c ", board[i][j]); if(j
棋盘构成了。随后棋手入场。
电脑和玩家 各自下棋。
电脑和玩家 各自下棋。
void game() { //存放下棋的数据 char board[ROW][COL] = { 0 }; //初始化棋盘为全空额 InitBoard(board, ROW, COL); //打印棋盘 DisplayBoard(board, ROW, COL); while (1) { //玩家下棋 player_move(board, ROW, COL); DisplayBoard(board, ROW, COL); //电脑下棋 conputer_move(board, ROW, COL); DisplayBoard(board, ROW, COL); } }
//玩家下棋 void player_move(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { printf("玩家下棋\n"); printf("请输入坐标:>"); scanf("%d %d", &x, &y); if (x >= 1 && x<= row && y >= 1 && y<= col) { //下棋 if (board[x - 1][y - 1] == ' ')//判断该坐标是否被占用(是否已经被下子) { board[x - 1][y - 1] = '*'; break; //记得brak退出 前面在死循环 } else { printf("该坐标已被占用,请重新输入\n"); } } else printf("非法坐标,请重新输入\n"); } } //电脑下棋 void conputer_move(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; //使用rand()生成随机数前需要调用 //srand((unsigned int)time(NULL)); #include
#include printf("电脑下棋\n"); while (1) { x = rand() % row; //0~ROW-1 y = rand() % col; //0~COL-1 //落子的地方需要就判断是否有子 if (board[x][y] == ' ') { board[x][y] = '#'; break; } } } 选手下完棋子后,需要判断游戏状态 。
死种游戏状态: 令:
玩家赢 —— 返回 ' * '
电脑赢 —— 返回 ' # '
平局 —— 返回 ' Q '
继续 —— 返回 ' C '
每一次 落子后就需要判断。
char ret = 0; while (1) { //玩家下棋 player_move(board, ROW, COL); DisplayBoard(board, ROW, COL); //判断输赢 ret = is_win(board, ROW, COL); if (ret != 'C') { break; } //电脑下棋 conputer_move(board, ROW, COL); DisplayBoard(board, ROW, COL); //判断输赢 ret = is_win(board, ROW, COL); if(ret != 'C') { break; } } if ('*' == ret) { printf("玩家赢了\n"); } else if ('#' == ret) { printf("你给电脑赢了??\n"); } else if('Q' == ret) { printf("平局\n"); }
判断 横、竖 、对角线 ,棋盘满子 等四种情况
char is_win(char board[ROW][COL], int row, int col) { // 判断横竖三,对角线是否三个相同的 int i = 0; int j = 0; int count = 0; for (i = 0; i< row; i++)//判断ROW行 { for (j = 1; j< col; j++) { if (board[i][j] == board[i][j - 1] && board[i][j] != ' ') { count++; } if (count == GAME_COUNT - 1) { return board[i][j]; } } count = 0; } for (j = 0; j< col; j++)//判断COL列 { for (i = 1; i< row; i++) { if (board[i][j] == board[i-1][j] && board[i][j] != ' ') { count++; } if (count == GAME_COUNT - 1) { return board[i][j]; } } count = 0; } for (i = 1, j = 1; i<= row || j<= col; i++, j++) //判断对角线 { if (board[i][j] == board[i - 1][j - 1] && board[i][j] != ' ') { count++; } if (count == GAME_COUNT - 1) { return board[i][j]; } count = 0; } if (FULL == is_full(board, ROW, COL))//判断平局 { return 'Q'; } return 'C'; }
//检测是否棋盘满子 int is_full(char board[ROW][COL],int row, int col) { int i = 0; int j = 0; for (i = 0; i< row; i++)//判断ROW行 { for (j = 0; j< col; j++) { if (board[i][j] == ' ') { return 0; } } } return 1; }
用count++计数, 当有一次相同时,count 计数+1,
每一行或者每一列 检测完毕的时候count清零。为下一行重新检测
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站栏目:系统学习之C复习(4)数组-创新互联
网站地址:http://scyanting.com/article/didjej.html