C/C++(變量作用域)


變量的作用域

凡是在{}以內的變量為局部變量,也包括形式參數。

凡是{}外的變量為全局變量

作用域:

{}以內的作用域為局部作用域,主要包含的事變量

{}以外的作用域為全局作用域,包含的是變量和函數

同一作用域內,不可以用重命名的變量
局部變量的作用域,起始於定義處,直到所在的大括號處結束。
全局變量的作用域,起始與定義處,知道本文件結束。

作用域疊加:

全局變量同局部變量的作用域疊加,在不同的作用域中,可以有重名的標識符,局部變量會覆蓋全局變量的作用域。

#include<stdio.h>
int a = 100;
int main() {
    int a = 10;
    printf("a = %d\n",a);//10
    return 0;
}

更小的作用域{}只能再次划分局部作用域

#include<stdio.h>
int a = 100;
int main() {
    int a = 10;
    {//只能用於局部
        int a = 1;
        printf("a = %d\n",a);//1
    }
    return 0;
}

全局變量命名污染

函數是全據變量,要防止命名污染,全局變量的使用更要避免命名重名。盡量少用全局變量。

局部變量的生命周期

函數的生命周期起始與調用,結束與調用結束。函數體內的局部變量相同。
main函數比較特殊它開始於程序的開始,結束語程序的結束

全局變量的生命周期

全局變量的生命周期起始與main函數的調用,結束於main函數的結束,等價於程序的生命周期。
main函數中的變量生命周期與全局變量相同,但他們的作用域不同

修飾符

auto類型

只能用於修飾局部變量,表示該變量存儲在棧上stack
特點:隨用隨開,用完消失
默認的局部變量,就是auto類型,所以通常將其省略。C++中auto是自動變量。
eg:

auto int a = 23;

register

只能修飾局部變量,將內存中的變量升級到cpu寄存器中存儲,這樣訪問速度會很快。存儲cpu的變量,速度快但數量有限,通常用來優化。用於頻繁使用的變量。一般不用。

extern(通關文牒)

修飾全局變量,
c語言是訂單文件編譯,然后再將編譯的.o文件同庫儀器連接成可執行文件,所以跨文件需要聲明。
區分聲明預定義:extern可以省略,不建議省略
eg:

int a;//聲明
int a = 120;//定義

全局變量聲明未定義時是0,局部變量是隨機數。vs中是不行的。局部變量必須定義。

static(隔離出境)

static修飾局部變量,默認初始化0

#include<stdio.h>
void func();
int main() {
    for(int i = 0;i < 10;i++) {
        func();
    }
    return 0;
}
void func() {
    int a = 1;//默認auto修飾,存儲在棧中即用即消失,所以每次用完消失++操作無效。
    printf("a = %d\t",a++);
    static int b = 1;//修飾的局部變量存放在data塊中,生命周期等同與進程。 
    //無論以后調用多少次函數,它的初始化一次
    printf("b = %d\n",b++);
    printf("++++++++++++++++++");
}
/*
a = 1   b = 1
++++++++++++++++++
a = 1   b = 2
++++++++++++++++++
a = 1   b = 3
++++++++++++++++++
a = 1   b = 4
++++++++++++++++++
a = 1   b = 5
++++++++++++++++++
a = 1   b = 6
++++++++++++++++++
a = 1   b = 7
++++++++++++++++++
a = 1   b = 8
++++++++++++++++++
a = 1   b = 9
++++++++++++++++++
a = 1   b = 10
++++++++++++++++++
*/

static修飾的變量存儲在data區域中,生命周期等同於進程,和函數的作用域無關

#include<stdio.h>
void print(int num,int age,char sex,float score);
int main() {
    print(1001,32,'x',99);
    print(1001,32,'x',99);
    print(1001,32,'x',99);
    print(1001,32,'x',99);
    print(1001,32,'x',99);
    print(1001,32,'x',99);
    print(1001,32,'x',99);
    print(1001,32,'x',99);
    print(1001,32,'x',99);
    print(1001,32,'x',99);
}
void print(int num,int age,char sex,float score) {
    static int flag = 1;
    if(flag == 1) {
        printf("num\tage\tsex\tscore\tcount\n");
        flag = 0;
    }
    static int count = 0;
    printf("%d\t%d\t%c\t%.2f\t%d\n",num,age,sex,score,++count);
}
//控制執行次數,記錄打印某函數的調用次數多用於避免多次加載的資源

全局變量會帶來命名污染,好處(全局可用,避免傳參),用static解決。一個全局變量擁有外延性,可以被其他的文件所用,extern。static修飾全局變量以后,外延性消失,變成本文件內部的全局變量
main.c

static int a = 100;

bb.c

static int a = 200;

這樣兩者文件中的a都限制在本文件中
main.c

extern a;
printf("a = %d\n",a);//報錯,編譯不通過

bb.c

static int a = 200;//限制了外延性,成了局部變量

同樣適用於函數
全局變量被static修飾后,存放的位置沒有變,改變的了作用域,外延性被限制。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM