概念
作用域:块作用域,函数作用域,文件作用域
链接:
外部链接:多文件中使用
内部链接:只在一个翻译单元(文件)内使用
无链接 :具有块,
函数,函数原型作用域的变量
存储期:静态作用域和非静态作用域
自动变量:
1.自动储存期,
2.块作用域,
3.无链接
4.auto关键字(显式)
void doSome(){
int d = 3;
};
int main(int argc, const char * argv[]) {
int a = 0;
for (int i = 0 ; i < 10 ; i++) {
int b = 1;
}
{
auto int c = 2;
}
return 0;
}
// a,b,c,d都是自动变量
静态内部链接:
1.static显式声明,
2.静态储存期,
3.内部链接,
4.文件作用域.
static int statc_a = 2; //只能在main.c中访问
int main(int argc, const char * argv[]) {
printf("%d",statc_a);
return 0;
}
静态外部链接:
1.静态储存期,
2.外部链接,
3.文件作用域.
/* sub.h */
#include "sub.h"
int sub_a = 2;
/* main.c */
#include
int main(int argc, const char * argv[]) {
extern int sub_a;
printf("sub_a : %d\n",sub_a);
return 0;
}
/*
sub_a : 2
Program ended with exit code: 0
*/
//编译器会找到sub_a这个变量的。
这样使用静态外部链接的存储类别变量是有问题的,如果全局的变量名有重复的就会报错,比如在main.c中又定义了一个相同名字的sub_a ,编译无法通过,显示链接错误。
#include
int sub_a = 2;
int main(int argc, const char * argv[]) {
extern int sub_a;
printf("sub_a : %d\n",sub_a);
return 0;
}
//clang: error: linker command failed with exit code 1 (use -v to see invocation)
一个比较规范办法是使用头文件,在头文件中申明需要外部使用的变量extern
/* .h */
#include
extern int sub_a;
#endif /* sub_h */
/* main.c */
#include
#include "sub.h"
int main(int argc, const char * argv[]) {
printf("sub_a : %d\n",sub_a);
int sub_a = 3;
printf("sub_a : %d\n",sub_a);
return 0;
}
//但是依然并不能完全解决我们上面产生的问题。
静态无链接
1.静态储存期,
2.无连接,
3.块作用域
PS:静态变量只能初始化一次,并且定义时候必须赋值。
static:在声明局部变量时,使用关键字 static 将局部变量指定为“静态局部变量”,这样在函数调用结束后不消失而保留原值,即占用的存储单元不释放,在下一次函数调用时,该变量已有值就是上次函数调用结束时的值。
static的作用?
1.在块作用域内将变量的存储期变成静态
void add(){
static int static_a = 1;
int a = 1;
printf("static_a:%d---a:%d\n",static_a,a);
static_a++;
a++;
}
//调用三次
static_a:1---a:1
static_a:2---a:1
static_a:3---a:1
2,将文件作用域内的变量从外部链接变成内部链接
/* sub.c */
#include "sub.h"
static int static_sub_a = 3;
int sub_a = 2;
/* main.c */
int main(int argc, const char * argv[]) {
extern int sub_a;
extern int static_sub_a;
printf("%d\n",static_sub_a);
printf("%d\n",sub_a);
return 0;
}
//报错 "_static_sub_a", referenced from: 外部无法访问static_sub_a