儲存類別和記憶體管理

weixin_34249678發表於2018-01-31

概念

作用域:塊作用域,函式作用域,檔案作用域

連結:

外部連結:多檔案中使用
內部連結:只在一個翻譯單元(檔案)內使用
無連結 :具有塊,

函式,函式原型作用域的變數

儲存期:靜態作用域和非靜態作用域

1647711-4caf642706b2c0ff.png
螢幕快照 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 <stdio.h>

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 <stdio.h>

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 <stdio.h>
extern int sub_a;
#endif /* sub_h */

/* main.c */
#include <stdio.h>
#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


相關文章