c语言鹏哥学习笔记(数组)

目录

数组

数组的定义

数组初始化

----字符数组

数组元素调用与查看

二维数组

初始化

使用与遍历

地址

用指针遍历

数组作为函数参数

----冒泡排序

 --------冒泡排序 提高效率(防止一开始就是排好的)

----数组名是数组首元素地址(两个例外)

数组作为函数传参时,两种形式

三子棋

扫雷


数组

一组相同类型元素的集合

数组的定义

数组元素类型  数组名  [常量表达式(用来指定数组的大小)]

数组[ ]内的一定是常量表达式

数组初始化

完全初始化 与 不完全初始化

	int arr[5] = { 1,2,3,4,5 };//完全初始化
	int arr1[5] = { 1 };//不完全初始化,剩下元素的全是0

不写常数表达式

int arr2[] = { 1,2,3 };

不写常数表达式,根据后面的元素个数确定数组大小

----字符数组

	char arr3[] = { 'a','b','c' };//三个,无'\0'
	char arr4[5] = { 'a' };//剩下的默认为0,等价于'\0'
	char ch1[4] = "si";//默认有s i \0
	char ch2[] = "wq";//默认有 w q \0

数组元素调用与查看

	arr[0] = 9;//数组元素调用

	int sz = sizeof(arr) / sizeof(arr[0]);//数组元素访问
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d", arr[i]);
	}

1.一维数组在内存中是连续存放的

2.随着数组下标的增长,地址是由高到低变化的

二维数组

arr[3][4]   //3行4列

初始化

初始化--创建同时赋值

	int arr[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	//{1,2,3,4}.{5,6,7,8},{9,10,11,12}

	int arr1[3][4] = { 1,2,3,4 };
	//空缺补0

	int arr2[2][3] = { {1,2,3},{4,5,6} };

	int arr4[2][3] = { {1},{2} };
	//空缺补0 {{1,0,0},{2,0,0}}

int arr  [行]  [列]

行可以省,列不能省

使用与遍历

数组名 [行号] [列号]

int main()
{
	int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
	int i = 0;
	int j = 0;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf(" %d", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

地址

int main()
{
	int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
	int i = 0;
	int j = 0;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("arr[%d][%d]=%p\n",i,j,&arr[i][j]);
		}
	}
	return 0;
}

(可以发现是连续的 相差4整型内存大小是4)

二维数组在内存中也是连续存放的(跨行也是连续的)

列不能省略的原因,省略了列 就不知道下一个元素该放在哪里

用指针遍历

//二维数组遍历 用指针
int main()
{
	int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };

	int* p = &arr[0][0];
	int i = 0;
	for (i = 0; i <12; i++)
	{
		printf("%d ", *p);
		p++;
	}
	return 0;
}

数组作为函数参数

----冒泡排序

两两相邻的元素进行比较,并且可能的话需要交换

//冒泡排序
void b_sort(int arr[], int sz)
{
	int i = 0;
	for (i = 1; i <= sz - 1; i++)//n个元素,一共n-1趟
	{
		int j = 0;
		for (j= 0;j<sz-i;j++)//每一趟一共交换n-1次
		{
			if (arr[j+1]<arr[j])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}

int main()
{
	int arr[] = { 1,6,8,6,3,88,99,3,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	b_sort(arr,sz);

	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf(" %d", arr[i]);
	}
	return 0;
}

 --------冒泡排序 提高效率(防止一开始就是排好的)

//冒泡排序
void b_sort(int arr[], int sz)
{
	int i = 0;
	for (i = 1; i <= sz - 1; i++)//n个元素,一共n-1趟
	{
		int flag = 1;
		int j = 0;
		for (j= 0;j<sz-i;j++)//每一趟一共交换n-1次
		{
			if (arr[j+1]<arr[j])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				int flag = 0;//排序一次就将其赋值为0
			}
		}
		if (flag==1)
		{
			break;//第一次交换,交换了0次,说明本来就是有序的
		}
	}
}

int main()
{
	int arr[] = { 1,6,8,6,3,88,99,3,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	b_sort(arr,sz);

	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf(" %d", arr[i]);
	}
	return 0;
}

----数组名是数组首元素地址(两个例外)

1.sizeof(数组名)-----数组名表示整个数组,计算的是整个数组的大小--单位是字节

2.&数组名---数组名表示整个数组--取出的是整个数组的地址

数组作为函数传参时,两种形式

数组形式

void test (int arr [6][3])

void test (int arr [][3])     行可以省略,列不能省略

指针形式

数组传参就是在传数组,只是形参形式不同

三子棋

rand做随机数时  

rand()%3  余数不大于3 其表示不大于三的正整数

test.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void game()
{
	char date[rr][ll];

	initchess(date, rr, ll);//初始化棋盘
	printchess(date, rr, ll);//打印棋盘

	while (1)
	{
		player(date, rr, ll);//玩家下棋
		printchess(date, rr, ll);//打印棋盘
		if (is_win(date,rr,ll)!='C')
		{
			break;
		}

		computer(date, rr, ll);//电脑下棋
		printchess(date, rr, ll);
		if (is_win(date, rr, ll) != 'C')
		{
			break;
		}
	}

	if (is_win(date,rr,ll)=='*')
	{
		printf("玩家胜利\n");
	}
	if (is_win(date, rr, ll) == '#')
	{
		printf("电脑胜利\n");
	}
	if (is_win(date, rr, ll) == 'D')
	{
		printf("和局\n");
	}

	Sleep(3000);
	system("cls");
}

int main()
{
	int sel = 0;

	do 
	{
		printf("* * * * * * * * * * * * * * * * * * *\n");
		printf("* * * * * * *1.play * * * * * * * * *\n");
		printf("* * * * * * *0.exit * * * * * * * * *\n");
		printf("* * * * * * * * * * * * * * * * * * *\n");
		printf("请选择->");

		scanf("%d", &sel);

		switch (sel)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入不合法\n");
		}
	} while (sel != 0);

	return 0;
}

