一、复习
函数传参:
1、值传递:普通参数通过函数是单向传递,函数之间是不能共享变量的
2、址传递:数组能共享,长度会丢失,需要额外增加一个参数传递数组的长度
3、返回值:return语句不是直接把返回值传递给调用者,而是先拷贝到一个公共内存区域,如果没有return语句,那么调用者从公共区域中获取到的是一个垃圾数据
注意:全局变量也能被程序内任意函数共享
进程映像:
程序:存储在磁盘上的文件(二进制、脚本)
进程:正在系统中运行的程序
进程映像:进程在内存中分布情况
text 代码段:
二进制指令、常量,只读的,如果强制修改会段错误
data 数据段:
初始化的全局变量,初始化过的静态局部变量
bss 静态数据段:
未初始化的全局变量、未初始化的静态局部变量,在程序开始前会自动清理为0
stack 栈:
局部变量和块变量,会自动申请、释放,由操作系统管理,内存小
heap 堆:
由程序员手动申请、释放的内存,优点:足够大
变量的分类:
生命周期、存储位置、使用范围(作用域)
全局变量:定义在函数外
程序开始到结束
data或bss
程序的任意位置
局部变量:定义在函数内
函数开始到函数结束
stack
本函数内使用
块变量:定义在函数内
语句块开始到语句块结束
stack
本语句块内使用
块变量会屏蔽同名全局、局部变量
局部变量会屏蔽同名全局变量
因此要注意变量的命名方式
类型限定符:
auto 声明在佛那个申明、自动释放的变量,不加就代表加了
不能声明全局变量,不能和static同时使用
extern 声明外部的全局变量
告诉编译器该外部变量在程序别的文件中已经定义了,先让程序通过编译阶段,最后在链接时再一起合并成可执行文件,但是如果链接时找不到该定义,依旧会报错
const 保护变量不被显式地修改
修饰data段数据时,会存到text段,吐过强制修改会段错误
static
改变局部变量存储位置
stack->data或bsst
void func(void)
{
static int num=0;
num++;
}
初始化语句只有第一次生效
延长局部变量生命周期
程序开始到结束
限制全局变量作用范围
只能本文件内使用
volatile 让变量的取值取消取值优化过程,无论该变量的值是否显式改变,每次获取都去内存取值
在硬件编程、多线程编程中常用
register 申请变量存储到寄存器中,加快访问速度
寄存器数量有限,不一定成功
而且修饰的变量无法取地址
typedef 类型重定义
typedef int num;
num n1 =10;
常用的:uint8_t time_t size_t 都是重定义出来的名字
注意:它不是替换
typedef int num;//类型重定义
#define num int //替换
五子棋项目:
数据分析:
1、定义(15*15)棋盘的二维数组
2、定义角色变量(1或2) '@'黑棋 '$'白棋 '*'空
3、定义变量用于记录落子位置
逻辑分析:
考虑是否需要初始化循环
for(;;)
{
1、清屏、打印棋盘
2、落子
判断是否超范围 如果是则提示非法并重新落子
判断石头已有棋子,如果是提示并重新落子
成果落子才继续
3、判断是否五子连珠
是:结束程序
4、交换角色
}
要求:每项功能封装成函数,数据可以定义成全局
函数递归:
函数自己调用自己的行为叫做函数递归
递归是分治思想的一种具体实现,就是把复杂而庞大的问题,分解成若干个相似的小问题,解决所有小问题,最终大问题得到解决
如果函数递归缺少出口设置,容易出现类似死循环的效果,且很快内存耗光程序异常结束
注意:如果能用循环解决的问题,不要用递归,因为递归会比循环更耗时耗内存
1、出口*
2、解决一个小问题
3、调用自己