C语言中数组的知识(后面有三子棋小游戏)

一、数组的创建和初始化

        数组是一组同类型元素的集合,合理运用数组可以帮我们完成一些复杂的操作

        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.cgame.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

        这里的电脑是纯纯的人机,纯人工智障,他不会思考,如果你想让电脑聪明一点可以私信我,还有就是你可以在加一个玩家一对战玩家二的模式,想要的评论呀

        都看到这里啦,还不给个赞吗??!

  • 34
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值