/*
* 12_變數的儲存方式和生存期.c
* * created on: 2023年7月5日
* author: zhong
*/#include #include /**
* 從變數的作用域分: 全域性變數,區域性變數
* 從變數存在的時間(生命週期)分:靜態儲存方式。動態儲存方式
* * 靜態儲存方式:在程式執行期間由系統分配固定的儲存空間的方式
* 動態儲存方式:在程式執行期間依據須要進行動態的分配儲存空間的方式。
* * 資料存放的位置:靜態儲存區,動態儲存區
* * 1:全域性變數所有存放在靜態儲存區,當程式開始執行時給全域性變數分配儲存區。結束後釋放。在執行期間占領固定儲存單元,而不是動態地進行分配和釋放。
* 動態儲存區內分配儲存單元,在程式整個執行期間都不會釋放。
* * 在c語言中,每個變數和函式都有兩個屬性:資料型別(如:int,float)和資料的儲存類別(靜態,動態儲存)。
* * c語言中儲存類別包含4種:自己主動的(auto,預設) ,靜態的(static),暫存器的(register),外部的的(extern)
* 儲存類別不同,變數的作用域和生存期也不同。
* *-------------------------------------------
* 一:區域性變數的儲存類別:
* 1:自己主動變數(預設的):在函式中的區域性變數。假設不專門聲名為static的。都是動態地分配儲存空間的,資料儲存在動態儲存區中。
* 呼叫函式會給這些變數分配儲存空間。結束時自己主動釋放儲存空間 * 如:函式的形參。區域性變數。 * 自己主動變數用keywordauto作儲存類別的宣告。 * * int f(int a) * * 2:靜態區域性變數(static區域性變數):僅僅是在區域性變數int a;前面加個statickeyword static int a; 資料儲存在靜態儲存區中。 * 特點:當函式結束後。靜態區域性變數的儲存單元不會釋放。當下次再呼叫這個函式時,這個值就是上一次呼叫時結束時產生的值。 * * 靜態區域性與自己主動區域性變數比較: * 1:靜態區域性變數是在編譯時賦初值,僅僅賦初值一次,在程式執行時它已經有初值。以後每次呼叫函式時不再又一次賦初值而僅僅是保留上次函式呼叫結束時的值 * 2:動態區域性變數賦初值,不是在編譯時進行的,而是在函式呼叫時進行的,每呼叫一次,函式又一次比例一次初值。 * 3:定義靜態區域性變數時不賦初值,系統會自己主動賦初值0,或空字元『\0』。對於自己主動變數來說,假設定義時不賦初值,系統會隨機分配乙個不確定的儲存單元。所以值不確定。 * 4:靜態區域性變數在函式呼叫結束後仍然存在,可是其他函式不能引用。
* * 靜態區域性變數使用場景:須要保留函式上一次呼叫結束時的值 * 如:輸出1到5的階乘值 * int fac(int n) * * int main() * * 3:暫存器變數(register): 將變數儲存到cpu的暫存器中。 * 說明: * 一般變數(靜態,動態儲存方式)的值都 存放在記憶體中的,當程式用到上"控制器"發生指令將記憶體中這個變數的值送到"運算器"中進行運算, * 運算後。再從運算器將資料送到記憶體中存放。 * * 為什麼要操作暫存器變數: * 比如在函式中執行1000次迴圈,每次迴圈中都 要引用區域性變數(對某個變數頻繁訪問),假設每次都由「控制器」傳送指令從記憶體中「訪問」變數值,會花費不少時間。 * 將區域性變數的值放在cpu的暫存器中,須要用的時間胻從暫存器取出參加運算,不必從記憶體中去訪問。
速度超快的說。
* * 宣告暫存器變數:register int f; * * 因為計算機的發展,優化的編譯系統能夠自己主動識別使用頻繁的變數,從而自己主動將這些變數放在暫存器中。所以實際程式設計中,程式猿不須要過多指定這樣的 變數。 * *------------------------------- *二:全域性變數的儲存類別: * * 全域性變數都是存放在靜態儲存區中的,因此它們的生存期是固定的。
存在於程式執行的整個過程。 * 儘管生命週期是固定的,可是全域性變數的作用域是不確定的,不同的儲存類別作用域不同。 * * 普通情況下假設全域性變數(外部變數)不在檔案的開頭定義(整個原始檔)。其作用域在定義處開始,到本程式檔案的未尾。
定義處之前的函式不能使用。
* * 假設不在檔案開關定義,又想定義處之前的函式能使用這個全域性變數,就要對全域性變數進行作用域擴充套件 * 1:在乙個檔案內擴充套件外部變數的作用域 (extern) * 在函式引用這個在函式之後定義的外部變數時,使keywordextern對這個變數作「外部變數宣告」:表示將外部變數的作用域擴充套件到此位置 * 如: * int fun() * int a=20; //在函式之後聲名的外部變數 * * 2:將外部變數的作用域擴充套件到其他檔案 * 將其他原始檔裡的全域性變數擴充套件到本原始檔加也是加個externkeyword就可以。 * * 如: * file 1.c: * int a=20; * int max() * * file2.c: * int funk() * extern a;//將file 1.c 中定義的全域性變數a擴充套件到這個檔案,當作這檔案的外部變數。在此之後的函式可用。之前的函式不可用 * int funk() * * (靜態外部變數) * 3:將外部變數的作用域限制在本檔案裡(不讓其他檔案訪問):僅僅須要在定義外部變數時加入statickeyword就可以。 * 同一時候。加了statickeyword的全域性變數的名稱,其他檔案也能夠使用這個檔案,不會發生衝突 * * static int a=20; //這樣其他檔案就不能訪問這個外部變數了。 * int main() * * *小結: * 一: static宣告乙個變數的作用: * 1:對區域性變數用static宣告。把它分配在靜態儲存區。這變數在整個程式執行期間不釋放 * 2:對全域性變數用static宣告,則這變數的作用域僅僅限於 本檔案模組。其他檔案不可引用 * *二: 宣告儲存型別的作用 * 對於區域性變數來說,宣告儲存型別的作用是指定變數儲存的區域(靜態儲存。動態儲存,暫存器),以及由此產生的生存期的問題 * 對於全域性變數,因為在編譯時分配記憶體的。都 存放在靜態儲存區中,宣告儲存型別的作用是變數作用域的擴充套件問題,無它。
* * */ //區域性靜態。動態變數 void local_static_auto(int a) void test_local_static_auto() /** * output: 第1次執行:b=1,c=3,a+b+c=5 第2次執行:b=1,c=4,a+b+c=7 第3次執行:b=1,c=5,a+b+c=9 第4次執行:b=1,c=6,a+b+c=11 */ } //求n的階乘 int fac(int n) void test_fac() extern a;//將11_全域性變數.c中定義的全域性變數a擴充套件到這個檔案,在此之後的函式可用。之前的函式不可用 //使用此函式之後 定義的外部變數 void use_extern_variable() int a=20; int main12()
C語言學習筆記 變數儲存
怎樣確定常量的型別呢?從常量的表示形式既可以判定其型別,舉例來說 只要看到由單撇號括起來的單個字元或轉義字元就是字元常量。也可以在常量的末尾加專用字元,強制指定常量的型別。從變數的作用域 即從空間 的角度來觀察,變數可以分為全域性變數和區域性變數 變數的儲存有兩種不同的方式 靜態儲存方式和動態儲存方...
C語言學習筆記12
回顧 1.位置指標 作業 1.id判斷 2.根據id顯示人員資訊 預處理指令是c語言支援的一種特殊指令 它們以 做開頭,不以 做結尾 預處理指令在編譯的第乙個階段被處理 所有預處理指令都是把程式變成另外的樣子 gcc可以使用 e選項單獨處理所有預處理指令 define是乙個預處理指令 這個預處理指令...
C語言學習之變數儲存
c語言中對變數的說明包括兩方面的內容 變數型別以及變數的儲存型別。變數型別如 int 整形 char 字元型 是用來說明變數所占用的記憶體空間的大小。變數儲存型別用來說明變數的作用範圍。c語言的變數儲存類有 自動類 暫存器類 靜態類和外部類。關鍵字auto加在變數名及其型別前,用來說明它是自動變數。...