C語言細節筆記2

2022-06-29 02:03:11 字數 2665 閱讀 8020

c語言常見問題筆記:

1. 指標的宣告

char * p1, p2;

p1 是乙個指向char型別的指標,而p2是乙個char型別變數

這是由於 * 並不是基本型別的一部分,而是包含被宣告識別符號的宣告符的一部分。 

2. 儲存型別

同乙個靜態函式或靜態變數最好在所有的宣告和定義出都包含(static)

extern 作為乙個格式上的提示,表明函式的定義可能出現在另乙個原始檔中

關健字auto毫無用處,已經過時了

3. 在乙個檔案中定義了乙個extern陣列,但在另乙個檔案中無法通過sizeof取到這個數

組的大小。這是由於sizeof是在編譯時產生作用,它不能獲得在另乙個檔案中的陣列大小

4. 如何在乙個檔案中獲得另乙個檔案中定義的陣列的大小

1. 在定義陣列的檔案中宣告,定義,並初始化乙個變數,儲存陣列的大小

2. 使用define為陣列定義乙個確定的可見的長度

3. 在陣列後面加入乙個元素作為哨兵值,(通常為 0,-1,null)

5. 實現抽象資料型別時,讓使用者使用指向沒有公開定義(也許還隱藏在型別定義後邊)的

結構型別的指標。客戶使用結構指標(及呼叫輸入和返回結構指標的函式)而不知道結構的

成員是什麼。

6. 通常對結構進行傳遞和返回時,使用結構指標而非結構,這是由於當結構作為函式引數

傳遞時,通常會把整個結構都推進棧,需要多少空間就使用多少空間,為了避免這個代價,

經常使用指標而不是結構。

7. 使用sizeof返回值大於結構的期望值,這可能是由於尾部填充,也可能是內部填充。

8. 空指標不會指向任何地方,它不是任何物件或函式的位址,取位址操作符&永遠也不會

但會空指標。malloc函式呼叫失敗會返回空指標,這是空指標的典型用法,表示未分配或

尚未指向任何地方的特殊指標值。空指標並不等同於為初始化的指標,未初始化的指標可

能指向任何地方。每種型別都有乙個空指標,而不同型別的空指標的內部表示可能不盡相

同。9. 使用未初始化的指標是非法的,因為此時不知道指標指向何處,且未初始化,通常包括

垃圾資訊,所以甚至都不能保證該指標是乙個空指標

int * p;

scanf("%d", p);

10. 宣告乙個指標變數時,編譯器只分配了足夠容納指標本身的記憶體,並沒有分配任何讓

指標指向的記憶體。

11. 使用malloc動態分配記憶體後,如果再使用realloc來改動動態分配的記憶體大小,則使

用malloc之後,realloc之前,指向該動態記憶體的指標的值也需要改變,這是因為realloc

並不一定能在原地擴大記憶體區域,如果它必須到記憶體中其它地方找尋足夠大的記憶體,則它

會返回乙個不同的指標,而原有的指標值就變為不可用的

int * p, * q;

p = (int *)malloc(len * sizeof(int));

q = p;

p = (int *)realloc((void *)p, len_max * sizeof(int));

此時q指向的記憶體可能非法。

12. 在c語言中,sizeof('a')的值不是sizeof(char),這是由於在c語言中,字元常量是int

型,所以sizeof('a')的值是sizeof(int),這正是c語言與c++的乙個不同的地方

int main(void)

13. 作為一般規則

a.將巨集定義,結構 聯合 列舉宣告,typedef宣告,外部函式宣告,全域性變數宣告,放入 .h 的

檔案中。

b.永遠不要把外部函式原型放到 .c檔案中。

c.如果定義或宣告為乙個原始檔私有,則最好留在該檔案中,作用域限於單檔案的私有函式和

變數應該宣告為static

d.不能把實際的**,如函式體,或全域性變數定義,即定義和初始化例項放入標頭檔案中。

e.當用多個檔案建立乙個專案時,應單獨編譯每個檔案,即使用特定的編譯選項,只進行編譯,

然後再將生成的目標檔案鏈結起來。

14. 在c語言中,只有輸入例程試圖讀取並失敗之後才能得到eof,通常c語言只要檢查輸入例程的返

回值。

while (!feof(infp))

這些**會把檔案的最後一行複製兩遍,就是上述的原因

一般來說可以不使用feof,偶爾使用foef或ferror在stdio呼叫返回eof或null之後判斷是檔案結束

條件還是檔案讀取錯誤。

上述**可改為

while (fgets(buf, maxline, infp) != null)

puts(buf, outfp);

15. printf實現可變域寬度

printf("%*d", width, x);

格式說明符中的星號表示引數列表中的乙個int值表示域寬度

16. 作為乙個一般性的規則,不能混用scanf和gets或任何其他輸入例程的呼叫,scanf對換行符的

特殊處理幾乎一定會帶來問題。要麼就用scanf處理所有的輸入,要麼不用

int n;

char str[10];

scanf("%d", &n);

gets(str);

上述**中的gets讀取到的只是乙個換行符,甚至程式不會給你輸入字串的機會

17. c語言的函式總是接收引數的副本,因此函式永遠不能通過向引數賦值返回任何東西

C語言細節

參考 注釋必須和 一起維護,不應該描述顯而易見的事,或把別的地方已說清楚的東西在說一遍。字面常量沒有語義,也沒有真正的記憶體位址。所以不可以取其位址,也不可以用於初始化普通引用,例如 long r1 40000 但是const long r1 40000 卻是合法的。所以,盡量不要使用字面常量,而應...

C語言細節

a b 先賦值再自增 a b先自增再賦值 float 6 4是1.500000 float 6 4 是1.000000 原始檔.c 目標程式.obj 執行程式.exe 都是二進位制檔案 源程式以ascii 形式存於文字檔案 c程式演算法可無輸入必須要有輸出 三種基本結構可以完成任何複雜的任務 大括號...

C語言細節

1.c誰呼叫了main函式 linux執行乙個程式就是建立乙個新程序,然後把這個程式丟到這個程序中執行直到結束。linux通過.task執行程式,新程序作為命令程序的乙個子程序執行。main函式的返回值最終會返回給父程序。父程序的引數傳遞給子程序。2.void型別的本質 void的意思是乙個變數還不...