C語言經(jīng)典問答開發(fā)經(jīng)驗 2008-09-01 20:40:55 閱讀135 評論0 字號:大中小 1.這樣的初始化有什么問題?char *p = malloc(10); 編譯器提示“非法初始式” 云云。 答:這個聲明是靜態(tài)或非局部變量嗎?函數(shù)調(diào)用只能出現(xiàn)在自動變量(即局部非靜態(tài)變量) 的初始式中。 2. *p++ 自增p 還是p 所指向的變量? 答:后綴++ 和-- 操作符本質(zhì)上比前綴一目操作的優(yōu)先級高, 因此*p++ 和*(p++) 等價, 它自增p 并返回p 自增之前所指向的值。要自增p 指向的值, 使用(*p)++, 如果副作用的順序無關(guān)緊要也可以使用++*p。 3 我有一個char * 型指針正巧指向一些int 型變量, 我想跳過它們。為什么如下的代碼((int *)p)++; 不行? 答:在C 語言中, 類型轉(zhuǎn)換意味著“把這些二進(jìn)制位看作另一種類型, 并作相應(yīng)的對待”; 這是一個轉(zhuǎn)換操作符, 根據(jù)定義它只能生成一個右值(rvalue)。而右值既不能賦值, 也不能用++ 自增。(如果編譯器支持這樣的擴(kuò)展, 那要么是一個錯誤, 要么是有意作出的非標(biāo)準(zhǔn)擴(kuò)展。) 要達(dá)到你的目的可以用:p = (char *)((int *)p + 1);或者,因為p 是char * 型, 直接用p += sizeof(int); 4.空指針和未初始化的指針是一回事嗎? 答:空指針在概念上不同于未初始化的指針:空指針可以確保不指向任何對象或函數(shù); 5.我可以用0來表示空指針嗎? 答:根據(jù)語言定義, 在指針上下文中的常數(shù)0 會在編譯時轉(zhuǎn)換為空指針。也就是說, 在初始化、賦值或比較的時候, 如果一邊是指針類型的值或表達(dá)式, 編譯器可以確定另一邊的常數(shù)0 為空指針并生成正確的空指針值。因此下邊的代碼段完全合法: 然而, 傳入函數(shù)的參數(shù)不一定被當(dāng)作指針環(huán)境, 因而編譯器可能不能識別未加修飾的0 “表示” 指針。
有兩條簡單規(guī)則你必須遵循: 6. 既然數(shù)組引用會蛻化為指針, 如果arr 是數(shù)組, 那么arr 和&arr 又有什么區(qū)別呢? 答:區(qū)別在于類型: 7. 我如何聲明一個數(shù)組指針? 答:通常, 你不需要。當(dāng)人們隨便提到數(shù)組指針的時候, 他們通常想的是指向它的第一個元素的指針。考慮使用指向數(shù)組某個元素的指針, 而不是數(shù)組的指針。類型T 的數(shù)組蛻變成類型T 的指針, 這很方便; 在結(jié)果的指針上使用下標(biāo)或增量就可以訪問數(shù)組中單獨的成員。而真正的數(shù)組指針, 在使用下標(biāo)或增量時, 會跳過整個數(shù)組, 通常只在操作數(shù)組的數(shù)組時有用—— 如果還有一點用的話。如果你真的需要聲明指向整個數(shù)組的指針,使用類似“int (*ap)[N];”這樣的聲明。其中N 是數(shù)組的大小。如果數(shù)組的大小未知, 原則上可以省略N, 但是這樣生成的類型, “指向大小未知的數(shù)組的指針”, 毫無用處。 8.當(dāng)我向一個接受指針的指針的函數(shù)傳入二維數(shù)組的時候, 編譯器報錯了,這是怎么回事? 答:數(shù)組蛻化為指針的規(guī)則不能遞歸應(yīng)用。數(shù)組的數(shù)組(即C 語言中的二維數(shù)組) 蛻化為數(shù)組的指針, 而不是指針的指針。數(shù)組指針常常令人困惑, 需要小心對待; 如果你向函數(shù)傳遞二位數(shù)組:
答:這里主要的問題是沒有正確地為連接結(jié)果分配空間。C 沒有提供自動管理的字符串類型。C 編譯器只為源碼中明確提到的對象分配空間(對于字符串, 這包括字符數(shù)組和串常量)。程序員必須為字符串連接這樣的運行期操作的結(jié)果分配足夠的空間, ??梢酝ㄟ^聲明數(shù)組或調(diào)用malloc() 完成。strcat() 不進(jìn)行任何分配; 第二個串原樣不動地附加在第一個之后。因此, 一種解決辦法是把第一個串聲明為數(shù)組:
答:返回指針必須是靜態(tài)分配的緩沖區(qū), 或者調(diào)用者傳入的緩沖區(qū), 11. 我有個程序分配了大量的內(nèi)存, 然后又釋放了。但是從操作系統(tǒng)看,內(nèi)存的占用率卻并沒有回去。 答:多數(shù)malloc/free 的實現(xiàn)并不把釋放的內(nèi)存返回操作系統(tǒng), 而是留著供同一程序的后續(xù)malloc() 使用。 12. calloc() 和malloc() 有什么區(qū)別?利用calloc 的零填充功能安 答:calloc(m, n) 本質(zhì)上等價于: 13. 我認(rèn)為我的編譯器有問題: 我注意到sizeof('a') 是2 而不是1 (即,不是sizeof(char))。 答:可能有些令人吃驚, C語言中的字符常數(shù)是int 型, 因此sizeof('a') 是sizeof(int),這是另一個與C++ 不同的地方。 14. 為什么聲明extern int f(struct x *p); 報出了一個奇怪的警告信息“結(jié)構(gòu)x 在參數(shù)列表中聲明”? 答:與C 語言通常的作用范圍規(guī)則大相徑庭的是, 在原型中第一次聲明(甚至提到)的結(jié)構(gòu)不能和同一源文件中的其它結(jié)構(gòu)兼容, 它在原型的結(jié)束出就超出了作用范圍。要解決這個問題, 在同一源文件的原型之前放上這樣的聲明:
答:const 限定詞真正的含義是 “只讀的”; 用它限定的對象是運行時 (同常) 不能被賦值的對象。 16. 我能否把 main() 定義為 void, 以避免擾人的 “main無返回值”警告? 答:不能。main() 必須聲明為返回 int, 且沒有參數(shù)或者接受適當(dāng)類型的兩個參數(shù)。如果你調(diào)用了 exit() 但還是有警告信息, 你可能需要插入一條冗余的 return語句(或者使用某種 “未到達(dá)”指令, 如果有的話)。很多書不負(fù)責(zé)任地在例子中使用 void main(), 并宣稱這樣是正確的。但他們錯了。
答:#pragam 指令提供了一種單一的明確定義的 “救生艙”, 可以用作各種 (不可移植的) 實現(xiàn)相關(guān)的控制和擴(kuò)展:源碼表控制、結(jié)構(gòu)壓縮、警告去除 (就像 lint 的老 /* NOTREACHED */注釋), 等等。 18. “#pragma once” 是什么意思?我在一些頭文件中看到了它。 答:這是某些預(yù)處理器實現(xiàn)的擴(kuò)展用于使頭文件自我識別; 它跟#ifndef技巧等價, 不過移植性差些。 |
|
來自: chuanshaoke > 《c》