常用关键字
关键字有32个,但是真正常用的关键字也就几个,这些常用关键字分别是const、static、extern、auto、volatile、register,想要掌握这些关键字得先知道以下几个方面的知识
作用域
作用域:标识符名称的默认使用范围(即代码内可以直接用命名的名称去代替实体,而无需其他的辅助操作)
1、局部作用域:定义在语句所在行开始到定义语句隶属的复合语句结尾
2、文件作用域:定义语句所在行开始到所属的.c文件结束
链接性
链接性:标识符作用域之外,能不能用相应的名称代表定义的实体,如果能范围是多大,需要提供什么辅助
1、无链接性:该名称只能在其作用域之外使用
2、内部链接性:作用域之外,在本.c文件之内可用,在用之前需要用对应的声明语句辅助
3、外部链接性:作用域之外,在任何.c文件里面都可以用,在用之前也要对应的声明语句辅助
生存期
生存期是指程序中分配的内存空间在什么时间段可以使用
1、自动存储时期:从定义语句被执行的这个时刻开始到这个定义语句所隶属的复合语句被执行完成的时刻
2、静态存储时期:从程序运行前到程序运行结束(即整个程序运行的时间)
3、动态存储时期:从程序员malloc一块内存空间开始到程序员调用free函数结束的时刻
内存四区
前面说完标识符的生存期,作用域、链接性,之后咱们得知道在关键字修饰的这些变量之前分别放在内存的哪里,修饰内存之后这些变量在内存的区域又会发生什么变化
栈区
这个栈区和数据结构的栈区是不同的概念,前者是真实存在的,后者是为了描述数据结构抽象出来的东西
栈区是有编译器自动生成的,存放的是局部变量,形参,一但所属的语句结束,内存空间自动释放
堆区
堆区是程序员自己申请分配的空间,如果在程序结束之前程序员不释放的话,那这个空间会一直存在,直到当前的程序结束
代码区
顾名思义这是存放二进制代码的区域
数据区
数据区又分为三个段,一个是常量段,存放的是字符串常量以及其他常量,在程序结束后由系统统一回收,另两个分别是初始化段、未初始化段,存放的是全局变量、静态变量,初始化的全局变量和静态变量在一个段(非BSS段),未初始化的全局变量、静态变量一个段(BSS段),在程序结束后由系统回收
关键字
通过以上描述我们可以知道一个变量(标识符)的生存期,作用域、链接性以及在内存中的区域,这个时候我们使用关键字会不会改变这些特性
static关键字
static在修饰局部变量的时候,局部变量的生存期有自动存储时期变为静态存储时期
static在修饰全局变量的时候,全局变量的链接性从外部链接性变为了内部链接性
static在修饰函数定义的时候,函数的链接性也是从外部链接性变为了内部链接性
const关键字
const关键字:可以理解为只读的变量
1、const在修饰局部变量和形参
因为局部变量和形参仍然在栈内,但栈区没法做成只读,因此:
1>后续的代码不可通过变量名区修改它的内容,否则编译会出错
2>但可以通过其地址值去修改它的内容,
2、修饰全局变量
全局变量的空间由数据区可读可写段转移到常量段,因此:
1>后续的代码不可通过变量名区修改它的内容,否则编译会出错
2>也不可以通过其地址值去修改它的内容,否则程序运行会发生段错误
注意:const修饰变量定义一定要初始化,否则const关键字不起作用
3、const修饰指针
1、是指针自身空间只读,此时的const关键字后应该紧跟着指针名
例:int * const pter;
2、是不可以通过指针变量名区修改其指向的几级指向内存地址的内容
例:int const * pter;
register关键字
1、用于修饰非static局部变量和函数形参
2、是一个建议性的关键字,非强制性的,实际是建议编译器尽量使用CPU寄存器
3、register修饰的非static局部变量和函数形参,代码中不可以出现取地址运算符
auto关键字
1、用于修饰非static局部变量和函数形参
2、该关键字可以省略,用于说明该变量或形参的生存期是自动存储时期
extern关键字
给非static全局变量和非static函数做声明用
volatile关键字
1、volatile意思是易变的,说明此关键字修饰的变量空间的内容是易变的
2、通知编译器不要对此变量做任何形式的优化,即每次使用该变量都去访问它的内存空间