标识符
标识符,就是函数名称(例如int select(void);
select就是标识符);数据名称(例如int _t=5;
t就是标识符)
C语言规定标识符只能由数字、字母和下划线组成,并且不能是C语言的关键字,而且不能以数字开头(例如int while=5;
就会出错)具体见https://baike.baidu.com/item/%E6%A0%87%E8%AF%86%E7%AC%A6/7105638?fr=aladdin
标识符的作用域
实际上标识符的作用域可以分为四种:代码块作用域、文件作用域、原型作用域、函数作用域,这里重点介绍代码块作用域和文件作用域:
代码块作用域
- 代码块就是位于一对大括号
{}
内的代码. - 代码块作用域分为两种:在正常声明时的标识符、函数形式参数中的标识符.
- 正常声明的标识符从声明的地方开始到该代码块结束有效,函数形式参数就像在函数开头声明一样,从函数开始到结尾有效.
文件作用域
- 文件作用域就是在该源文件中有效的标识符,分为两类:在代码块外面声明的标识符、源文件中的函数名称.
- 在代码块外面声明的标识符从声明的地方到该源文件结尾有效,函数名称从声明处到源文件结束有效.
标识符的存储类型
有三个地方可以存储变量:普通内存、运行时堆栈、硬件寄存器.
- 首先说硬件寄存器的存储(这个基本上用不到,原因如下:在该变量被使用的次数太多时编译器会自动将它放到CPU中的寄存器中以便提高效率;有时候即使你自己把变量设置成寄存器类型,编译器也不会理会),只需要在正常声明前加上register就行(例如
register int a;
);另外,寄存器变量在调试时看不到,因为寄存器变量的地址可能一直在变. - 静态存储类型的标识符在程序运行前创建、在整个程序执行期间有效,动态存储类型的标识符在程序运行到该处时创建、在执行流离开该代码块时销毁、无效.
- 在代码块外部声明的变量都不是存储在堆栈中的,这类存储类型叫做静态存储类型(
static
);在代码块内部声明的变量默认存储在堆栈中,这类存储类型叫做动态存储类型(auto
),如果代码块内部声明的变量前面加上关键字auto
,这就跟默认存储类型一样,默认代码块内部声明类型为auto
,如果代码块内部声明前加上关键字static
,就会把默认存储类型改变为静态类型.
标识符的链接属性
- 标识符的链接属性是关于不同文件中标识符的处理问题.
- 链接属性有三种:external(外部链接属性)、internal(内部链接属性)、none(无链接属性).
- 函数定义或者代码块之外的声明,这俩的链接属性默认时external,也就是不仅在该源文件有效,在其他源文件仍有效;如果再加上
static
关键字,就将标识符改为internal链接属性,也就是除了该文件中有效,其他源文件都用不了. - 在代码块内部的声明前加上
extern
关键字,会将该声明变成外部链接属性,即在其他源文件中也有效.
static 关键字
对这个关键字单独解释:
- 当它用于函数定义或者代码块之外的变量声明时,static关键字用于声明标识符的链接属性,而标识符的存储类型和作用域不变(代码块之外的变量存储在静态区,已经是静态变量了,再加static改变其链接属性);
- 当它用于代码块内部的变量声明时,static关键字用于声明变量的存储类型,而标识符的作用域的和链接属性不变