學習一 關鍵字

	我是一名軟件工程專業即將大四的學生,周圍的同學都在準備考研,不知道爲什麼考研對我沒有太大的吸引力。當然我不是反對考研,上研究生確實很好,它可以讓我們深入某一個流域、對知識有一個系統的理解等。但對於一個喜歡技術的我而言,我更傾向於在實際開發經驗中去獲得新知識,可能這也就是我選擇工作的主要原因吧。所以最近一直都在準備即將到來的2014年的校園招聘,聽畢業參加工作的一些學長那裏得知筆試、面試大多都還是考一些最基礎的東西,比如C語言/數據結構/網絡等。因此最近也都在看一些基礎的東西和往年一些公司的面試題,看了好幾天,感覺考得是挺基礎的,但也有一定的深度。有很多看似很基礎的東西就是弄不明白,可能這也與我們的教育體制有關吧(至少本人很鄙視)。感覺現在很多計科出身的同學大學畢業了,連C語言的門都還沒有找到,更別說入門了,有的都還以爲C語言早過時了,而且太簡單了,學也沒有什麼用。所以大多同學都熱衷直接學什JAVA/C#/C++等高級語言,甚至有些學校把這些高級語言都開了一遍。個人認爲如果把C語言這種簡單的整明白了,我想其它語言學習也不再話下。好了,不多說了(這是本人第一次寫博客,囉嗦了點~),下面是最近對C語言的深入學習吧,現在讓我們一塊進入主題吧。
 
	可能我現在問大家:C語言中有多少關鍵字?sizeof怎麼用?sizeof是個關鍵字嗎? 我相信現在很多同學都答不出來(當然在我沒有複習以前,一些關鍵字我自己都也不認識)。
	C語言標準定義了32個關鍵字:
	關鍵字			意義
	auto 			聲明自動變量,缺省時編譯器一般默認爲auto
	int 			聲明整型變量
	double 		聲明雙精度變量
	long 			聲明長整型變量
	char 			聲明字符型變量
	float 		聲明浮點型變量
	short 		聲明短整型變量
	signed 		聲明有符號類型變量
	unsigned 		聲明無符號類型變量
	struct 		聲明結構體變量
	union 		聲明聯合數據類型
	enum 			聲明枚舉類型
	static 		聲明靜態變量
	switch 		用於開關語句
	case 			開關語句分支
	default 		開關語句中的“其他”分支
	break 		跳出當前循環
	register 		聲明寄存器變量
	const 		聲明只讀變量
	volatile 		說明變量在程序執行中可被隱含地改變
	typedef 		用以給數據類型取別名(當然還有其他作用)
	extern 		聲明變量是在其他文件正聲明(也可以看做是引用變量)
	return 		子程序返回語句(可以帶參數,也可不帶參數)
	void 			聲明函數無返回值或無參數,聲明空類型指針
	continue 		結束當前循環,開始下一輪循環
	do 			循環語句的循環體
	while 		循環語句的循環條件
	if 			條件語句
	else			條件語句否定分支(與if 連用)
	for 			一種循環語句(可意會不可言傳)
	goto 			無條件跳轉語句
	sizeof 		計算對象所佔內存空間大小
	在一一講解這些關鍵字前,先弄清楚兩個概念:
	什麼是聲明?什麼是定義?他們怎麼區別?
	舉個例子:
	
	A> int i; 
	B> extern int i; 
	哪個是定義?哪個是聲明?或者都是定義或者都是聲明?
	什麼是定義:所謂的定義就是(編譯器)創建一個對象,爲這個對象分配一塊內存並給它取上一個名字,這個名字就是我們經常所說的變量名或對象名。但注意,這個名字一旦和這塊內存匹配起來(可以想象是這個名字嫁給了這塊空間,沒有要彩禮啊。^_^),它們就同生共死,終生不離不棄。並且這塊內存的位置也不能被改變。一個變量或對象在一定的區域內(比如函數內,全局等)只能被定義一次,如果定義多次,編譯器會提示你重複定義同一個變量或對象。
	什麼是聲明:有兩重含義,如下:
	第一重含義:告訴編譯器,這個名字已經匹配到一塊內存上了(伊人已嫁,吾將何去何從?何以解憂,唯有稀粥),下面的代碼用到變量或對象是在別的地方定義的。聲明可以出現多次。
	第二重含義:告訴編譯器,我這個名字我先預定了,別的地方再也不能用它來作爲變量名或對象名。比如你在圖書館自習室的某個座位上放了一本書,表明這個座位已經有人預訂,別人再也不允許使用這個座位。其實這個時候你本人並沒有坐在這個座位上。這種聲明最典型的例子就是函數參數的聲明,例如:
	void fun(int i, char c);
	好,這樣一解釋,我們可以很清楚的判斷:A)是定義;B)是聲明。那他們的區別也很清晰了。
	記住,定義、聲明最重要的區別:定義創建了對象併爲這個分配內存,聲明沒有分配內存。(一個是抱伊人,一個抱自己,哈哈~)。
	 
	1.最寬恆大量的關鍵字---auto
	auto: 編譯器在默認情況下,所有變量都是auto的。所以說它很寬恆大量,你就當他不存在吧。
 
	2. 最快的關鍵字---register
	register:這個關鍵字請求編譯器儘可能的將變量存在cpu內部寄存器中而不是通過內存尋址訪問以提高效率。注意是儘可能,不是絕對。你想想,一個cpu的寄存器也就那麼幾個或幾十個,你要是定義了很多很多register變量,它累死也不可能把這些變量放到寄存器吧,輪也輪不到你。
	皇帝身邊的小太監---寄存器:大家都知道皇帝閱讀奏章的時候,大臣總是先把奏章交給皇帝身邊的小太監,小太監呢再交給皇帝同志。其實這個小太監只是箇中轉站,別無其他功能。  好了,現在讓我們聯想一下我們的cpu,cpu不就相當於皇帝嗎,大臣就相當於我們的內存,數據從他們這拿出來。那小太監就是我們的寄存器了(這裏不考慮cpu的高速緩存區)。數據從內存中拿出來先放到寄存器中,然後cpu再從寄存器中讀取數據來處理,處理之後同樣通過寄存器放回內存裏,cpu不直接和內存打交道。但是我們要注意一點:小太監是主動從大臣手裏接過奏章然後有主動交給皇帝,但我們的寄存器沒有這麼自覺,它從不主動幹什麼事。	可能大家會問爲啥這麼麻煩?,速度,就是因爲速度。
	register使用的注意事項:雖然寄存器的速度非常快,但使用register也有些限制:register變量必須是被cpu寄存器所接受的類型。意味着register必須是一個單個的值,並且其長度應該小於等於整型的長度。而且register變量有可能不存放在內存中,所以不能用取址運算符“&”來獲取register變量的地址。
	3. 最名不符實的關鍵字---static
	不要以爲關鍵字static很安靜,其實它一點都不安靜。這個關鍵字在C語言裏主要有兩個作用,C++對它進行了擴展。
	第一個作用:修飾變量。變量又分爲局部和全局變量,但它們都存在內存的靜態區。
	   靜態全局變量:作用域僅限於變量定義的文件中,其他文件即使使用extern聲明也沒有辦法使用它。準確地說作用域是從定義之處開始,到文件結尾處結束,在定義之處前面的那些代碼行也不能使用它,要想使用就得在前面加上extern***。噁心吧?
	   靜態局部變量:在函數體內部定義,就只能在這個函數裏面使用,同一個文檔中的其他函數也不能用。由於被static修飾的變量總是存在內存的靜態區,所以即使這個函數運行結束,這個靜態變量的值還是不會被銷燬。函數下次使用時仍然能用到這個值。
	
static int j ; 

void fun1(){
   static int i = 0; 
   i++; 
}
void fun2(){
   j = 0; 
   j++; 
}

int main(){
   for(int k = 0; k<10; k++){
       fun1(); 
       fun2(); 
    }
   return 0; 
}
i和j 的值分別是多少?爲什麼?
	第二個作用:修飾函數。函數前加上static使得函數成爲靜態函數。但此處“static”的含義不再指存儲方式,而是指對函數的作用域僅侷限於本文件(所以又稱局部函數)。使用內部函數的好處是:不同人編寫不同的函數式,不用擔心自己定義的函數是否會與其他文件中的函數同名。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章