普通变量,static变量虽然都是变量,但是他们有很大的区别,下面从存储区域,初始化值,作用域,生命周期来辨析他们(在同一个文件下)。
普通局部变量
//测试使用,无意义
void add(int a,int b)
{
int tmp[100];
int sum;
printf("sum: %d\n",sum);
}
int main()
{
add(1,2);
int tmp;
printf("tmp的初始化值: %d\n",tmp);
add(3,4);
//printf("sum = %d\n",sum); error
return 0;
}
结果
sum: 6356940
tmp的初始化值: 53
sum: 1944111648
通过结果可以得到结论
生命周期:只有在对应的大括号{}内,函数运行结束普通局部变量自动释放回收。可以通过调用两次函数,但是结果不一样说明两次变量不是同一个东西,所以生命周期只有在所在的大括号{}运行期间。
作用域:由最后打印局部变量失败说明普通局部变量在它所在的{}内;
初始化值:由结果可知,初始化值为随机数
存储区域:栈区
普通全局变量
int num;
void test()
{
//使用全局变量
num = 10;
}
int main()
{
printf("全局变量初始化值:%d\n",num);
test();
printf("%d\n",num);
return 0;
}
结果
全局变量初始化值:0
10
生命周期:在程序结束的时候,系统自动回收
作用域:本文件下都可以调用。如果想要在其他文件也可以使用,文末有说明
初始化值:由结果得知,初始化值为0
存储区域:全局数据区
静态局部变量
void test2()
{
static int num;
printf("&num: %u\n",&num);
}
int main()
{
//tmp = 0; error
test2();
static int tmp;
printf("静态局部变量初始值:%d\n",tmp);
test2();
return 0;
}
结果
&num: 4214796
静态局部变量初始值:0
&num: 4214796
生命周期:可以看到两次调用地址不变,所以在程序结束时才结束生命周期。
作用域:赋值tmp失败,所以作用域为在大括号{}内;
初始化值:由结果得知,为0
存储区域:全局数据区
静态去全局变量
static int num;
void test()
{
//使用静态全局变量
num = 10;
printf("func:num = %d\n",num);
}
int main()
{
printf("静态全局变量初始值:%d\n",num);
test();
return 0;
}
结果
静态全局变量初始值:0
func:num = 10
生命周期:在程序运行结束时自动释放内存
作用域:本文件下
初始化值:有结果得知是0
存储区域:全局数据区
不同文件下
tmp.h
int c;
static int num;
test.h
#include"tmp.h"
extern int tmp;
//extern static int num; error
main.c
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
int main()
{
return 0;
}
如果想要在其他文件使用本文件的普通全局变量,可以在其他文件使用extren关键字,注意格式为
extren 数据类型 变量名; 注意不能赋值,因为这个只是声明。且要注意静态全局变量的作用域为文件,不可以跨文件使用。这个特性可以用做保护数据。
静态变量特性
int test()
{
static int sta = 0;
sta++;
return sta;
}
int main()
{
int sta = test();
//静态初始化值不能用变量
//static int tmp = sta; error
printf("%d\n",sta);
sta = test();
printf("%d\n",sta);
return 0;
}
结果
1
2
静态变量初始化值不可以为变量,且静态变量只初始化一次,看上文的sta每次初始化为0,结果应该输出两个1,但是结果为一个1一个2。验证上面是正确的。
两个作用域不同的同名变量
int num;
int main()
{
printf("&num : %u\n",&num);
printf("%d\n",num);
int num;
printf("&num : %u\n",&num);
printf("%d\n",num);
return 0;
}
结果
&num : 4214868
0
&num : 6356748
53
文中两个同名的变量,但作用域不同,编译器会调用那个的值呢?从结果得知,编译器会选择就近原则,调用离它最近的那个变量,并不是后面的覆盖前面的值,它们是不同的两个变量。静态变量也是这样。注意,并不允许两个作用域相同的同名函数,这样编译器报错。
总结
除开普通局部变量,其他三个的初始化值均为0。这是因为普通局部变量存储在栈区,储存的具体位置随运行的程序变化,就没有确定的值,其他三个在程序运行时位置不变,就可以有一个确切的初始化值。除开普通局部变量的生命周期在程序运行离开所在的作用域就结束,其他的都是程序运行结束才结束。
微信号
网友评论