變量的作用域
凡是在{}以內的變量為局部變量,也包括形式參數。
凡是{}外的變量為全局變量
作用域:
{}以內的作用域為局部作用域,主要包含的事變量
{}以外的作用域為全局作用域,包含的是變量和函數
同一作用域內,不可以用重命名的變量
局部變量的作用域,起始於定義處,直到所在的大括號處結束。
全局變量的作用域,起始與定義處,知道本文件結束。
作用域疊加:
全局變量同局部變量的作用域疊加,在不同的作用域中,可以有重名的標識符,局部變量會覆蓋全局變量的作用域。
#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修飾后,存放的位置沒有變,改變的了作用域,外延性被限制。