存储类别和内存管理

概念

作用域:块作用域,函数作用域,文件作用域

链接:

外部链接:多文件中使用
内部链接:只在一个翻译单元(文件)内使用
无链接 :具有块,

函数,函数原型作用域的变量

存储期:静态作用域和非静态作用域

屏幕快照 2018-01-31 下午3.59.43.png

自动变量:

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


你可能感兴趣的:(存储类别和内存管理)