C語言基礎(chǔ)知識(shí)點(diǎn)解析(extern,static,typedef,const)
一、extern的使用方法
下面是《C語言程序設(shè)計(jì)》中的關(guān)于extern的解釋:
在一個(gè)源程序的所有源文件中,一個(gè)外部變量只能在某個(gè)文件中定義一次,而其他文件可以通過extern聲明來訪問它(定義外部變量的源文件中也可以包含對(duì)該外部變量的extern聲明)。外部變量的定義中必須指定數(shù)組的長(zhǎng)度,但extern聲明不一定指定數(shù)組的長(zhǎng)度。
外部變量的初始化只能出現(xiàn)在其定義中。
假設(shè)函數(shù)push與pop定義在一個(gè)文件中,而變量val與sp在另一個(gè)文件中定義本那個(gè)被初始化(通常不太可能這樣組織程序),則需要通過下面這些定義與申明把這些函數(shù)與聲明“綁定”在一起:
在文件file1中:
extern int sp;
extern double val[];
void push(double f) {.......}
double pop(void) {........}
在文件file2中:
int sp=0;
double val[MAX_SIZE];
由于在file1中的extern申明不僅放在函數(shù)的外部,還放在它們的最前面,因此它們適用于該文件中的所有函數(shù)。對(duì)于file1,這樣一組聲明就夠了。如果要在同一文件中先使用、后定義變量sp與val,也需按照這種方式組織文件。
使用通俗的語言總結(jié)extern的使用方法,殼分為下面三種情況:
1) extern修飾變量的聲明。舉例來說,如果文件a.c需要引用b.c中變量int v,就可以在a.c中聲明extern int v,然后就可以引用變量v。這里需要注意的是,被引用的變量v的鏈接屬性必須是外鏈接(external)的,也就是說a.c要引用到v,不只是取決于在a.c中聲明extern int v,還取決于變量v本身是能夠被引用到的。這涉及到c語言的另外一個(gè)話題--變量的作用域。能夠被其他模塊以extern修飾符引用到的變量通常是全局變量。還有很重要的一點(diǎn)是,extern int v可以放在a.c中的任何地方,比如你可以在a.c中的函數(shù)fun定義的開頭處聲明extern int v,然后就可以引用到變量v了,只不過這樣只能在函數(shù)fun作用域中引用v罷了,這還是變量作用域的問題。對(duì)于這一點(diǎn)來說,很多人使用的時(shí)候都心存顧慮。好像extern聲明只能用于文件作用域似的。
2) extern修飾函數(shù)聲明。從本質(zhì)上來講,變量和函數(shù)沒有區(qū)別。函數(shù)名是指向函數(shù)二進(jìn)制塊開頭處的指針。如果文件a.c需要引用b.c中的函數(shù),比如在b.c中原型是int fun(int mu),那么就可以在a.c中聲明extern int fun(int mu),然后就能使用fun來做任何事情。就像變量的聲明一樣,extern int fun(int mu)可以放在a.c中任何地方,而不一定非要放在a.c的文件作用域的范圍中。對(duì)其他模塊中函數(shù)的引用,最常用的方法是包含這些函數(shù)聲明的頭文件。使用extern和包含頭文件來引用函數(shù)有什么區(qū)別呢?extern的引用方式比包含頭文件要簡(jiǎn)潔得多!extern的使用方法是直接了當(dāng)?shù)?,想引用哪個(gè)函數(shù)就用extern聲明哪個(gè)函數(shù)。這大概是KISS原則的一種體現(xiàn)吧!這樣做的一個(gè)明顯的好處是,會(huì)加速程序的編譯(確切的說是預(yù)處理)的過程,節(jié)省時(shí)間。在大型C程序編譯過程中,這種差異是非常明顯的。
3) 此外,extern修飾符可用于指示C或者C++函數(shù)的調(diào)用規(guī)范。比如在C++中調(diào)用C庫函數(shù),就需要在C++程序中用extern “C”聲明要引用的函數(shù)。這是給鏈接器用的,告訴鏈接器在鏈接的時(shí)候用C函數(shù)規(guī)范來鏈接。主要原因是C++和C程序編譯完成后在目標(biāo)代碼中命名規(guī)則不同。這個(gè)用法的說明在下篇文章。
下面再歸納解釋一下extern的用法:
在C語言中,修飾符extern用在變量或者函數(shù)的聲明前,用來說明“此變量/函數(shù)是在別處定義的,要在此處引用”。
1. extern修飾變量的聲明。舉例來說,如果文件a.c需要引用b.c中變量int v,就可以在a.c中聲明extern int v,然后就可以引用變量v。這里需要注意的是,被引用的變量v的鏈接屬性必須是外鏈接(external)的,也就是說a.c要引用到v,不只是取決于在a.c中聲明extern int v,還取決于變量v本身是能夠被引用到的。這涉及到c語言的另外一個(gè)話題--變量的作用域。能夠被其他模塊以extern修飾符引用到的變量通常是全局變量。還有很重要的一點(diǎn)是,extern int v可以放在a.c中的任何地方,比如你可以在a.c中的函數(shù)fun定義的開頭處聲明extern int v,然后就可以引用到變量v了,只不過這樣只能在函數(shù)fun作用域中引用v罷了,這還是變量作用域的問題。對(duì)于這一點(diǎn)來說,很多人使用的時(shí)候都心存顧慮。好像extern聲明只能用于文件作用域似的。
2. extern修飾函數(shù)聲明。從本質(zhì)上來講,變量和函數(shù)沒有區(qū)別。函數(shù)名是指向函數(shù)二進(jìn)制塊開頭處的指針。如果文件a.c需要引用b.c中的函數(shù),比如在b.c中原型是int fun(int mu),那么就可以在a.c中聲明extern int fun(int mu),然后就能使用fun來做任何事情。就像變量的聲明一樣,extern int fun(int mu)可以放在a.c中任何地方,而不一定非要放在a.c的文件作用域的范圍中。對(duì)其他模塊中函數(shù)的引用,最常用的方法是包含這些函數(shù)聲明的頭文件。使用extern和包含頭文件來引用函數(shù)有什么區(qū)別呢?extern的引用方式比包含頭文件要簡(jiǎn)潔得多!extern的使用方法是直接了當(dāng)?shù)?,想引用哪個(gè)函數(shù)就用extern聲明哪個(gè)函數(shù)。這大概是KISS原則的一種體現(xiàn)吧!這樣做的一個(gè)明顯的好處是,會(huì)加速程序的編譯(確切的說是預(yù)處理)的過程,節(jié)省時(shí)間。在大型C程序編譯過程中,這種差異是非常明顯的。
3. 此外,extern修飾符可用于指示C或者C++函數(shù)的調(diào)用規(guī)范。比如在C++中調(diào)用C庫函數(shù),就需要在C++程序中用extern “C”聲明要引用的函數(shù)。這是給鏈接器用的,告訴鏈接器在鏈接的時(shí)候用C函數(shù)規(guī)范來鏈接。主要原因是C++和C程序編譯完成后在目標(biāo)代碼中命名規(guī)則不同。
二、static的使用方法
下面是《C語言程序設(shè)計(jì)》中的關(guān)于static的解釋:
外部的static聲明通常多用于變量,當(dāng)然,它也可用于聲明函數(shù)。通常情況下,函數(shù)名字是全局可訪問的,對(duì)整個(gè)程序的各個(gè)部分而言都可見。但是,如果把函數(shù)申明為static類型,則該函數(shù)名除了對(duì)該函數(shù)申明所在的文件可見外,其他文件都不可見。
static也可用于申明內(nèi)部變量。static類型的內(nèi)部變量同自動(dòng)變量一樣,是某個(gè)特定函數(shù)的局部變量,只能在該函數(shù)中使用,但它與自動(dòng)變量不同的是,不管其所在的函數(shù)是否別調(diào)用,它一直存在,而不像自動(dòng)變量那樣,隨著所在函數(shù)的調(diào)用和退出而存在和消失。換句話說,static類型的內(nèi)部變量是一種只能在某個(gè)特定函數(shù)中使用但一直占據(jù)空間的變量。
使用通俗的說法解釋關(guān)于static的三種用法:
1)在函數(shù)體,一個(gè)被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過程中維持其值不變。這個(gè)變量也成為靜態(tài)局部變量。
2)在模塊內(nèi)(但在函數(shù)體外),一個(gè)被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問。它是一個(gè)本地的靜態(tài)全局變量。
3)在模塊內(nèi),一個(gè)被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用。那就是,這個(gè)函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用。
三、typedef的使用方法
下面是《C語言程序設(shè)計(jì)》中的關(guān)于typedef的解釋:
從任何意義上上講,typedef申明并沒有創(chuàng)建一個(gè)新類型,它只是為某個(gè)已存在的類型增加了一個(gè)新的名稱而已。typedef聲明也沒有增加任何新的語義,通過這種方式聲明的變量和通過普通聲明方式聲明的具有完全相同的屬性。實(shí)際上,typedef類似于#define語句,但由于typedef是由編譯器解釋的,因此它的文本替換功能要超過處理器的能力。例如:
typedef int (*PFI)(char *, char * );
該語句定義了類型PFI是“一個(gè)指向函數(shù)的指針“,該函數(shù)具有兩個(gè)char*的參數(shù),返回值類型為int *.
除了表達(dá)方式更簡(jiǎn)潔之外,使用typedef還有另外的兩個(gè)重要原因。首先,它可以使程序參數(shù)化,以提高程序的可移植性。如果typedef聲明的數(shù)據(jù)類型同機(jī)器有關(guān)。那么,當(dāng)程序移植到其他機(jī)器上時(shí),只需要改變typedef類型定義即可。一個(gè)經(jīng)常使用的情況,對(duì)于各種不同大小的整形來說,都使用通過typedef定義的類型名,然后,分別為各個(gè)不同的宿主機(jī)選擇一組合適的short 、int和long類型大小即可。標(biāo)準(zhǔn)庫中有一些例子,例如size_t和ptrdiff_t等。
四、const的使用方法
C語言中const代表著”不可變“,基本和常量一樣不可修改,但是應(yīng)用場(chǎng)景不一樣。
1) 應(yīng)用在變量
const char a='A';
a='B'; //錯(cuò)誤,變量a的值不可以修改。
此時(shí)代表變量a值不可改變,任何企圖修改a變量值的語句(例如a=20;)都會(huì)報(bào)錯(cuò)。
2) 應(yīng)用在指針
應(yīng)用在*左邊
const char *p;
char const *p;
以上兩條語句作用一樣,都是表示指針指向的變量值不可以修改,但指針可以修改。
例如1;
const char *p='A';
char *q;
*p='B'; //錯(cuò),指針指向的值不可以修改。
p=q; //對(duì),指針值可以修改
應(yīng)用在*右邊
char *const *p;
表示指針值(指針指向的位置)不可以改變,但指針指向的值可以改變。
例如2:
char *const *p='A';
char *q;
*P='b'; // 對(duì),指針指向的值可以修改。
p=q; //錯(cuò)誤,指針值不可以修改。
總之,const在*左邊,表示指針指向的值不可以修改。const在*右邊,表示指針值(也就是指針指向的位置)不可以修改。
3)應(yīng)用在函數(shù)參數(shù)
例如3:strcat(char *a,char const *b),將參數(shù)b指向的字符串,添加到參數(shù)a字符串的末尾。
此時(shí),參數(shù)*a值可以改變,但是表示參數(shù)*b值不可改變
上一篇:C++符號(hào)優(yōu)先級(jí)(詳細(xì)整理)
欄 目:C語言
下一篇:優(yōu)先隊(duì)列(priority_queue)的C語言實(shí)現(xiàn)代碼
本文標(biāo)題:C語言基礎(chǔ)知識(shí)點(diǎn)解析(extern,static,typedef,const)
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/3988.html
您可能感興趣的文章
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)- 解析最少換車次數(shù)的問題詳解
- 01-10深入解析最長(zhǎng)公共子串
- 01-10深入解析Linux下\r\n的問題
- 01-10Linux線程管理必備:解析互斥量與條件變量的詳解
- 01-10解析Linux下的時(shí)間函數(shù):設(shè)置以及獲取時(shí)間的方法
- 01-10DHCP:解析開發(fā)板上動(dòng)態(tài)獲取ip的2種實(shí)現(xiàn)方法詳解
- 01-10節(jié)序問題:解析大小的端判定
- 01-10解析如何在C語言中調(diào)用shell命令的實(shí)現(xiàn)方法
- 01-10解析c中stdout與stderr容易忽視的一些細(xì)節(jié)
- 01-10深入解析C中的數(shù)值與


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法