C-class Week2.Day7

复习:

​ 1,函数声明 告诉编译器函数的格式,方便编译器检查调用者的参数、返回值

​ 2,隐式声明 函数调用时没有声明就会产生,编辑器就会猜测函数的格式,函数的形参会根据调用者提供的实参来猜测

​ 返回值会猜测为int类型。

​ 3,函数定义 函数定义如果出现在函数调用之前,可以省略函数声明

​ 4,函数传参

​ 值传递:普通变量,局部变量,单项值传递,函数之间的变量无法共享 因为是局部变量

​ 址传递:目前来说只有数组是址传递,导致数组的长度会丢失,需要额外增加一个参数传递数组长度,此时就共享了一个数组

​ 返回值:return语句返回给调用者,并不是把数据直接传递给调用者,而是把返回值放在一个他们都能访问的公共区域,如果

没有return语句就会产生一个垃圾值。

进程映像:

​ 程序:储存在磁盘上的文件,二进制文件或者脚本

​ 进程:系统中正在运行的程序

​ 进程映像:就是进程内存的分布情况!

​ text 代码段(只读段):二进制指令、常量、如果强制修改则会产生段错误

​ data 数据段:初全、初静局

​ bss 静态数据段:未初全、未初静局、该段内存在程序运行时会先被清理为0;

​ heap 堆 由程序员手动管理,特点大

​ stack 栈 局部变量、特点小、超过后产生段错误、由系统管理不需要手动申请释放

变量的分类:

​ 储存位置、生命周期、使用范围

​ 全局变量:

​ 取决于是否初始化放在data或者bss

​ 从程序运行开始到结束

​ 程序任何位置使用

​ 局部变量:

​ 定义在函数内的

​ stack中

​ 从定义的位置开始到函数的结束释放

​ 函数内才能使用

​ 块变量:

​ 定义在循环体内的变量

​ stack中

​ 从定义的位置开始到函数结束

​ 只能在语句块内使用

全局变量、局部变量、块变量—均可同名,因为在不同的范围内会屏蔽,使用时应该注意关系!

类型限定符:

​ auto:用于定义自动申请、自动释放的内存,不加代表加,不能用于定义全局变量!也不能与static使用

​ extern:用于声明外部变量、告诉编译器在别的文件有定义,先行通过。当链接时没有找到还是会报错

​ static:

​ 改变储存位置:

​ 局部变量的储存位置变化由stack>data或者bss 取决于是否初始化

​ 延迟生命周期:

​ 局部变量、块变量、不会被销毁 它们的初始化语句只是第一次有效

​ 改变作用域:

​ 全局变量、函数 被加了static就会被限制只能在本文件使用

​ const:保护变量不被显式的修改 初始化过的全局变量和静态局部变量被const修饰后 储存位置就变成text了,就成为了真正的常量

​ 强行修改就会产生段错误、但是通过地址还是可以改的!

​ volatile:不让取值优化、而不会重新读取。适用于硬件编程,或者其他会隐式修改的程序,随时更新变量的值就需要使用

​ register:申请把变量从内存到寄存器,快。但是不是每次都能申请成功!!!!!

​ 注意不能取地址

​ typedef:类型重定义、当定义变量时、前面加上typedef那么变量名就相当于这个类型

​ typedef

​ uint8_t time_t size_t 使用typefdef定义的

​ 注意不是替换就是重定义

五子棋:

思路

​ 1、定义棋盘

​ 2、定义变量用于记录下棋的坐标

​ 3、定义一个棋子角色

业务逻辑:

​ 1、是否需要对数据进行初始化

​ for(;😉

​ {

​ 1、清理屏幕、显示棋盘

​ 2、落子

​ 判断坐标是否合法、该位置是否有棋子

​ 方向键控制—输入x、y坐标

​ 3、判断是否五子连珠

​ 4、交换角色—三目运算符

​ }

利用光标来做比较合适!

棋子— @----$ ↑ ↓ ← →移动 回车下子

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <getch.h>

//	定义棋盘
char board[15][15];

//	定义下棋坐标
char key_x = 7,key_y = 7;

//	定义棋子角色
char role = '@';

//	初始化棋盘
void init_board(void)
{
	for(int x = 0; x<15; x++)
	{
		for(int y = 0; y<15; y++)
		{
			board[x][y] = '*';	
		}
	}
}

//	显示棋盘
void show_board(void)
{
	system("clear");
	for(int x = 0; x<15; x++)
	{
		for(int y = 0; y<15; y++)
		{
			printf(" %c",board[x][y]);	
		}
		printf("\n");
	}
}

//	落子
void get_key(void)
{
	printf("请%c下棋\n",role);
	while(1)
	{
		printf("\33[%hhd;%hhdH",key_x+1,(key_y+1)*2);	
		switch(getch())
		{
			case 183:	key_x>0 && key_x--; 	break;
			case 184:	key_x<14 && key_x++;	break;
			case 185:	key_y<14 && key_y++;	break;
			case 186:	key_y>0	&& key_y--;		break;
			case 10:	
				if('*' == board[key_x][key_y])
				{
					board[key_x][key_y] = role;
					return;
				}
		}
	}
}
//	检查某个方向上有几个相同的棋子
int check_key(int ox,int oy)
{
	int count = 0;
	for(int x=key_x+ox,y=key_y+oy;
			x>=0 && x<15 && y>=0 && y<15; x+=ox,y+=oy)
	{
		if(board[x][y] == board[key_x][key_y])
		{
			count++;	
		}
		else
		{
			break;	
		}
	}
	return count;
}

//	检查是否五子连珠
bool is_win(void)
{
	if(check_key(0,-1)+check_key(0,1) >= 4)
		return true;
	if(check_key(-1,0)+check_key(1,0) >= 4)
		return true;
	if(check_key(-1,-1)+check_key(1,1) >= 4)
		return true;
	if(check_key(-1,1)+check_key(1,-1) >= 4)
		return true;
	return false;
}
int main(int argc,const char* argv[])
{
	init_board();

	for(int i=0;i<225;i++)
	{
		show_board();

		get_key();

		if(is_win())
		{
			show_board();
			printf("恭喜%c胜利!\n",role);
			return 0;
		}
		//	交换角色
		role = role == '@'?'$':'@';
		/*
		if('@' == role)
			r(le = '$';	
		else
			role = '@';
			*/
	}
	printf("平局,你俩真棒!\n");
	return 0;
}

小结:

1、用光标的体验会更好!使用方式是(还可以改变它的形状颜色等。。)

int x=0,y=0;
printf("\33[%d;%dH",x,y);

2、判断方向时,利用左右 上下 斜左 斜右 四个大方向来判断八个小方向是否五子连珠,具体方法见上

3、交换角色,由于只有两个角色可以简单if-else替换

4、要考虑平局情况

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值