内存:
程序在内存中的分段
当程序开始运行后会加载到内存中,会把内存分成若干段(60)。
每一段的功能和权限不同。
代码段(txt):程序中的二进制指令存储在此段,只读权限。
只读段:存储常量,字符串字面值。(有时和txt合并)
bss段:静态数据段,程序运行时会清理。
全局段(data):存储全局变量。
txt,bss,data当程序编译完成后大小就确定了,可以使用size文件名查看。
---------------------------
栈:局部变量,由操作系统管理,自动申请,释放。
堆:由程序员手动管理
变量:
变量的属性:
存储位置:变量使用的哪一个位置。
作用域:变量的使用范围。
生命周期:创建时间~销毁时间
变量的分类:
全局变量:定义在函数外。
存储位置:未初始化在bss,被初始化在data。
作用域:整个程序。比如在a.c定义全局变量,在b.c中也可以使用。
生命周期:main函数执行前就被定义出,程序运行结束才被释放。
局部变量:定义在函数内。
存储位置:栈
作用域:所在的函数内
生命周期:从定义语句开始~函数执行结束,函数每调用一次就会进行一次定义和释放。
块变量:定义在if,for,,while等语句块中。
存储位置:栈
作用域:所在语句块的大括号内
生命周期:从定义语句开始~函数执行结束。
修饰变量的关键词:
auto 用来定义自动申请内存,自动释放内存的变量(局部,块变量)
不加就代表加,与signed一样。
注意全局变量前不能使用。
const 是对变量提供一种保护,但它不是常量
变量一旦初始化后,就不能再显式修改它的值
const修饰被初始化过的全局变量,才是真正的常量,一旦修改就出现段错误,因为编译器把全局变量的存储位置划分给了text。
static 限制作用域(全局变量,函数),改变存储位置,延长生命周期(局部,块变量)
修饰变量:全局变量:static会限制全局变量的作用域,只能在.c中使用。区域,块变量:改变存储位置,由栈改为bss(未初始化),data(初始化),但作用与没有变,并且会延长生命周期。
修饰函数:
const int func(void);修饰函数返回值;
static int func(void);修饰函数;
由普通函数(外部函数)变为内部函数,只能在.c中调用。
Register
计算机的存储介质:硬盘-》固态硬盘——》内存-》缓存——》缓存-》寄存器
申请把变量的存储位置更改为寄存器,因为寄存器不够,不一定成功。
寄存器变量不能取地址,&变量名。
volatile 不稳定的,易变的,修饰线程间共享的变量,或者硬件编程时使用
如果一个变量的值没有显式的修改,编译器不会再次从内存中读取它的数值,而是直接使用上次的读取结果(优化)。
volatile的功能就是告诉编译器变量的值随时可能发生变化,不要优化它的取值过程(每次用到变量时都去内存中获取它的值)。
~
extern 声明变量,多文件中谁使用
定义:创建变量名,分配存储空间。
声明:创建变量名。
a.c中定义一个全局变量,b.c中如果想使用。
输入输出缓冲区:
输出缓冲区:
当使用printf/puts/putchar等函数显示数据时,并不会直接显示在屏幕上,而是先放入输出缓存区中(提高程序运行效率),当满足某些条件下才会显示出来:
1.遇到\n;
2.从输出转换为输入状态;
3.程序结束;
4.当缓存区满4k数据;
5.手动刷新 fflush(stdout);
输入缓存区:
在终端输入的数据会先存储到输入缓存区中,然后再根据占位解析成对应的数据,如果前一次输入的数据有残留的的垃圾,会影响后续数据的输入。
1.输入字符时前一次输会残留一个空格或‘\n’,解决方法就在%c前加一个空格;
2.如果输入时有若干个垃圾数据,会影响后续所有数据的输入;
1.使用正则表达式,注意:必须确定有垃圾数据再使用。
scanf("%*[^\n]");//*从缓存区获取数据但不存储到变量中
scanf("%*c");
2.设置缓存区中的位置指针
stdin->_IO_read_ptr 开始位置
stdin->_IO_read_end 结束位置
stdin->_IO_read_ptr=stdin->_IO_read_end 清除缓存区数据;