C語言入門-全局變量

1、全局變量

  1. 定義在函數外面的變量是全局變量
  2. 全局變量具備全局的生存期和做用域
  3. 它們與任何函數無關,在任何函數內部均可以使用它們
#include <stdio.h>

int f(void);


// 全局變量
int gALL = 12;


int main(int argc, char const *argv[])
{
    printf("in %s gALL=%d\n", __func__,gALL);
    f();

    printf("agn in %s gALL=%d\n", __func__,gALL);

    return 0;
}

int f(void)
{
    printf("in %s gALL=%d\n", __func__,gALL);
    gALL += 8;
    printf("agn in %s gALL=%d\n", __func__,gALL);
    return gALL;
}


// in main gALL=12
// in f gALL=12
// agn in f gALL=20
// agn in main gALL=20

2、全局變量初始化

  1. 沒有作初始化的全局變量會獲得0值
  2. 指針會獲得NULL值
  3. 只能用編譯時刻已知的值來初始化全局變量
  4. 它們的初始化發生在main函數以前

3、被隱藏的全局變量

若是函數內部存在與全局變量同名的變量,則全局變量被隱藏安全

#include <stdio.h>

int f(void);


// 全局變量
int gALL = 12;


int main(int argc, char const *argv[])
{
    printf("in %s gALL=%d\n", __func__,gALL);
    f();

    printf("agn in %s gALL=%d\n", __func__,gALL);

    return 0;
}

int f(void)
{
    // 這裏定義一個名字相同的變量,那麼全局的就被隱藏了
    int gALL = 1;
    printf("in %s gALL=%d\n", __func__,gALL);
    gALL += 8;
    printf("agn in %s gALL=%d\n", __func__,gALL);
    return gALL;
}
// in main gALL=12
// in f gALL=1
// agn in f gALL=9
// agn in main gALL=12

4、靜態本地變量

  1. 在本地變量定義時加上static修飾符就成爲靜態本地變量
  2. 當函數離開的時候,靜態本地變量會繼續存在並保持其值
  3. 靜態本地變量的初始化只會在第一次進入這個函數時作,之後進入函數時會保持上次離開的值
#include <stdio.h>

int f(void);

int main(int argc, char const *argv[])
{
    f();
    f();

    return 0;
}

int f(void)
{
    static int all = 1;
    printf("in %s all=%d\n", __func__,all);
    all += 9;
    printf("agn in %s all=%d\n", __func__,all);
    return all;
}
// in f all=1
// agn in f all=10
// in f all=10
// agn in f all=19

注意事項

  1. 靜態本地變量其實是特殊的全局變量
  2. 它們位於相同的內存區域
  3. 靜態本地變量具備全局的生存期,函數內的局部做用域
  4. static在這裏的意思就是局部做用域(本地能夠訪問)

5、後記:返回指針的函數

  1. 返回本地變量的地址是危險的
  2. 返回全局變量或靜態本地變量的地址是安全的
  3. 返回在函數內malloc的內存是安全的,可是容易形成問題
  4. 最好的作法是返回傳入的指針

下面的寫法就是很危險的函數

#include <stdio.h>

int* f(void);
void g(void);

int main(int argc, char const *argv[])
{
    int *p = f();
    printf("*p = %d\n", *p);
    g();
    printf("*p = %d\n", *p);

    return 0;
}

int* f(void)
{
    int i = 12;

    // 返回本地變量的地址是危險的
    return &i;
}

void g(void)
{
    int k = 24;
    printf("k = %d\n", k);
}

// *p = 12
// k = 24
// *p = 24

tips

  1. 不要使用全局變量來在函數間傳遞參數和結果
  2. 儘可能避免使用全局變量
  3. 使用全局變量和靜態本地變量的函數是線程不安全的
相關文章
相關標籤/搜索