C C 深層探索

2021-05-17 14:19:59 字數 2735 閱讀 6786

一、

1、關於位元組順序:話說在特定的硬體平台上,多位元組資料的順序存放有兩種方式(little-endian、big-endian)。前者的資料的低位元組

部分存放在低位址記憶體,後者恰好相反。pc一般是基於ia-32微處理器,屬於little-endian。某些risc架構的cpu,例如sparc、

powerpc等,則屬於big-endian。

2、呼叫函式、棧,變數的可見範圍與生命期:我們知道乙個程式由資料和**兩大部分構成,而資料有幾種類別,一種是「靜態」的,也就

是說在整個程式執行期間,它在記憶體中的位址是固定的,**可以對其反覆訪問。c語言中的外部變數,內部靜態變數就屬於此類,儲存

就是對「棧」進行操作。

3、變數的宣告和定義: 「宣告」只是告訴編譯器某個識別符號是:變數(什麼型別?)還是函式(引數和返回值是什麼?)。要是在後面的

**中出現該識別符號,編譯器就知道如何處理。宣告變數不會導致編譯器為這個變數分配儲存空間。

鏈結程式就會報錯。

鏈結性質是內部的。而對於內部變數,static改變的是其儲存性質,使其可見範圍不變,生存期為程式執行期間。

7、使用標頭檔案: 標頭檔案應該包含:函式原型宣告,全域性變數的宣告,自己定義的巨集和型別;

不應該包含:全域性變數和函式的定義(全域性變數只能定義一次,如果你把「int global = 0;」這樣的語句放在標頭檔案)

則凡是包含了這個標頭檔案的地方都定義了一次全域性變數global,到了鏈結的時候,鏈結程式就會報告說找到很多歌global

,不知該用哪乙個。函式的情形也是這個道理,同樣會產生名字衝突而導致鏈結失敗。

static變數和static函式(在全域性變數宣告與static變數的定義之間,static優先,於是本來應該訪問乙個

全域性變數的**,最後訪問的卻是乙個由標頭檔案定義的、毫無用處的static變數)。

二、(函式和變數的名字),找到的話就把該函式裡面需要定位的符號進行定位,然後將整塊函式**放進可執行檔案裡。

只存在乙份函式**。但動態庫的資料仍然可能有多份副本。因為每乙個鏈結到動態庫的程序都可能會修改庫的資料,每當出現這種情況

的時候,作業系統就複製出乙份資料的副本,然後修改程序的位址空間對映,使它指向新的資料副本,於是程序修改的知識屬於自己的那

份資料。

10、簡單型別的轉換: 整型之間的轉換(如果被擴充套件變數是帶符號的,那麼擴充套件就是帶符號的擴充套件;如果被擴充套件變數是不帶符號的,那麼

擴充套件就是不帶符號的擴充套件)。整型值轉換為浮點型值不一定是安全的,浮點型值的數值範圍雖然大,但卻受精度的限制(不能超過6位

有效數字)。

11、 復合型別的對齊

指標的值可以在執行期隨意改變。

陣列名字只是代表某段儲存空間的起始位址,陣列名字相當於乙個常量,編譯器不會為陣列名字本身分配空間,

不能改變,不能改變陣列名字代表的位址值。

陣列指標,指向指標的指標,多維陣列

三13、 詞法分析: 最大匹配原則

14、 注釋:  /* */ 與 //

15、 優先順序與運算順序: 不要對運算的順序作過多的假設。

16、 友好的typedef: 定義新的資料型別名,實際賦予別名。

typedef 跟變數一樣有可視範圍,並且內層的可以覆蓋外層的。

在同一範圍內,不能使用相同的名字定義不同的資料型別。

#define(預編譯指令)執行的僅僅是低階的符號替換,typedef是由編譯器進行語法分析,用它定義的型別對

宣告或者定義語句中的每乙個變數都起作用。

17、 c_v限定詞: const在c++與c兩種語言中存在差別

1)c++能夠把(已有常量賦值的)const變數看作編譯期常數,c沒有這種功能。

2)c++預設const變數的鏈結性質是內部的,而c則相反,預設是外部的。

3)c只能允許用常量初始化const外部變數,c++沒有這種限制。

volatile修飾乙個變數的意思是告訴編譯器這個變數可能會被外部事件修改,編譯期在優化**時不要擅自作出假

定,而導致錯誤的結果。

18、字串: 字串常量,不能被改變。指向字串的指標 不能修改字串。

可以使用字串常量來初始化字元陣列,可以修改字元陣列的值。

19、void: void指標具有兩個主要特性:

1)void指標可以和其他型別指標(函式指標除外)相互轉化而不需要型別強制轉換。

2)不能對它執行取值和下標操作。

在c++中,對型別的檢查非常嚴格,任何指標(包括void指標)都不能不通過強制轉換就直接賦值給其他指標;

但c++中,如果把其他型別指標的值賦給void指標,則不需要強制轉換,與c一致。(void指標賦予其他指標就需要強制轉

換)20、 #pragma 為特定的編譯器提供特定的編譯指示。_pragma

21、 _complex 與 _imaginary

22、 內聯函式: 巨集僅僅是一種記號替換,不像函式,它沒有辦法知道真正的引數是什麼,從而無法對引數進行檢查,也不能像

函式那樣把某些運算侷限於內部。

由於內聯函式要求編譯器在呼叫點盡可能地嵌入函式的**,所以,僅僅宣告乙個內聯函式卻沒有在同一檔案中給出函式

定義的做法是沒有意義的。c++明確規定,一旦使用inline宣告乙個函式,這個函式就成為內聯函式,所有呼叫該函式的

檔案都應該給出函式的定義,並且所有這些定義都應該是相同的。所以內聯函式的定義一般直接放在標頭檔案。

c++的inline修飾符不改變函式的鏈結特性,所以內聯函式完全可以有外部鏈結特性。進一步規定,所以外部鏈結的內聯

函式都必須具有相同的位址,他們內部定義的靜態變數都指向同乙個實體。

C C 語言struct深層探索

c c 語言struct深層探索 2008年04月02日 星期三 下午 06 24 c c 語言struct深層探索 2008年03月27日 星期四 08 16 p.m.c c 語言struct深層探索 1.struct的巨大作用 面對乙個人的大型c c 程式時,只看其對struct的使用情況我們就...

C C 語言struct深層探索

1.struct的巨大作用 面對乙個人的大型c c 程式時,只看其對struct的使用情況我們就可以對其編寫者的程式設計經驗進行評估。因為乙個大型的c c 程式,勢必要涉及一些 甚至大量 進行資料組合的結構體,這些結構體可以將原本意義屬於乙個整體的資料組合在一起。從某種程度上來說,會不會用struc...

C C 語言struct深層探索

1.struct的巨大作用 面對乙個人的大型c c 程式時,只看其對struct的使用情況我們就可以對其編寫者的程式設計經驗進行評估。因為乙個大型的c c 程式,勢必要涉 及一些 甚至大量 進行資料組合的結構體,這些結構體可以將原本意義屬於乙個整體的資料組合在一起。從某種程度上來說,會不會用stru...