game.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"


void initchess(char date[rr][ll], int r, int l)//棋盘的初始化
{
	int i = 0;
	int j = 0;
	for (i = 0; i <r; i++)
	{
		for (j = 0; j < l; j++)
		{
			date[i][j] = ' ';
		}
	}
}

void printchess(char date[rr][ll], int r, int l)//棋盘的打印
{
	int i = 0;
	int j = 0;
	for (i = 0; i < r; i++)
	{
		for (j = 0; j < l; j++)
		{
			printf(" %c ", date[i][j]);
			if (j < l - 1)
			{
				printf("|");
			}
		}
		printf("\n");

		for (j = 0; j < l; j++)
		{
			printf("---");
			if (j < l - 1)
			{
				printf("|");
			}
		}
		printf("\n");
	}
	printf("\n");
}

void player(char date[rr][ll], int r, int l)//玩家下棋
{
	int i = 0;
	int j = 0;
	printf("玩家走\n");

    
	while (1)
	{
		printf("请输入坐标->");
		scanf("%d %d", &i, &j);

		if (i < rr + 1 && j < ll + 1 &&date[i-1][j-1]==' ')
		{
			date[i-1][j-1] = '*';
			break;
		}
		else
		{
			printf("输入非法\n");
		}
	}
}


void computer(char date[rr][ll], int r, int l)//电脑走
{

	printf("电脑走\n");
	while (1)
	{
		srand((unsigned int)time(NULL));
		int i = rand() % 3;
		int j = rand() % 3;//可以得到比三小的随机数
		if (i < rr && j < ll&&date[i][j]==' ')
		{
			date[i][j] = '#';
			break;
		}
		else
		{
			continue;
		}
	}
}

//#是电脑下的棋 *是玩家下的棋
//所以
//返回 #----电脑赢
//     *----玩家赢
//	   C----继续
//	   D----平局   都是字符

int is_full(char date[rr][ll], int r, int l)
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < l; j++)
		{
			if (date[i][j]==' ')
			{
				return 0;
			}
		}
	}
	return 1;

}

char is_win(char date[rr][ll], int r, int l)//判断是否胜利
{
	int i = 0;
	for (i = 0; i < r; i++)//行上相等
	{
		if (date[i][0] == date[i][1] && date[i][1] == date[i][2]&&date[i][0] != ' ')
		{
			return date[i][0];
		}
	}

	for (i = 0; i < r; i++)//列上相等
	{
		if (date[0][i]==date[1][i]&&date[1][i]==date[2][i]&date[0][i] != ' ')
		{
			return date[0][i];
		}
	}

	if ((date[0][0]==date[1][1]&&date[1][1]==date[2][2])||(date[2][0]==date[1][1]&&date[1][1]==date[0][2]&date[1][1] != ' '))//对角相等
	{
		return date[0][0];
	}

	if (is_full(date, r, l) == 1)
	{
		return 'D';
	}
	else
	{
		return 'C';
	}
}

game.h

#pragma once
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

#define rr 3
#define ll 3

