【C语言】作用域和生命周期
条评论作用域和生命周期
变量的作用域
变量的作用域指变量能在代码什么地方可以被访问到。
变量类型 | 作用域 |
---|---|
全局变量 | 所有程序中的代码都能访问 |
静态全局变量 | 在同一个源文件中可以访问,不同源文件不可访问,也不能用extern来导入 |
局部变量 | 只能在函数内部访问 |
静态局部变量 | 只能函数内部访问 |
寄存器变量 | 只能在函数内部访问 |
注:如果全局变量在一个源文件中定义,在另一个源文件中访问,需要用extern关键字导入。多线程访问全局变量注意安全问题。
变量的生命周期
变量的生命周期是指变量在程序运行期间的有效时间
变量类型 | 生命周期 |
---|---|
全局变量 | 整个程序运行期间有效 |
静态全局变量 | 整个程序运行期间有效 |
局部变量 | 函数范围内或代码块范围内有效 |
静态局部变量 | 整个程序运行期间有效 |
寄存器变量 | 函数范围内或代码块范围内有效 |
static和extern
static修饰全局变量
- 表示这个全局变量只能在当前文件使用,不能在其他文件使用
- 在不同文件可以声明同名变量
- 修饰函数表示这是一个内部函数
static修饰局部变量
- 延长局部变量声明周期,从程序启动到程序结束,但是没有修改变量的作用域
- 定义变量的代码在整个程序运行期间就只执行一次
extern修饰全局变量
- 表示这个全局变量可以在其他文件使用
- 在不同文件不能声明同名变量
- 修饰函数表示这是一个外部函数
extern 不能修饰局部变量
注:全局变量、静态全局变量、静态局部变量的声明周期相同,都是直到程序结束才被释放
实例:
分析下列程序中每个变量的存储位置,作用域,与生命周期
int a = 0; char *p1; static int x = 10; void func(void) { int b; char s[] = "123"; char *p2; char *p3 = "hello,world"; static int c = 0; register int i = 0; p1 = (char *)malloc(128); p2 = (char *)malloc(256); free(p1); free(p2); } int main(void) { func(); printf("hello,world\n"); return 0; }
解答:
int a = 0; //全局变量,初始化
char *p1; //全局变量,
static int x = 10; //全局变量,初始化
void func(void)
{
int b; //局部变量
char s[] = "123"; //s为局部变量,"123"为常量,初始化
char *p2; //局部变量
char *p3 = "hello,world"; //p3为局部变量,"hello,world"为常量,初始化
static int c = 0; //局部静态变量,初始化
register int i = 0; //寄存器变量,初始化
p1 = (char *)malloc(128); //p1指向堆上的内存,直到free
p2 = (char *)malloc(256); //p2指向堆上的内存,直到free
free(p1);
free(p2);
}
变量或常量 | 存储空间 | 作用域 | 生命周期 |
---|---|---|---|
a | 静态区(data.) | 整个工程,extern int a; | 整个程序结束 |
p1 | 静态区(bbs.),指向的内存在堆上 | 整个工程,extern char *p1; | 整个程序结束,指向的内存需要free释放。 |
x | 静态区(data.) | 当前文件 | 整个程序结束 |
b | 栈 | main函数 | main函数结束 |
s | 栈 | main函数 | main函数结束 |
p2 | 栈,指向的内存在堆上 | main函数 | main函数结束,指向的内存需要free释放 |
p3 | 栈 | main函数 | main函数结束 |
c(参考demo/static) | 静态区(data.) | main函数 | 整个程序结束 |
i | 可能是寄存器或栈 | main函数 | main函数结束 |
“hello,world”,”123” | 静态区(data.) | 整个程序结束 |
参考: