C語言精華記錄 壹(變數的作用域及儲存方式)

2021-07-02 16:27:26 字數 4229 閱讀 5559

分類: c 系列

2012-10-13 20:20

1199人閱讀收藏 

舉報儲存c語言

程式設計彙編

悟道系列之——c語言

這是我的第一篇博文。對我來說csdn並不陌生,但一直以來我都是乙個默默的潛水者,可是今天我要冒泡了。特意選了十月一日來重新註冊賬號,我想賦予這個日子以新的意義。在進入正題之前,我想有必要簡單的向大家介紹一下自己。

本人80後後,剛畢業於一所普通師範類學校的化學專業。本人形象猥瑣,身無長物,自覺難以為祖國的教育事業服務,遂混跡於程式猿們的隊伍之中。

本科四年,前半段渾渾噩噩,後半段幡然悔悟。而正式決定踏入程式設計,則已是2023年的愚人節了。(我有意選擇這個日子作為紀念)屈指算來今天竟剛滿一年半,這真是乙個讓人驚喜的巧合。

寫了這麼多廢話,無非是想讓大家明白:這不是乙個大牛的部落格。如果您想從中尋找一些金玉良言,那麼讓您失望了。這裡只是乙個技術菜鳥對他一路以來在程式設計中思考和領悟的記錄,分享給那些在學習中有些困惑的初學者。

從c講起吧,以前學習時做了很多筆記,現在把它們篩選整理成電子版的形式分享出來,也方便自己以後查閱。

本系列文章中的讀者應該是 c語言語法的入門者。

因為本文不是零基礎掃盲貼。要熟悉c的語法 隨便一本教材反覆研讀實踐即可。

此文大多是個人的讀書筆記、程式設計感悟及曾經遇到的問題,至於一些技巧和**風格網上資源不在少數,故本文很少提及。

提綱::變數的作用域及儲存方式

:幾個關鍵字、幾個運算子、隱式轉換/溢位、表示式求值的順序、左值和右值

:陣列與指標(一)

:陣列與指標(二)

:字串、函式、動態記憶體分配

:結構、聯合、位段、位級操作

:檔案、輸入輸出函式

:預處理、程式除錯、程式設計風格

:常用庫函式

開場白:

【c語言結合了組合語言的所有威力和組合語言的所有易用性】

變數的作用域:

1, 區域性變數

區域性變數是在函式內定義的變數,其作用域僅限於函式內,在函式內才引用,即可以對它賦值或取值。在作用域外,使用它們是非法的。

2, 全域性變數

全域性變數是定義在函式之外的變數,它的作用域是從定義處開始,到所在檔案的結束。即從定義之處起,它可以在文字的所有函式中使用。

【全域性變數的命名最好取有特殊含義的識別符號(例如在變數名前加q_)。防止不經意間改變了它的值。***全域性變數違反了最低特權原則,而且是糟糕的軟體工程方法***】

3, 外部變數

全域性變數的作用域是在所在檔案的整個檔案,而乙個檔案中的全域性變數的作用域還可以擴充套件到其它檔案。某個檔案中引用另乙個檔案中的全域性變數,只要用extern宣告,說明這個變數是在其它檔案中已經定義過的外部變數。那麼,該檔案中不會為外部變數分配記憶體。

幾點說明:

(1)關於外部變數宣告的定義和引用

c所存在的乙個眾所周知的缺陷是很難區分外部變數宣告的定義和引用。(**於《c語言參考手冊》)

標準c:在頂層宣告中,如果出現了初始化值,它就被認為是個定義性宣告。其它的宣告則是引用性宣告。在c程式的所有檔案中,同乙個變數的定義性宣告只能出現一次。

[cpp]view plain

copy

print?

intx ;                 

//引用   (c++認為其是定義)

intx=0;               

//定義

extern

intx ;        

//引用

extern

intx =0 ;    

//定義  (c++認為非法)

建議:a,每個外部變數具有乙個單獨的定義點(在原始檔中)。在定義性宣告中,省略extern類別,並提供乙個顯式的初始化值:  int  errcnt = 0 ;

【所以說,全域性變數就是外部變數】

b,在其它引用外部變數的每個原始檔或標頭檔案中,在引用性宣告中,使用儲存類別extern,並且不要包含初始化值:  extern  int errcnt  ;

【注意:】

外部變數的引用型別必須和其定義型別一致!(分別編譯的時候編譯器無法檢查兩者型別是否一致,但是若不一致執行時會出錯)

[cpp]view plain

copy

print?

intarr[80];  

externint *arr;  

