局部变量
- 定义在函数内部,或者循环体等代码块内部。
- 作用域:从定义的那一行开始,直到函数或代码块结束为止。
- 生命周期:程序运行到定义那一行开始分配存储空间,直到离开该变量所在的作用域。
- 存储位置:内存的栈区。
- 特点:相同作用域不可以定义同名变量,内部作用域的变量会覆盖外部作用域的变量。
auto和register关键字
-
auto关键字
只能修饰局部变量,如果局部变量没有修饰符,默认就是auto的。 -
register关键字
只能修饰局部变量,将内存中的变量提升到CPU寄存器中存储,提升访问速度。寄存器数量有限,不同平台和编译器在优化截断会自动转化为auto。
auto int num;
register int sum;
static关键字
延长局部变量的生命周期,从程序启动到程序退出,不会改变作用域。定义变量的代码在整个程序期间仅会运行一次。
#include <stdio.h>
void test();
int main() {
test();//n2的值每次都是一样的,n1的值会在上次修改后的结果上继续修改
test();
test();
}
void test() {
static int n1 = 0;
int n2 = 0;
n1++;
n2++;
printf("n1=%d\n", n1);//1 2 3
printf("n2=%d\n", n2);//1 1 1
}
全局变量
- 定义在函数外部。
- 作用域:从定义的那一行开始,直到文件结尾。
- 生命周期:程序一启动就会分配存储空间,直到程序结束。
- 存储位置:静态存储区。
- 特点:多个同名的全局变量指向同一块存储空间。
- 全局变量分类:
- 内部变量:只能在本文件访问。
- 外部变量:可以在其他文件中访问,默认所有的全局变量都是外部变量。
static关键字
由于多个同名的全局变量共享同一块内存空间,所以会导致全局变量污染问题。
如果想让某个全局变量只在某个文件中使用,并且不和其他文件中同名的全局变量共享同一块内存空间,那么就需要使用static修饰。
extern关键字
声明一个变量,变量只有定义才会开辟存储空间,所以对于局部变量而言,即使提前声明有某个局部变量,但是只有执行到才会分配存储空间,因此,对局部变量无效。而对于全局变量而言,告诉编译器我在其他地方定义了这个变量,你可以放心使用。和函数的声明作用类似。
函数
和全局变量类似,分为内部函数和外部函数。默认即为外部函数。
- 内部函数:只能在本文件访问的函数。函数的定义和声明使用static关键字修饰。
- 外部函数:可以在其他文件中访问的函数。使用extern关键字修饰,默认即为外部函数,所以关键字可以省略。