第十九節 條件編譯使用分析
1、#include的本質是將已經存在的檔案內容嵌入到當前檔案中;
2、#include的間接包含同樣會產生嵌入檔案內容的操作;
3、條件編譯使得我們可以按不同的條件編譯不同的**段,因而可以產生不同的目標**;
4、#if…#else…#endif被預處理器處理,而if…else…語句被編譯器處理,必然編譯進目標**;
5、通過編譯器命令能夠定義預處理器使用的巨集:
① gcc -dname=value file.c
② gcc -dname file.c
6、條件編譯可以避免重複包含同乙個標頭檔案;
7、條件編譯是工程開發中可以區別不同產品線的**;
8、條件編譯可以定義產品發布和除錯版;
第二十節 #error和#line分析
1、#error用於自定義一條編譯錯誤資訊;
2、#warning用於自定義一條編譯警告資訊;
3、#error和#warning常用於條件編譯的情形;
4、#line常用於強制指定新的行號和檔名:#line linenum filename(可省略);
第二十一節 #pragma分析
1、#pragma message:
① message引數在大多的編譯器中都有相似的實現;
②message引數在編譯時輸出訊息到編譯輸出視窗中;
③message引數用於條件編譯中科提示**的版本資訊;
2、#pragma once:
① #pragma once用於保證標頭檔案只被編譯一次;
② #pragma once是編譯器相關的,不一定被支援;
3、#pragma pack(num):用於制定記憶體對齊方式,編譯器預設的是4個位元組對齊,記憶體對齊是不同的資料型別以一定的順序在記憶體中存放;
4、為什麼需要記憶體對齊?
① cpu對記憶體的讀取是不連續的,分塊讀取,快的大小只能是1,2,4,…位元組;
② 當讀取操作的資料未對齊,則需要兩次匯流排週期來訪問記憶體,因此效能大打折扣;
注:struct占用記憶體的大小?
分析:① 第乙個成員起始於0偏移處;
② 每乙個成員按其型別大小和pack引數中較小的乙個進行對齊:
i. 偏移位址必須能被對齊引數整除;
ii. 結構體成員的大小取其內部長度最大的資料成員作為其大小;
③ 結構體總長度必須是所取對齊引數的整數倍;
eg: //對齊引數 偏移位址 大小
第二十二節 #和##操作符
1、#運算子用於在預處理期將巨集引數轉換為字串;
2、##運算子用於在預處理期粘連兩個識別符號;
3、編譯器不知道#和##存在,他們只在巨集定義中生效;
第二十三節 指標的本質分析
1、在指標宣告時,號表示所宣告的變數是指標;
2、在指標使用時,號表示取指標所指向的記憶體空間中的值;
3、指標是變數,因此可以宣告指標引數;
4、當乙個函式體內部需要改變實參的值,則需要使用指標引數;
5、指標儲存的是記憶體位址,在32位作業系統中占用4個位元組;
6、口訣:左數右指
① 當const出現在號的左邊時,指標指向的資料為常量;
② 當const出現在號的右邊時,指標本身為常量;
第二十四節 陣列的本質分析
1、陣列名代表陣列首元素的位址,陣列的位址需要用取位址符號得到;
2、陣列的首元素的位址值與陣列的位址值相同;
3、陣列首元素的位址與陣列位址意義不同,值相同但所占有的儲存空間不同;
4、陣列名不包括陣列的長度資訊,在表示式中陣列名只能作為右值使用;
5、陣列名其實並不是指標,不能將其等同於指標;
C語言筆記(四)
1 為什麼要使用陣列?陣列定義?陣列的要素?思考 輸入輸出10個學生的年齡 資料模型 10個學生年齡 操作 迴圈 乙個整型變數可以儲存乙個學生的年齡 int age0 int age1 int age2 int age3 int age4 int age5 int age6 int age7 int...
C語言筆記(四)const
變數定義的方式 const 在型別前 const int var 1oo const在型別後 int const var2 999 以上兩種定義的方式沒有區別 const變數在定義的時候被初始化,當乙個變數被const變數意味著該變數是乙個常量,不可修改,換句話說該變數只能做右值,不能做左值 int...
c語言學習筆記四
結構體 復合型別和結構體 復合型別 示例 struct test sturuct 如果用這種復合型別來定義變數 示例 struct test stuructz1,z2 定義訪問結構體 include int main void z int x 3 z.x x z.y 4 printf z f f z...