按變數的儲存方式分——從變數的存在時間(生存期)角度
動態儲存
二、變數的作用域、可見性、存在性、生存期
三、變數的宣告和定義
四、內部函式和外部函式
(一) 區域性變數:
含義:在乙個函式內部定義的變數或者函式的形參,統稱為區域性變數。
在乙個函式內部復合語句裡定義的變數,只在這個復合語句內有效。這種復合語句也叫分程式或者程式塊。
區域性變數的使用範圍:只能在本函式內部使用。不同函式可以有相同的變數名,
(二) 全域性變數:
含義:在所有函式外部定義的變數。
全域性變數的使用範圍為從定義位置開始到本原始檔結束。
不成文習慣:將全域性變數的名字首字母大寫。
區域性變數和全域性變數的命名衝突的問題:
在乙個函式內部如果定義的區域性變數的名字和全域性變數名一樣時,區域性變數會遮蔽掉全域性變數。
變數的儲存方式分為靜態儲存方式和動態儲存方式
使用者區內容程式區
靜態儲存區
全域性變數
動態儲存區
函式形參、自動變數、現場保護和返回位址
靜態儲存
(一) 靜態區域性變數 static
有時候需要函式呼叫結束後不讓系統釋放空間,還保留運算後的結果,就需要定義乙個靜態區域性變數。
靜態區域性變數在靜態儲存區內分配儲存單元,在整個程式執行期間內都不釋放,而動態變數在函式呼叫結束後就釋放。
對於靜態區域性變數時在編譯時賦初值的,只賦初值一次。以後每次呼叫函式時不再對變數賦初值,而是保留上次呼叫結束的值。
int
sum(
int m)
int main (
void
)//輸出
第一次加1:101
第二次加1:102
長期占用記憶體不釋放,呼叫函式多次時會搞不清楚當前靜態變數的值到底是什麼,降低了程式的可讀性。
(二) 靜態外部變數
限制某些外部變數只能在本檔案中使用,而不能被其他檔案所引用。
加上 static 只能用於本檔案的外部變數為靜態外部變數。 static int a;
這樣即使 另乙個檔案寫了 extern a;也不能使用。
注意:
對於區域性變數來說,宣告儲存型別的作用是指定變數的儲存區域(靜態儲存區或者動態儲存區)
對於全域性變數,都是在編譯時分配記憶體的,宣告儲存型別的作用是為了作用域擴充套件問題。
對於區域性變數用 static 宣告,把它分配在靜態儲存區,該變數在整個程式執行期間不釋放,其所分配的空間始終都在。
對於全域性變數使用 static 宣告,則該變數的作用域只限於本檔案。
(三) 外部變數(即非靜態的外部變數)
外部變數是在函式外部定義的全域性變數
一般來說,外部變數的作用域為定義處到本檔案結束。可以對其定義域進行擴充套件。
擴充套件外部變數的定義域
① 在乙個檔案內擴充套件外部變數的作用域
因為作用範圍是從定義處開始的,怎麼樣才能在定義處上邊也可以用該外部變數呢?
在引用前加上 extern 表示把外部變數的作用域擴充套件到當前,這叫做 外部變數宣告
# include
intmain
(void
)int a,b,c;
//輸出:100 100 100
② 在外部變數的作用域擴充套件到其他檔案乙個c程式有很多原始檔構成,如果在不同的原始檔中定義了名字相同的外部變數,在連線時會報錯「重複定義」
為避免這種情況,可採用乙個原始檔定義外部變數,另乙個原始檔將這個外部變數的作用域擴充套件到本檔案。
還是採用關鍵字 extern ,在需要擴充套件的檔案開頭加上 extern 外部變數名
注意:系統如何識別 extern 是擴充套件本檔案的外部變數作用域還是擴充套件其他原始檔的外部變數作用域?
採用就近原則,如果本檔案已經定義了要擴充套件的變數,就預設為擴充套件本檔案的,沒有則去其他原始檔尋找。
動態儲存
(一) 自動變數 auto —— 動態區域性變數
auto 只能用來修飾區域性變數。
函式中的區域性變數,如果不專門宣告為static(靜態)儲存類別,都是動態的分配儲存空間的,資料儲存在動態儲存區中。
函式形參和函式中定義的變數一般都屬於自動變數,這些變數系統會在呼叫函式時動態的分配儲存空間,而函式呼叫結束後就會自動釋放分配的空間。
int main (
void
)//預設情況下,這裡的 a 是乙個自動變數,所以auto 可以不加
(二) 暫存器變數 register
register 只能用來修飾區域性變數,但它不一定成為乙個暫存器變數,能不能成為乙個暫存器變數需要根據編譯系統來決定。
一些編譯系統會把反覆使用的變數放到暫存器裡。
如下圖,暫存器在cpu,cpu運算速度極快,變數放到暫存器,就可以在運算時免從記憶體取出變數在運算器運算,加快執行效率。
乙個變數在某個檔案或者函式範圍內是有效的,就稱該範圍為該變數的作用域。
在作用域內可引用該變數,九城該變數在此作用域內可見。
如果某一時刻該變數占用記憶體,則該變數在這一時刻是存在的,這一時刻屬於該變數的生存期
[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-3t8vwgjy-1595172015738)(生存期.jpg)]
廣義上的宣告:包括定義性宣告和引用性宣告,其中定義性宣告需要建立儲存空間,例如:int a; 為了簡便,通常叫做「定義」; 而引用性宣告不需要建立儲存空間,例如: extern a; 通常叫「宣告」。
狹義的「宣告」:不需要建立儲存空間
定義:需要建立儲存空間
函式的本質就是「全域性」的,構建乙個函式的目的就是為了讓本檔案或者其他檔案呼叫。
可以通過加 static 限制某一函式只能在本檔案被呼叫,這樣的函式叫做內部函式(靜態函式)。
static
intnamea
(形參表列)
函式定義時,在型別名的前邊 加上extern則為外部函式,可以被其他檔案所呼叫,在型別名前面什麼都沒加,預設是外部函式。
1. 第一種
extern
intnameb
(形參表列)
1. 第二種
intnamec
(形參表列)
7 1 move method 搬移函式
在該函式最常引用的類中建立乙個有著類似行為的新函式。將舊函式變成乙個單純的委託函式,或是將舊函式完全移除。動機 如果乙個類有太多行為,或如果乙個類與另乙個類有太多合作而形成高度耦合,我就會搬移函式。使用另乙個物件的次數比使用自己所駐物件的次數還多。觀察呼叫它的那一端,它呼叫的那一端,以及繼承體系中它...
7 1 函式式資料結構
7.1 函式式資料結構 用函式程式設計,程式處理的資料總是儲存在資料結構中。資料結構和物件之間的區別在於,資料結構公開了表示資料 從名字就可以知道 的結構 知道了資料的結構便於寫處理的 但要到第九章才討論,f 還提供了一種封裝結構的方法,如同物件導向程式設計,當我們想從庫中匯出 f 資料結構,或者用...
71 函式的異常規格說明
注 部落格中內容主要來自 狄泰軟體學院 部落格僅當私人筆記使用。測試環境 ubuntu 10.10 gcc版本 9.2.0 一 函式的異常規格說明 1 問題 如何判斷乙個函式是否會丟擲異常,以及丟擲哪些異常?1 給函式宣告丟擲異常 2 檢視文件 2 c 提供語法用於宣告函式所丟擲的異常 3 異常宣告...