intmain()     

該程式可以編譯通過,但執行時會出錯。原因是,在另乙個檔案中用 extern int *arr來外部宣告乙個陣列並不能得到實際的期望值,因為他們的型別並不匹配。導致指標實際並沒有指向那個陣列。修改:extern int arr。

陣列是陣列指標是指標。雖然在函式間傳遞時陣列名會退化為常量指標。在定義的時候它們是不同的,編譯器給它們分配不同的空間。在外部宣告引用時,編譯器見到int*arr只會認為其是指標,由於其是全域性變數,故給其初始化為0,而編譯器見到extern int arr會知道arr為外部定義的陣列。

(2)同一原始檔中,允許全域性變數和區域性變數同名,但在區域性變數的作用域內,全域性變數不起作用。【即當全域性變數與區域性變數相遇,區域性變數遮蔽全域性變數

[cpp]view plain

copy

print?

#include 

inta=1 , b=2, c=3 ;  

intmain(

void

)        

printf("%d,%d,%d"

,a,b,c) ; 

//輸出 1,2,40

return0 ;  

}  //位於乙個花括號之間的所有語句成為乙個**塊,在**塊開始位置宣告的變數的作用域只在此**塊中

//花括號的作用就是打包,使之成為乙個整體,並與外界絕緣。

變數的儲存方式

1, 動態儲存:在程式的執行過程中,使用它時才分配儲存單元,使用完畢立即釋放。

(其儲存空間在棧上)

自動變數的型別說明符為:auto自動變數是動態儲存方式,凡未加儲存型別說明的變數均視為自動變數。自動變數的作用域和生存期都侷限於定義它的個體內。

2, 靜態變數:在變數定義時就分定儲存單元並一直保持不變,直至程式結束。

(其儲存空間在堆上)

靜態變數的初值是在編譯時賦予的,不是在程式執行期間賦予的

(1)      靜態區域性變數

在區域性變數的說明前加上static 就構成靜態區域性變數。

a,靜態區域性變數在函式內定義,但它的生存期為整個程式

b,其生存期雖為整個程式,但其作用域與自動變數相同,只能在定義的函式內使用。退出函式後,儘管該變數還在,但已不能再使用。

c,允許對靜態區域性變數賦初值。若未賦初值,則由系統自動賦0值

d,只在第一次呼叫函式時給靜態變數賦初值,再次呼叫定義它的函式時,其儲存了前一次被呼叫後留下的值。

【因此,當多次呼叫乙個函式且要求在呼叫之後保留某些變數的值時,可採用靜態區域性變數】

(2)      靜態全域性變數

在全域性變數前加static,就構成了靜態的全域性變數。它們都是靜態儲存方式。但兩者的區別在於:作用域的擴充套件上。

全域性變數的作用域可以擴充套件到整個源程式。靜態全域性變數的作用域侷限於乙個原始檔內。

【因此,全域性變數加上static限制,是為了避免在其它原始檔中被引用,防止出錯】

c語言中static的作用:

1、 修飾變數。

靜態全域性變數,作用域僅限於變數被定義的檔案中。

靜態區域性變數,在函式體中定義的,就只能在這個函式裡用了。

2、 修飾函式。

指函式的作用域僅侷限於本檔案(內部函式),使用內部函式的好處是防止與其他檔案中的函式命名衝突。

**:

C語言變數作用域

作用域描述程式中可訪問識別符號的區域。乙個c變數的作用域可以是塊作用域,函式作用域,函式原型作用域或檔案作用域。int fun int a q作用域結束 在這個例子中,q的作用域只在內層塊,只有內層塊中的 才能訪問q。在c99中,把塊的概念擴充套件到for迴圈,while迴圈,do while迴圈和...

C語言變數的作用域

什麼叫做 塊呢?塊就是我們在復合語句中的就要 塊,在 塊中的auto 自動變數 是無法超出這個範圍的,一旦超出了這個範圍的話就會消失它的作用,比如 void main 這個main函式的花括號就是乙個 塊,而我們要在它的裡面再定義乙個 塊 這個就是乙個 塊,這是個內部的 塊,雖然是寫在main函式裡...

C語言變數的作用域

作用域是程式中定義的變數存在 或生效 的區域,超過該區域變數就不能被訪問。c語言中有四種地方可以定義變數。1 在所有函式外部定義的是全域性變數。2 在標頭檔案中定義的是全域性變數。3 在函式或語句塊內部定義的是區域性變數。4 函式的引數是該函式的區域性變數。順便解釋一下,函式的宣告和函式的定義是兩個...