void initchess(char date[rr][ll],int,int);
void printchess(char date[rr][ll], int, int);

void player(char date[rr][ll], int, int);

void computer(char date[rr][ll], int, int);

char is_win(char date[rr][ll], int, int);

扫雷

两个棋盘 一个存雷 一个存信息

n*n 的棋盘 数组大小(n+1)*(n+1)   -----扫描周围八个 防止边缘不够八个

实参  arr 不用标

形参 int aa(int arr[ ][列不能省去 ] )

数字 n +48     的ACALL码值是字符  'n'

即  n+'0'='n'

字符0的值为48

函数前加上static (只能在该源文件中使用)

game.c

#include "game.h"

void initchess(char date[rows][cols], int r, int c, char s)//初始化雷盘
{
	for (int i = 0; i < r; i++)
	{
		for (int j = 0; j < c; j++)
		{
			date[i][j] = s;
		}
	}
}

void displaychess(char date[rows][cols], int r, int c)//展示棋盘
{
	printf("-------------扫雷游戏-------------\n");
	for (int ii = 0; ii <= col; ii++)
	{
		printf("%d ", ii);
	}
	printf("\n");

	for (int i = 1; i <= r; i++)
	{
		printf("%d", i);
		for (int j = 1; j <= c; j++)
		{
			printf(" %c", date[i][j]);
		}
		printf("\n");
	}
	printf("-------------扫雷游戏-------------\n\n");
}

void initmine(char date[rows][cols], int r, int c)
{
	int r_count = count;
	while (r_count != 0)
	{
		int ii = rand() % 9 + 1;
		int jj = rand() % 9 + 1;//随机埋雷点

		if (date[ii][jj] == '0')
		{
			date[ii][jj] = '1';
			r_count--;
		}
	}
}

int mine_num(char mine[rows][cols], int x, int y)
{
	return (mine[x - 1][y - 1] - '0') +
		(mine[x][y - 1] - '0') +
		(mine[x + 1][y - 1] - '0') +
		(mine[x - 1][y] - '0') +
		(mine[x + 1][y] - '0') +
		(mine[x - 1][y + 1] - '0') +
		(mine[x][y + 1] - '0') +
		(mine[x + 1][y + 1] - '0');
}

void Findmine(char show[rows][cols], char mine[rows][cols], int r, int c)
{
	int x = 0;
	int y = 0;

	int win = 0;//没有猜中地雷的次数

	while (win < ((row * col) - count))
	{
		printf("输入坐标->");
		scanf("%d %d", &x, &y);

		if (mine[x][y] == '1')
		{
			printf("踩中地雷\n");
			break;
		}

		else {
			int shu = mine_num(mine, x, y);
			show[x][y] = shu + '0';
			win++;
			displaychess(show, row, col);
		}
	}

	if (win == ((row * col) - count))
	{
		printf("胜利!!!!!\n");
	}
}

game.h

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include <stdio.h>
#include <time.h>

#define rows 11 //真实棋盘大小
#define cols 11

#define row 9 //展示的棋盘大小
#define col 9

#define count 80//埋雷数量

void initchess(char date[rows][cols],int r,int c, char s);//初始化棋盘

void displaychess(char date[rows][cols], int r, int c);//展示棋盘

void initmine(char date[rows][cols], int r, int c);//埋雷

void Findmine(char show[rows][cols], char mine[rows][cols], int r, int c);//找雷

test.c

#include "game.h"

void game()
{
	printf("开始游戏!!!!!\n");
	char mine[rows][cols];//雷
	char show[rows][cols];//展示

	initchess(mine,rows, cols,'0');//初始化雷盘
	initchess(show,rows, cols,'*');//初始化展示盘

	displaychess(show, row, col);//展示棋盘

	initmine(mine, row, col);//埋雷
	displaychess(mine, row, col);//展示雷区

	Findmine(show,mine, rows, cols);//找雷

	printf("五秒后开始下一局");
	Sleep(5000);
	system("cls");
}

int main()
{
	int sel = 0;

	srand((unsigned int)time(NULL));
	do
	{
		printf("* * * * * * * * * * * * * * * * *\n");
		printf("* * * * * * *1.play * * * * * * *\n");
		printf("* * * * * * *2.exit * * * * * * *\n");
		printf("* * * * * * * * * * * * * * * * *\n");
		printf("请选择->");
		scanf("%d", &sel);

		switch (sel)
		{
		case 1:
			game();
			break;
		case 2:
			break;
		default:
			printf("输入错误\n");
			break;
		}
	} while (sel != 2);

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值