「基本概念:」
- 作用域:起作用的区域,也就是可以工作的范围。
- 代码块:所谓代码块,就是用{}括起来的一段代码。
- 数据段:数据段存的是数,像全局变量就是存在数据段的
- 代码段:存的是程序代码,一般是只读的。
- 栈(stack):先进后出。C语言中局部变量就分配在栈中。
「局部变量」
普通的局部变量定义的时候直接定义或者在前面加上auto
void func1(void) { int i = 1; i++; printf("i = %d.\n", i); }
局部变量i的解析:
在连续三次调用func1中,每次调用时,在进入函数func1后都会创造一个新的变量i,
并且给它赋初值1,然后i++时加到2,
然后printf输出时输出2.然后func1本次调用结束,
结束时同时杀死本次创造的这个i。这就是局部变量i的整个生命周期。下次再调用该函数func1时,又会重新创造一个i,经历整个程序运算,
最终在函数运行完退出时再次被杀死。
「静态局部变量(static)」
静态局部变量定义时前面加static关键字。
「总结:」
- 1、静态局部变量和普通局部变量不同。静态局部变量也是定义在函数内部的,静态局部变量定义时前面要加static关键字来标识,静态局部变量所在的函数在多调用多次时,只有第一次才经历变量定义和初始化,以后多次在调用时不再定义和初始化,而是维持之前上一次调用时执行后这个变量的值。本次接着来使用。
- 2、静态局部变量在第一次函数被调用时创造并初始化,但在函数退出时它不死亡,而是保持其值等待函数下一次被调用。下次调用时不再重新创造和初始化该变量,而是直接用上一次留下的值为基础来进行操作。
- 3、静态局部变量的这种特性,和全局变量非常类似。它们的相同点是都创造和初始化一次,以后调用时值保持上次的不变。不同点在于作用域不同
- 搜索公众号C语言中文社区,后台回复“资源”,免费获取200G编程资料。
「全局变量」 定义在函数外面的变量,就叫全局变量。
「普通全局变量」普通全局变量就是平时使用的,定义前不加任何修饰词。普通全局变量可以在各个文件中使 用,可以在项目内别的.c文件中被看到,所以要确保不能重名。
「静态全局变量」静态全局变量就是用来解决重名问题的。静态全局变量定义时在定义前加static关键字, 告诉编译器这个变量只在当前本文件内使用,在别的文件中绝对不会使用。这样就不用担心重名问题。所以静态的全局变量就用在我定义这个全局变量并不是为了给别的文件使用,本来就是给我这个文件自己使用的。
跨文件引用全局变量(extern) 就是说,你在一个程序的多个.c源文件中,可以在一个.c文件中定义全局变量g_a,并且可以在别的另一个.c文件中引用该变量g_a(引用前要声明)
函数和全局变量在C语言中可以跨文件引用,也就是说他们的连接范围是全局的,具有文件连接属性,总之意思就是全局变量和函数是可以跨文件看到的(直接影响就是,我在a.c和b.c中各自定义了一个函数func,名字相同但是内容不同,编译报错。)。
「局部变量和全局变量的对比:」
1、定义同时没有初始化,则局部变量的值是随机的,而全局变量的值是默认为0.
2、使用范围上:全局变量具有文件作用域,而局部变量只有代码块作用域。
3、生命周期上:全局变量是在程序开始运行之前的初始化阶段就诞生,到整个程序结束退出的时候才死亡;而局部变量在进入局部变量所在的代码块时诞生,在该代码块退出的时候死亡。
4、变量分配位置:全局变量分配在数据段上,而局部变量分配在栈上。
- static
#include <stdio.h> void func1(void); void func_static(void); void func_static2(void); void func_global(void); void func_register(void); int g_a = 1; int main(void) { //a = 4; // 编译报错,未定义 g_a = 5; // 可以,因为g_a是全局变量,所以到处都可以用 func1(); // i = 2 func1(); // i = 2 func1(); // i = 2 func_static(); // a = 2 func_static(); // a = 3 func_static(); // a = 4 func_static2(); // a = 4; func_static2(); // a = 7; func_static2(); // a = 10; func_global(); // g_a = 4; func_global(); // g_a = 7; func_global(); // g_a = 10; func_register(); func_register(); func_register(); // 因为i是定义在函数func中的局部变量,所以i的作用域为代码块作用域,所以i只在func1 // 函数内部有效,在func1外面是不能访问i的。所以这里i会无定义。 //i = 5; // error: ‘i’ undeclared (first use in this function) return 0; } void func1(void) { int i = 1; // 普通的局部变量,auto可以省略的 //auto int i = 0; // 自动局部变量,其实就是普通局部变量 i++; printf("i = %d.\n", i); } void func_static(void) { static int a = 1; // 静态的局部变量 a++; printf("a = %d.\n", a); } void func_static2(void) { static int a = 1; // 静态的局部变量 a += 3; printf("a = %d.\n", a); } void func_global(void) { g_a += 3; printf("g_a = %d.\n", g_a); } void func_register(void) { register int a = 1; // 静态的局部变量 a += 3; printf("a = %d.\n", a); }
- globle
#include <stdio.h> int g_i = 13; // 实验结论: // 首先,main函数是一个程序运行最开始执行的东西,所有的其他函数都只能在main函数中被 // 直接或者间接的调用才能被执行。main函数的执行其实就是整个程序的生命周期,main函数 // 一return返回,整个程序就结束了。 // 其次,全局变量的定义和初始化是在main函数运行之前发生的。 int main(void) { printf("g_i = %d.\n", g_i); return 0; }
#include <stdio.h> void func_in_a(void); extern int g_a; // 声明了一个int变量g_a //extern int g_b; void func_in_b(void) { printf("I am func in b.c.\n"); } int main(void) { printf("I am main in a.c.\n"); printf("I am main in a.c, g_a = %d.\n", g_a); printf("I am main in a.c, g_a = %d.\n", g_b); //func_in_b(); // 直接调用 func_in_a(); // 间接调用 return 0; }
#include <stdio.h> void func_in_b(void); int g_a = 12; int g_b = 111; void func_in_a(void) { g_a = 24; printf("I am in func_in_a of a.c, g_a = %d.\n", g_a); func_in_b(); } /* // 定义错误 // C语言中,定义函数都必须在外面,不能在一个函数里面定义别的函数 // 所以没有局部函数,只有全局函数。 void func1(void) { int a; void func2() { int b; } } */
最后两个分别为a.c b.c 文件目录为