一、数组的创建和初始化
数组是一组同类型元素的集合,合理运用数组可以帮我们完成一些复杂的操作
1.1 一维数组的创建和初始化
一维数组创建的方式:
type_t arr_name[const_n];
//type_t 是指数组的元素类型
//const_n 是一个常量表达式,用来指定数组的大小
一维数组创建的实例:
int arr1[10] = {1,2,3};
int arr2[] = {1,2,3,4};
int arr3[5] = {1,2,3,4,5};
char arr4[3] = {'a',98, 'c'};
char arr5[] = {'a','b','c'};
char arr6[] = "abcdef";
需要注意的是对于下面的代码,内存如何分配
char arr1[] = "abc";
char arr2[3] = {'a','b','c'};
这里arr1其实是有四个字符在里面的( “a” “b” “c” “\0” )
而arr2只有三个字符在里面( “a” “b” “c” )
1.2 一维数组的使用
对于整型数组,使用for循环给数组的输入输出很方便
int main()
{
int i = 0;
int a[10] = { 0 };//不完全初始化
for (i = 0; i < 10; i++)
{
a[i] = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
再补充一个知识点:
数组的大小可以通过计算得到:
sz = sizeo ( a[10] ) / ( a[0] );
1.3 二维数组的创建和初始化
一些实例:
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};
需要注意的是在arr[ ][ ]中,第一个“ [ ] ”表示行,第二个“ [ ] ”表示列,他两的下标都和一维数组一样,从0开始
行可以省略,但是列不行,以为只写列不写行电脑可以帮我们计算出有多少行,但是不写列就无法确定
1.4 二维数组的使用
和一位数组类似,请看以下代码:
int main()
{
int a[3][4] = { 0 };
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
a[i][j] = i + j;
}
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
二、数组作为函数参数
2.1 冒泡排序
在我们写程序的过程中经常需要以一个数组为参数传给我们的函数,就以冒泡排序法为例子
冒泡排序法(升序):第一个数和第二个数比大小,若前一个数大,则这两个数交换,否则这两个数字不变,在用第二个数字和第三个数字比大小,一直循环下去,直到最后一个数字,这样最大的一个数字就能被交换到最后一个,以此类推,第二大的数字在该数组的倒数第二个……直到排到第二个数字。
例:将以下数组排序:6 1 2 8 4 3 0 9 5 7
void paixu(int arr[])
{
int sz = arr[10] / arr[0];
int i = 0;
int j = 0;
for (i = 0; i < sz - 1; i++)
{
for (j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[i];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int i = 0;
int arr[10] = { 6,1,2,8,4,3,0,9,5,7 };
paixu(arr);
for (i = 0; i < 10; i++)
{
printf("%d", arr[i]);
}
return 0;
}
上面这个代码我们直接把数组传给函数paixu()对吗?
运行之后发现程序毛线都没有换,这是为什么呢?
经过调试后发现:在paixu()函数中的sz的值为1,说明无法一组的数组直接传给函数
是因为我们在传参的时候,数组名“arr”只是数组开始的第一个地址,但是数组有多少个,无法传给paixu()函数中
所以我们现在主函数中把sz算出来,在给他和“arr”一起传给函数paixu(),就能解决这个问题
void paixu(int* arr, int sz)
{
int i = 0;
int j = 0;
for (i = 0; i < sz - 1; i++)
{
for (j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int i = 0;
int arr[10] = { 6,1,2,8,4,3,0,9,5,7 };
int sz = sizeof(arr) / sizeof(arr[0]);//在这里计算函数大小
paixu(arr, sz);//这里把函数的大小一起传过去
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
搞定!
三、三子棋小游戏
只要知道游戏运行的大体思路,运用选择语句、循环语句、数组、函数已经可以写出一些较为复杂的小游戏了,那么不多废话,开始写我们的第一个小游戏:三子棋
这里我想用三个文件来实现这个游戏,使得这个游戏的代码更加通俗易懂
在fox.c文件为游戏运行的整体逻辑,game.c和game.h分别为实现这个游戏运行的代码
3.1 目录
和之前猜数字游戏类似,简单的打印出一个目录就行
#define _CRT_SECURE_NO_WARNINGS 1;
#include"game.h"
void menu()//菜单函数
{
printf("*********************\n");
printf("**** 1.play ****\n");
printf("**** 0.exit ****\n");
printf("*********************\n");
}
void test()
{
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始游戏\n");
break;
case 0:
printf("游戏结束,下次再见!\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
程序能运行,继续下一步
3.2 打印棋盘
棋盘其实就只是一个3*3的格子,所以这里我们需要创建一个二维数组,先给棋盘初始化,在打印棋盘
//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);
//打印棋盘
void print_board(char board[ROW][COL], int row, int col);
void init_board(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++)
{
board[i][j] = ' ';
}
}
}
void print_board(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 < col - 1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
3.3 玩家下棋
玩家下棋其实就是将制定坐标改为棋子,这里用星号*代表玩家下的棋
注意玩家输入的坐标是1 2 3,并不是数组下标的0 1 2 ,这里需要改一下,并且判断下棋的合理性
//玩家下棋
void player_move(char board[ROW][COL], int row, int col)
void player_move(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋\n");
while (1)
{
printf("请输入下棋坐标:");
scanf("%d %d", &x, &y);
if (1 <= x && x <= 3 && 1 <= y && y <= 3)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("该格子已被占用,请重新输入\n");
}
}
else
{
printf("非法输入,请重输\n");
}
}
}
fox.c中游戏运行逻辑为:
void game()
{
char board[ROW][COL];
init_board(board, ROW, COL);//初始化棋盘
print_board(board, ROW, COL);//打印棋盘
while (1)
{
player_move(board, ROW, COL);//玩家下棋
print_board(board, ROW, COL);//打印棋盘
}
}
3.4 电脑下棋
让电脑随机生成两个0~2数,作为坐标x y下棋,同样需要判断一下该棋格是否已经有棋子了
//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col)
{
while (1)
{
int x = rand() % 3;
int y = rand() % 3;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
3.5 判断输赢
这里用一个变量ret来接收判断输赢函数输出的四个信号
若玩家赢输出:*
若电脑赢输出;#
若游戏继输出:C
若平局输出:P
char is_win(char board[ROW][COL], int row, int col)
{
int i = 0;
//判断行
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] != ' ')
return board[i][0];
}
//判断列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] != ' ')
return board[0][i];
}
//判断交叉
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
return board[1][1];
//判断平局
int ret = is_full(board, ROW, COL);
if (1 == ret)
{
return 'P';
}
return 'c';
}
此时游戏运行逻辑为:
void game()
{
char board[ROW][COL];
char ret = 0;
init_board(board, ROW, COL);//初始化棋盘
print_board(board, ROW, COL);//打印棋盘
while (1)
{
player_move(board, ROW, COL);//玩家下棋
print_board(board, ROW, COL);//打印棋盘
ret = is_win(board, ROW, COL);//判断输赢
if (ret != 'C')
{
break;
}
computer_move(board, ROW, COL);//电脑下棋
print_board(board, ROW, COL);//打印棋盘
ret = is_win(board, ROW, COL);//判断输赢
if (ret != 'C')
{
break;
}
}
if (ret == '*')
printf("玩家赢\n");
else if (ret == '#')
printf("电脑赢\n");
else
printf("平局\n");
}
这样游戏就做完啦
3.6 游戏全代码
game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);
//打印棋盘
void print_board(char board[ROW][COL], int row, int col);
//玩家下棋
void player_move(char board[ROW][COL], int row, int col);
//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);
//判断输赢
char is_win(char board[ROW][COL], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1;
#include"game.h"
void init_board(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++)
{
board[i][j] = ' ';
}
}
}
void print_board(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 < col - 1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
void player_move(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋\n");
while (1)
{
printf("请输入下棋坐标:");
scanf("%d %d", &x, &y);
if (1 <= x && x <= 3 && 1 <= y && y <= 3)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("该格子已被占用,请重新输入\n");
}
}
else
{
printf("非法输入,请重输\n");
}
}
}
void computer_move(char board[ROW][COL], int row, int col)
{
while (1)
{
int x = rand() % 3;
int y = rand() % 3;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int is_full(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++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
char is_win(char board[ROW][COL], int row, int col)
{
int i = 0;
//判断行
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] != ' ')
return board[i][0];
}
//判断列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] != ' ')
return board[0][i];
}
//判断交叉
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
return board[1][1];
//判断平局
int ret = is_full(board, ROW, COL);
if (1 == ret)
{
return 'P';
}
return 'C';
}
fox.c
#define _CRT_SECURE_NO_WARNINGS 1;
#include"game.h"
void menu()
{
printf("*********************\n");
printf("**** 1.play ****\n");
printf("**** 0.exit ****\n");
printf("*********************\n");
}
void game()
{
char board[ROW][COL];
char ret = 0;
init_board(board, ROW, COL);//初始化棋盘
print_board(board, ROW, COL);//打印棋盘
while (1)
{
player_move(board, ROW, COL);//玩家下棋
print_board(board, ROW, COL);//打印棋盘
ret = is_win(board, ROW, COL);//判断输赢
if (ret != 'C')
{
break;
}
computer_move(board, ROW, COL);//电脑下棋
print_board(board, ROW, COL);//打印棋盘
ret = is_win(board, ROW, COL);//判断输赢
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("玩家赢\n");
}
else if (ret == '#')
{
printf("电脑赢\n");
}
else
{
printf("平局\n");
}
}
void test()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始游戏\n");
game();
break;
case 0:
printf("游戏结束,下次再见!\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
3.7 Ps
这里的电脑是纯纯的人机,纯人工智障,他不会思考,如果你想让电脑聪明一点可以私信我,还有就是你可以在加一个玩家一对战玩家二的模式,想要的评论呀
都看到这里啦,还不给个赞吗??!