關(guān)于我們
書(shū)單推薦
新書(shū)推薦
|
你必須知道的495個(gè)C語(yǔ)言問(wèn)題
《你必須知道的495個(gè)C語(yǔ)言問(wèn)題》以問(wèn)答的形式組織內(nèi)容,討論了學(xué)習(xí)或使用C語(yǔ)言的過(guò)程中經(jīng)常遇到的一些問(wèn)題。書(shū)中列出了C用戶(hù)經(jīng)常問(wèn)的400多個(gè)經(jīng)典問(wèn)題,涵蓋了初始化、數(shù)組、指針、字符串、內(nèi)存分配、庫(kù)函數(shù)、C預(yù)處理器等各個(gè)方面的主題,并分別給出了解答,而且結(jié)合代碼示例闡明要點(diǎn)。
《你必須知道的495個(gè)C語(yǔ)言問(wèn)題》結(jié)構(gòu)清晰,講解透徹,是各高校相關(guān)專(zhuān)業(yè)C語(yǔ)言課程很好的教學(xué)參考書(shū),也是各層次C程序員的實(shí)踐指南。
全球C語(yǔ)言程序員集體智慧的結(jié)晶
全五星好評(píng)圖書(shū)
解答495個(gè)常遇到的C語(yǔ)言問(wèn)題
作者Summit在本書(shū)中提供了常遇到的495個(gè)C語(yǔ)言問(wèn)題的答案。本書(shū)針對(duì)作者在Internet上廣受歡迎的C FAQ列表進(jìn)行了全面修訂,回答了400多個(gè)問(wèn)題來(lái)闡釋關(guān)鍵點(diǎn)并為程序員提供實(shí)用指導(dǎo)。對(duì)于所有的C程序員來(lái)說(shuō),本書(shū)都是頗受歡迎的參考,它提供了準(zhǔn)確的答案,有見(jiàn)地的解釋?zhuān)⑤o之以大量的代碼示例來(lái)澄清要點(diǎn)。
本書(shū)特色:
以實(shí)用、具體的方式講解C語(yǔ)言的操作手冊(cè)
針對(duì)400多個(gè)常問(wèn)到的問(wèn)題,給出了正確的答案
在實(shí)際編寫(xiě)程序時(shí)遇到的真實(shí)問(wèn)題進(jìn)行了詳細(xì)描述
針對(duì)常被誤解的問(wèn)題進(jìn)行了澄清:微妙的移植性問(wèn)題、正確的語(yǔ)言使用、系統(tǒng)特定的問(wèn)題
Steve Summit,畢業(yè)于麻省理工學(xué)院,有15年的C編程經(jīng)驗(yàn)。他在Internet上廣受尊重,并且維護(hù)著Usenet新聞組comp.lang.c的FAQ列表。他當(dāng)前從事C和UNIX的教學(xué)工作,并致力于各種C和UNIX項(xiàng)目,其重點(diǎn)是積極的可移植代碼和接口設(shè)計(jì)。
第1章 聲明和初始化 1
基本類(lèi)型 1 1.1 我該如何決定使用哪種整數(shù)類(lèi)型? 1 1.2 為什么不精確定義標(biāo)準(zhǔn)類(lèi)型的大? 2 1.3 因?yàn)镃語(yǔ)言沒(méi)有精確定義類(lèi)型的大小,所以我一般都用typedef定義int16和int32。然后根據(jù)實(shí)際的機(jī)器環(huán)境把它們定義為int、short、long等類(lèi)型。這樣看來(lái),所有的問(wèn)題都解決了,是嗎? 2 1.4 新的64位機(jī)上的64位類(lèi)型是什么樣的? 3 指針聲明 3 1.5 這樣的聲明有什么問(wèn)題?char *p1, p2; 我在使用p2的時(shí)候報(bào)錯(cuò)了!3 1.6 我想聲明一個(gè)指針,并為它分配一些空間,但卻不行。這樣的代碼有什么問(wèn)題?char *p; *p=malloc(10); 4 聲明風(fēng)格 4 1.7 怎樣聲明和定義全局變量和函數(shù)最好? 4 1.8 如何在C中實(shí)現(xiàn)不透明(抽象)數(shù)據(jù)類(lèi)型? 5 1.9 如何生成“半全局變量”,就是那種只能被部分源文件中的部分函數(shù)訪(fǎng)問(wèn)的變量? 5 存儲(chǔ)類(lèi)型 6 1.10 同一個(gè)靜態(tài)(static)函數(shù)或變量的所有聲明都必須包含static存儲(chǔ)類(lèi)型嗎? 6 1.11 extern在函數(shù)聲明中是什么意思? 6 1.12 關(guān)鍵字auto到底有什么用途? 7 類(lèi)型定義(typedef) 7 1.13 對(duì)于用戶(hù)定義類(lèi)型,typedef 和#define有什么區(qū)別? 7 1.14 我似乎不能成功定義一個(gè)鏈表。我試過(guò)typedef struct{char *item; NODEPTR next;}* NODEPTR; 但是編譯器報(bào)了錯(cuò)誤信息。難道在C語(yǔ)言中結(jié)構(gòu)不能包含指向自己的指針嗎? 7 1.15 如何定義一對(duì)相互引用的結(jié)構(gòu)? 9 1.16 Struct{ } x1;和typedef struct{ } x2; 這兩個(gè)聲明有什么區(qū)別? 10 1.17 “typedef int(*funcptr)();”是什么意思? 10 const 限定詞 10 1.18 我有這樣一組聲明:typedef char *charp; const charp p; 為什么是p而不是它指向的字符為const? 10 1.19 為什么不能像下面這樣在初始式和數(shù)組維度值中使用const值?const int n=5; int a[n]; 10 1.20 const char *p、char const *p和char *const p有什么區(qū)別? 10 復(fù)雜的聲明 11 1.21 怎樣建立和理解非常復(fù)雜的聲明?例如定義一個(gè)包含N個(gè)指向返回指向字符的指針的函數(shù)的指針的數(shù)組? 11 1.22 如何聲明返回指向同類(lèi)型函數(shù)的指針的函數(shù)?我在設(shè)計(jì)一個(gè)狀態(tài)機(jī),用函數(shù)表示每種狀態(tài),每個(gè)函數(shù)都會(huì)返回一個(gè)指向下一個(gè)狀態(tài)的函數(shù)的指針?晌艺也坏饺魏畏椒▉(lái)聲明這樣的函數(shù)——感覺(jué)我需要一個(gè)返回指針的函數(shù),返回的指針指向的又是返回指針的函數(shù)……,如此往復(fù),以至無(wú)窮!12 數(shù)組大小 13 1.23 能否聲明和傳入數(shù)組大小一致的局部數(shù)組,或者由其他參數(shù)指定大小的參數(shù)數(shù)組? 13 1.24 我在一個(gè)文件中定義了一個(gè)extern數(shù)組,然后在另一個(gè)文件中使用,為什么sizeof取不到數(shù)組的大? 13 聲明問(wèn)題 14 1.25 函數(shù)只定義了一次,調(diào)用了一次,但編譯器提示非法重聲明了!14 *1.26 main的正確定義是什么?void main正確嗎? 15 1.27 我的編譯器總在報(bào)函數(shù)原型不匹配的錯(cuò)誤,可我覺(jué)得沒(méi)什么問(wèn)題。這是為什么? 15 1.28 文件中的第一個(gè)聲明就報(bào)出奇怪的語(yǔ)法錯(cuò)誤,可我看沒(méi)什么問(wèn)題。這是為什么? 15 1.29 為什么我的編譯器不允許我定義大數(shù)組,如double array[256][256]? 15 命名空間 15 1.30 如何判斷哪些標(biāo)識(shí)符可以使用,哪些被保留了? 15 初始化 18 1.31 對(duì)于沒(méi)有顯式初始化的變量的初始值可以作怎樣的假定?如果一個(gè)全局變量初始值為“零”,它可否作為空指針或浮點(diǎn)零? 18 1.32 下面的代碼為什么不能編譯? intf(){char a[]="Hello, world!";} 18 *1.33 下面的初始化有什么問(wèn)題?編譯器提示“invalid initializers ”或其他信息。char *p=malloc(10); 19 1.34 char a[]= "string literal";和char *p="string literal"; 初始化有什么區(qū)別?當(dāng)我向p[i] 賦值的時(shí)候,我的程序崩潰了!19 1.35 char a{[3]}= "abc"; 是否合法? 20 1.36 我總算弄清楚函數(shù)指針的聲明方法了,但怎樣才能初始化呢? 20 1.37 能夠初始化聯(lián)合嗎? 20 第2章 結(jié)構(gòu)、聯(lián)合和枚舉 21 結(jié)構(gòu)聲明 21 2.1 struct x1{ };和typedef struct{ }x2; 有什么不同? 21 2.2 這樣的代碼為什么不對(duì)?struct x{ }; x thestruct; 22 2.3 結(jié)構(gòu)可以包含指向自己的指針嗎? 22 2.4 在C語(yǔ)言中用什么方法實(shí)現(xiàn)抽象數(shù)據(jù)類(lèi)型最好? 22 *2.5 在C語(yǔ)言中是否有模擬繼承等面向?qū)ο蟪绦蛟O(shè)計(jì)特性的好方法? 22 2.6 為什么聲明extern f(struct x *p); 給我報(bào)了一個(gè)晦澀難懂的警告信息? 23 2.7 我遇到這樣聲明結(jié)構(gòu)的代碼:struct name {int namelen; char namestr[1];};然后又使用一些內(nèi)存分配技巧使namestr數(shù)組用起來(lái)好像有多個(gè)元素,namelen記錄了元素個(gè)數(shù)。它是怎樣工作的?這樣是合法的和可移植的嗎? 23 2.8 我聽(tīng)說(shuō)結(jié)構(gòu)可以賦給變量也可以對(duì)函數(shù)傳入和傳出。為什么K&R1卻明確說(shuō)明不能這樣做? 25 2.9 為什么不能用內(nèi)建的==和!=操作符比較結(jié)構(gòu)? 26 2.10 結(jié)構(gòu)傳遞和返回是如何實(shí)現(xiàn)的? 26 2.11 如何向接受結(jié)構(gòu)參數(shù)的函數(shù)傳入常量值?怎樣創(chuàng)建無(wú)名的中間的常量結(jié)構(gòu)值? 26 2.12 怎樣從/向數(shù)據(jù)文件讀/寫(xiě)結(jié)構(gòu)? 27 結(jié)構(gòu)填充 27 2.13 為什么我的編譯器在結(jié)構(gòu)中留下了空洞?這導(dǎo)致空間浪費(fèi)而且無(wú)法與外部數(shù)據(jù)文件進(jìn)行“二進(jìn)制”讀寫(xiě)。能否關(guān)掉填充,或者控制結(jié)構(gòu)域的對(duì)齊方式? 27 2.14 為什么sizeof返回的值大于結(jié)構(gòu)大小的期望值,是不是尾部有填充? 28 2.15 如何確定域在結(jié)構(gòu)中的字節(jié)偏移量? 28 2.16 怎樣在運(yùn)行時(shí)用名字訪(fǎng)問(wèn)結(jié)構(gòu)中的域? 29 2.17 C語(yǔ)言中有和Pascal的with等價(jià)的語(yǔ)句嗎? 29 2.18 既然數(shù)組名可以用作數(shù)組的基地址,為什么對(duì)結(jié)構(gòu)不能這樣? 29 2.19 程序運(yùn)行正確,但退出時(shí)卻“core dump ”(核心轉(zhuǎn)儲(chǔ))了,怎么回事? 29 聯(lián)合 30 2.20 結(jié)構(gòu)和聯(lián)合有什么區(qū)別? 30 2.21 有辦法初始化聯(lián)合嗎? 30 2.22 有沒(méi)有一種自動(dòng)方法來(lái)跟蹤聯(lián)合的哪個(gè)域在使用? 30 枚舉 31 2.23 枚舉和一組預(yù)處理的#define有什么不同? 31 2.24 枚舉可移植嗎? 31 2.25 有什么顯示枚舉值符號(hào)的容易方法嗎? 31 位域 31 2.26 一些結(jié)構(gòu)聲明中的這些冒號(hào)和數(shù)字是什么意思? 31 2.27 為什么人們那么喜歡用顯式的掩碼和位操作而不直接聲明位域? 32 第3章 表達(dá)式 33 求值順序 33 3.1 為什么這樣的代碼不行?a[i]= i++; 33 3.2 使用我的編譯器,下面的代碼int i= 7; printf("%d\n", i++ * i++); 打印出49。不管按什么順序計(jì)算,難道不該是56嗎? 33 3.3 對(duì)于代碼int i=3; i=i++; 不同編譯器給出不同的i值,有的為3,有的為4,哪個(gè)是正確的? 34 *3.4 有這樣一個(gè)巧妙的表達(dá)式:a^= b^= a^= b; 它不需要臨時(shí)變量就可以交換a和b的值!34 3.5 可否用顯式括號(hào)來(lái)強(qiáng)制執(zhí)行我所需要的計(jì)算順序并控制相關(guān)的副作用?就算括號(hào)不行,操作符優(yōu)先級(jí)是否能夠控制計(jì)算順序呢? 35 3.6 可是&&和||操作符呢?我看到過(guò)類(lèi)似while((c = getchar()) != EOF && c != '\n')的代碼…… 35 3.7 是否可以安全地認(rèn)為,一旦&&和||左邊的表達(dá)式已經(jīng)決定了整個(gè)表達(dá)式的結(jié)果,則右邊的表達(dá)式不會(huì)被求值? 36 3.8 為什么表達(dá)式printf("%d %d", f1(), f2()); 先調(diào)用了f2?我覺(jué)得逗號(hào)表達(dá)式應(yīng)該確保從左到右的求值順序!36 3.9 怎樣才能理解復(fù)雜表達(dá)式并避免寫(xiě)出未定義的表達(dá)式?“序列點(diǎn)”是什么? 36 3.10 在a[i] = i++;中,如果不關(guān)心a[]的哪一個(gè)分量會(huì)被寫(xiě)入,這段代碼就沒(méi)有問(wèn)題,i也的確會(huì)增加1,對(duì)嗎? 38 3.11 人們總是說(shuō)i=i++的行為是未定義的?晌覄倓傇谝粋(gè)ANSI編譯器上嘗試過(guò),其結(jié)果正如我所期望的!38 3.12 我不想學(xué)習(xí)那些復(fù)雜的規(guī)則,怎樣才能避免這些未定義的求值順序問(wèn)題呢? 38 其他的表達(dá)式問(wèn)題 39 *3.13 ++i和i++有什么區(qū)別? 39 3.14 如果我不使用表達(dá)式的值,那我應(yīng)該用i++還是++i來(lái)做自增呢? 39 3.15 我要檢查一個(gè)數(shù)是不是在另外兩個(gè)數(shù)之間,為什么if(a b c)不行? 40 3.16 為什么如下的代碼不對(duì)?int a=1000, b=1000; long int c=a * b; 40 3.17 為什么下面的代碼總是給出0?double degC, degF; degC= 5.0 / 9 * (degF - 32); 40 3.18 需要根據(jù)條件把一個(gè)復(fù)雜的表達(dá)式賦給兩個(gè)變量中的一個(gè)。可以用下面這樣的代碼嗎?((condition) ? a : b)= complicated_expression; 41 3.19 我有些代碼包含這樣的表達(dá)式。a ? b=c : d 有些編譯器可以接受,有些卻不能。為什么? 41 保護(hù)規(guī)則 42 3.20 “semantics of‘’change in ANSI C”的警告是什么意思? 42 3.21 “無(wú)符號(hào)保護(hù)”和“值保護(hù)”規(guī)則的區(qū)別在哪里? 42 第4章 指針 45 基本的指針應(yīng)用 45 4.1 指針到底有什么好處? 45 4.2 我想聲明一個(gè)指針并為它分配一些空間,但卻不行。這些代碼有什么問(wèn)題呢?char *p; *p =malloc(10); 45 4.3 *p++自增p還是p所指向的變量? 46 指針操作 46 4.4 我用指針操作int數(shù)組的時(shí)候遇到了麻煩!46 4.5 我有一個(gè)char *型指針碰巧指向一些int型變量,我想跳過(guò)它們。為什么((int *)p)++; 這樣的代碼不行? 47 4.6 為什么不能對(duì)void *指針進(jìn)行算術(shù)操作? 47 4.7 我有些解析外部結(jié)構(gòu)的代碼,但是它卻崩潰了,顯示出了“unaligned access”(未對(duì)齊的訪(fǎng)問(wèn))的信息。這是什么意思? 47 作為函數(shù)參數(shù)的指針 47 4.8 我有個(gè)函數(shù),它應(yīng)該接受并初始化一個(gè)指針:void f(int *ip){ static int dummy = 5; ip = &dummy;}但是當(dāng)我如下調(diào)用時(shí):int *ip; f(ip); 調(diào)用者的指針沒(méi)有任何變化。 47 4.9 能否用void ** 通用指針作為參數(shù),使函數(shù)模擬按引用傳遞參數(shù)? 48 4.10 我有一個(gè)函數(shù)extern intf(int *); ,它接受指向int型的指針。我怎樣用引用方式傳入一個(gè)常數(shù)?調(diào)用f(&5);似乎不行!49 4.11 C語(yǔ)言可以“按引用傳參”嗎? 50 其他指針問(wèn)題 50 4.12 我看到了用指針調(diào)用函數(shù)的不同語(yǔ)法形式。到底怎么回事? 50 4.13 通用指針類(lèi)型是什么?當(dāng)我把函數(shù)指針賦向void *類(lèi)型的時(shí)候,編譯通不過(guò)!51 4.14 怎樣在整型和指針之間進(jìn)行轉(zhuǎn)換?能否暫時(shí)把整數(shù)放入指針變量中,或者相反? 51 *4.15 我怎樣把一個(gè)int變量轉(zhuǎn)換為char *型?我試了類(lèi)型轉(zhuǎn)換,但是不行!52 第5章 空指針 53 空指針和空指針常量 53 5.1 臭名昭著的空指針到底是什么? 53 5.2 怎樣在程序里獲得一個(gè)空指針? 54 5.3 用縮寫(xiě)的指針比較“if(p)”檢查空指針是否有效?如果空指針的內(nèi)部表達(dá)不是0會(huì)怎樣? 55 NULL 宏 56 5.4 NULL是什么,它是怎么定義的? 56 5.5 在使用非零位模式作為空指針的內(nèi)部表示的機(jī)器上,NULL 是如何定義的? 56 5.6 如果NULL定義成#define NULL((char *)0) ,不就可以向函數(shù)傳入不加轉(zhuǎn)換的NULL 了嗎? 57 5.7 我的編譯器提供的頭文件中定義的NULL為0L。為什么? 57 5.8 NULL可以合法地用作函數(shù)指針嗎? 57 5.9 如果NULL和0作為空指針常量是等價(jià)的,那我到底該用哪一個(gè)呢? 58 5.10 但是如果NULL的值改變了,比如在使用非零內(nèi)部空指針的機(jī)器上,用NULL(而不是0) 不是更好嗎? 58 5.11 我曾經(jīng)使用過(guò)一個(gè)編譯器,不使用NULL就不能編譯!58 5.12 我用預(yù)處理宏#define Nullptr(type)(type *)0幫助創(chuàng)建正確類(lèi)型的空指針!59 回顧 59 5.13 這有點(diǎn)奇怪:NULL可以確保是0,但空(null)指針卻不一定? 59 5.14 為什么有那么多關(guān)于空指針的疑惑?為什么這些問(wèn)題如此頻繁地出現(xiàn)? 60 5.15 有沒(méi)有什么簡(jiǎn)單點(diǎn)兒的辦法理解所有這些與空指針有關(guān)的東西呢? 60 5.16 考慮到有關(guān)空指針的所有這些困惑,要求它們的內(nèi)部表示都必須為0不是更簡(jiǎn)單嗎? 60 5.17 說(shuō)真的,真有機(jī)器用非零空指針嗎,或者不同類(lèi)型用不同的表示? 61 地址0 上到底有什么? 61 5.18 運(yùn)行時(shí)的整數(shù)值0轉(zhuǎn)換為指針以后一定是空指針嗎? 61 5.19 如何訪(fǎng)問(wèn)位于機(jī)器地址0處的中斷向量?如果我將指針值設(shè)為0,編譯器可能會(huì)自動(dòng)將它轉(zhuǎn)換為非零的空指針內(nèi)部表示。 62 5.20 運(yùn)行時(shí)的“null pointer assignment”錯(cuò)誤是什么意思?應(yīng)該怎樣捕捉它? 62 第6章 數(shù)組和指針 63 數(shù)組和指針的基本關(guān)系 63 6.1 我在一個(gè)源文件中定義了char a[6],在另一個(gè)源文件中聲明了extern char *a。為什么不行? 63 6.2 可是我聽(tīng)說(shuō)char a[]和char *a是等價(jià)的。是這樣的嗎? 63 6.3 那么,在C語(yǔ)言中“指針和數(shù)組等價(jià)”到底是什么意思? 64 6.4 既然它們這么不同,那為什么作為函數(shù)形參的數(shù)組和指針聲明可以互換呢? 65 數(shù)組不能被賦值 66 6.5 為什么不能這樣向數(shù)組賦值?extern char *getpass(); char str[10]; str=getpass("Enter password:"); 66 6.6 既然不能向數(shù)組賦值,那這段代碼為什么可以呢?int f(char str[]){ if(str[0] == '\0') str="none";…} 66 6.7 如果你不能給它賦值,那么數(shù)組如何能成為左值呢? 66 回顧 67 6.8 現(xiàn)實(shí)地講,數(shù)組和指針的區(qū)別是什么? 67 6.9 有人跟我講,數(shù)組不過(guò)是常指針。這樣講準(zhǔn)確嗎? 67 6.10 我還是很困惑。到底指針是一種數(shù)組,還是數(shù)組是一種指針? 67 6.11 我看到一些“搞笑”的代碼,包含5["abcdef"]這樣的“表達(dá)式”。這為什么是合法的C語(yǔ)言表達(dá)式呢? 68 數(shù)組的指針 68 6.12 既然數(shù)組引用會(huì)退化為指針,如果array是數(shù)組,那么array和&array又有什么區(qū)別呢? 68 6.13 如何聲明一個(gè)數(shù)組的指針? 69 動(dòng)態(tài)數(shù)組分配 70 6.14 如何在運(yùn)行時(shí)設(shè)定數(shù)組的大?怎樣才能避免固定大小的數(shù)組? 70 6.15 我如何聲明大小和傳入的數(shù)組一樣的局部數(shù)組? 70 6.16 如何動(dòng)態(tài)分配多維數(shù)組? 71 6.17 有個(gè)很好的竅門(mén),如果我這樣寫(xiě):int realarray[10]; int *array = &realarray[-1]; 我就可以把“array”當(dāng)作下標(biāo)從1 開(kāi)始的數(shù)組!72 函數(shù)和多維數(shù)組 73 6.18 當(dāng)我向一個(gè)接受指針的指針的函數(shù)傳入二維數(shù)組的時(shí)候,編譯器報(bào)錯(cuò)了!73 6.19 我怎樣編寫(xiě)接受編譯時(shí)寬度未知的二維數(shù)組的函數(shù)? 74 6.20 我怎樣在函數(shù)參數(shù)傳遞時(shí)混用靜態(tài)和動(dòng)態(tài)多維數(shù)組? 74 數(shù)組的大小 75 6.21 當(dāng)數(shù)組是函數(shù)的參數(shù)時(shí),為什么sizeof不能正確報(bào)告數(shù)組的大? 76 6.22 如何在一個(gè)文件中判斷聲明為extern的數(shù)組的大小(例如,數(shù)組定義和大小在另一個(gè)文件中)?sizeof操作符似乎不行。 76 6.23 sizeof返回的大小是以字節(jié)計(jì)算的,怎樣才能判斷數(shù)組中有多少個(gè)元素呢? 76 第7 章 內(nèi)存分配 77 基本的內(nèi)存分配問(wèn)題 77 7.1 為什么這段代碼不行?char *answer; printf("Type something:\n"); gets(answer); printf("You typed \"%s\"\n", answer); 77 7.2 我的strcat() 不行。我試了下面的代碼:char *s1= "Hello,"; char *s2= "world!"; char *s3= strcat(s1, s2);但是我得到了奇怪的結(jié)果!78 7.3 但是strcat的文檔說(shuō)它接受兩個(gè)char *型參數(shù)。我怎么知道(空間)分配的事情呢? 78 *7.4 我剛才試了這樣的代碼:char *p; strcpy(p, "abc");它運(yùn)行正常。怎么回事?為什么它沒(méi)有出錯(cuò)? 79 *7.5 一個(gè)指針變量分配多少內(nèi)存? 79 7.6 我使用fgets將文件的所有行讀入一個(gè)數(shù)組,為什么讀入的每一行都是最后一行的內(nèi)容呢? 79 7.7 我有個(gè)函數(shù),本該返回一個(gè)字符串,但當(dāng)它返回調(diào)用者的時(shí)候,返回的字符串卻是垃圾信息。 為什么? 80 *7.8 那么返回字符串或其他聚集的正確方法是什么呢? 81 調(diào)用malloc 81 7.9 為什么在調(diào)用malloc()時(shí)報(bào)出了“waring: assignment of pointer from integer lacks a cast”? 81 7.10 為什么有些代碼小心翼翼地把malloc返回的值轉(zhuǎn)換為分配的指針類(lèi)型? 81 *7.11 在調(diào)用malloc()的時(shí)候,錯(cuò)誤“不能把void * 轉(zhuǎn)換為int * ”是什么意思? 82 7.12 我看到下面這樣的代碼:char *p = malloc(strlen(s) + 1); strcpy(p,s); 難道不應(yīng)該是malloc ((strlen(s) + 1) * sizeof(char)) 嗎? 82 7.13 我為malloc寫(xiě)了一個(gè)小小的封裝函數(shù)。它為什么不行? 82 7.14 我想聲明一個(gè)指針并向它分配一些內(nèi)存,但是不行。這樣的代碼有什么問(wèn)題?char *p; *p = malloc(10); 82 7.15 我如何動(dòng)態(tài)分配數(shù)組? 83 7.16 怎樣判斷還有多少內(nèi)存? 83 7.17 malloc(0)是返回空指針還是指向0個(gè)字節(jié)的指針? 83 7.18 我聽(tīng)說(shuō)有的操作系統(tǒng)在程序使用的時(shí)候才真正分配malloc申請(qǐng)的內(nèi)存。這合法嗎? 83 有關(guān)malloc 的問(wèn)題 83 7.19 為什么malloc返回了離譜的指針值?我的確讀過(guò)問(wèn)題7.9,而且也在調(diào)用之前包含了extern void *malloc();聲明。 83 7.20 我用一行這樣的代碼分配一個(gè)巨大的數(shù)組,用于數(shù)值運(yùn)算:double *array = malloc (256 *256 *sizeof(double));malloc()并沒(méi)有返回空指針,但是程序運(yùn)行得有些奇怪,好像改寫(xiě)了某些內(nèi)存,或者malloc()并沒(méi)有分配我申請(qǐng)的那么多內(nèi)存。為什么? 84 7.21 我的PC機(jī)有8兆內(nèi)存。為什么我只能分配640K左右的內(nèi)存? 84 7.22 我的應(yīng)用程序非常依賴(lài)數(shù)據(jù)結(jié)構(gòu)的節(jié)點(diǎn)的動(dòng)態(tài)分配,而malloc/free的代價(jià)成了瓶頸。我該怎么做? 84 7.23 我的程序總是崩潰,顯然發(fā)生在malloc內(nèi)部的某個(gè)地方。但是我看不出哪里有問(wèn)題。是malloc有bug嗎? 84 釋放內(nèi)存 85 7.24 動(dòng)態(tài)分配的內(nèi)存一旦釋放之后就不能再使用,是吧? 85 7.25 為什么在調(diào)用free()之后指針沒(méi)有變空?使用(賦值、比較)釋放之后的指針有多么不安全? 86 7.26 當(dāng)我調(diào)用malloc()為一個(gè)函數(shù)的局部指針?lè)峙鋬?nèi)存時(shí),我還需要用free()顯式地釋放嗎? 86 7.27 我在分配一些結(jié)構(gòu),它們包含指向其他動(dòng)態(tài)分配的對(duì)象的指針。我在釋放結(jié)構(gòu)的時(shí)候,還需要釋放每一個(gè)下級(jí)指針嗎? 86 7.28 我必須在程序退出之前釋放分配的所有內(nèi)存嗎? 86 7.29 我有個(gè)程序分配了大量的內(nèi)存,然后又釋放了。但是從操作系統(tǒng)看,內(nèi)存的占用率卻并沒(méi)有變回去!87 分配內(nèi)存塊的大小 87 7.30 free()怎么知道有多少字節(jié)需要釋放? 87 7.31 那么我能否查詢(xún)malloc包,以查明可分配的最大塊是多大? 87 7.32 為什么sizeof不能告訴我它所指的內(nèi)存塊的大。俊87 其他分配函數(shù) 88 7.33 (像問(wèn)題6.14中那樣)動(dòng)態(tài)分配數(shù)組之后,還能改變它的大小嗎? 88 7.34 向realloc()的第一個(gè)參數(shù)傳入空指針合法嗎?你為什么要這樣做? 89 7.35 calloc()和malloc()有什么區(qū)別?應(yīng)該用哪一個(gè)?利用calloc 的零填充功能安全嗎?free()可以釋放calloc()分配的內(nèi)存嗎,還是需要一個(gè)cfree()? 90 7.36 alloca是什么?為什么不提倡使用它? 91 第8章 字符和字符串 92 8.1 為什么strcat(string, '!'); 不行? 92 8.2 我想檢查一個(gè)字符串是否跟某個(gè)值匹配。為什么這樣不行?if(string == "value") 92 8.3 如果我可以寫(xiě)char a[] = "Hello, world!"; 那為什么不能寫(xiě)char a[14]; a = "Hello, world!"; 93 8.4 為什么我的strcat 不行?我試了char *s1="Hello,"; char *s2="world!"; char *s3 =strcat(s1, s2);可得到的結(jié)果很奇怪!93 8.5 char a[]= "string literal"; 和char *p= "string literal"; 初始化有什么區(qū)別?當(dāng)我對(duì)p[i]賦值的時(shí)候,程序崩潰了!93 8.6 我怎么得到與字符相對(duì)應(yīng)的數(shù)字(即ASCII 或其他字符集下的)值?反過(guò)來(lái)又該怎么做? 94 8.7 C語(yǔ)言有類(lèi)似其他語(yǔ)言的"substr"(提取子串)這樣的函數(shù)嗎? 94 8.8 我將用戶(hù)鍵入的字符串讀入數(shù)組,然后再顯示出來(lái)。當(dāng)用戶(hù)鍵入\n這樣的序列時(shí),為什么不能正確處理呢? 94 8.9 我注意到sizeof('a')是2而不是1(即不是sizeof(char)),是不是我的編譯器有問(wèn)題? 94 8.10 我正開(kāi)始考慮多語(yǔ)言字符集的問(wèn)題。是否有必要擔(dān)心sizeof(char)會(huì)被定義為2,以便表達(dá)16位的字符集呢? 95 第9章 布爾表達(dá)式和變量 96 9.1 C語(yǔ)言中布爾值該用什么類(lèi)型?為什么它不是一個(gè)標(biāo)準(zhǔn)類(lèi)型?我應(yīng)該用#define或enum定義真值和假值嗎? 96 9.2 既然在C 語(yǔ)言中所有的非零值都被看作“真”,那是不是把TRUE 定義為1很危險(xiǎn)?如果某個(gè)內(nèi)建的函數(shù)或關(guān)系操作符“返回”不是1的其他值怎么辦? 97 9.3 當(dāng)p是指針時(shí),if(p)是合法的條件表達(dá)式嗎? 98 9.4 我該使用像TRUE和FALSE這樣的符號(hào)名稱(chēng)還是直接用1和0來(lái)作布爾常量? 98 9.5 我準(zhǔn)備使用的一個(gè)第三方頭文件定義了自己的TRUE和FALSE,它們跟我已經(jīng)開(kāi)發(fā)的部分不兼容。我該怎么辦? 98 第10章 C預(yù)處理器 99 宏定義 99 10.1 我想定義一些函數(shù)式的宏,例如:#define square(x)x * x但它們并不總是正確的。為什么? 99 10.2 這里有一些的預(yù)處理宏,使用它們,我可以寫(xiě)出更像Pascal的C代碼。你覺(jué)得怎么樣? 100 10.3 怎么寫(xiě)一個(gè)交換兩個(gè)值的通用宏? 101 10.4 書(shū)寫(xiě)多語(yǔ)句宏的最好方法是什么? 101 10.5 用typdef和預(yù)處理宏生成用戶(hù)定義類(lèi)型有什么區(qū)別? 102 頭文件 102 10.6 我第一次把一個(gè)程序分成多個(gè)源文件,我不知道該把什么放到.c文件,把什么放到.h文件。(“.h”到底是什么意思?) 102 10.7 可以在一個(gè)頭文件中包含另一頭文件嗎? 103 10.8 完整的頭文件搜索規(guī)則是怎樣的? 104 10.9 我在文件的第一個(gè)聲明就遇到奇怪的語(yǔ)法錯(cuò)誤,但是看上去沒(méi)什么問(wèn)題。 104 10.10 我使用了來(lái)自?xún)蓚(gè)不同的第三方庫(kù)的頭文件,它們都定義了相同的宏,如TRUE、FALSE、Min()和Max()等,但是它們的定義相互沖突,而且跟我在自己的頭文件中的定義也有沖突。我該怎么辦? 104 10.11 我在編譯一個(gè)程序,看起來(lái)我好像缺少需要的一個(gè)或多個(gè)頭文件。誰(shuí)能發(fā)給我一份? 105 條件編譯 105 10.12 怎樣構(gòu)造比較字符串的#if預(yù)處理表達(dá)式? 105 10.13 sizeof操作符可以用在#if預(yù)處理指令中嗎? 106 10.14 我可以像這樣在#define行里使用#ifdef來(lái)定義兩個(gè)不同的東西嗎? 106 10.15 對(duì)typedef的類(lèi)型定義有沒(méi)有類(lèi)似#ifdef的東西? 106 10.16 我如何用#if表達(dá)式來(lái)判斷機(jī)器是高字節(jié)在前還是低字節(jié)在前? 107 10.17 為什么在我用#ifdef關(guān)掉的代碼行中報(bào)出了奇怪的語(yǔ)法錯(cuò)誤? 107 10.18 我拿到了一些代碼,里邊有太多的#ifdef。我不想使用預(yù)處理器把所有的#include 和#ifdef都擴(kuò)展開(kāi),有什么辦法只保留一種條件的代碼呢? 107 10.19 如何列出所有的預(yù)定義宏? 107 奇異的處理 108 10.20 我有些舊代碼,試圖用這樣的宏來(lái)構(gòu)造標(biāo)識(shí)符:#define Paste(a, b) a/**/b 但是現(xiàn)在不行了。為什么? 108 10.21 我有一個(gè)舊宏:#define CTRL(c) ('c' & 037)現(xiàn)在不能用了。為什么? 108 10.22 為什么宏#define TRACE(n) printf("TRACE: \%d\n", n) 報(bào)出警告“macro replacement within a string literal ”?它似乎把TRACE(count);擴(kuò)展成了printf("TRACE: \%d\count", count); 109 10.23 如何在宏擴(kuò)展的字符串字面量中使用宏參數(shù)? 109 10.24 我想用ANSI 的“字符串化”預(yù)處理操作符#將符號(hào)常量的值放入消息中,但它總是對(duì)宏名稱(chēng)而不是它的值進(jìn)行字符串化。這是什么原因? 109 10.25 我想用預(yù)處理器做某件事情,但卻不知道如何下手!110 可變參數(shù)列表的宏 110 10.26 怎樣寫(xiě)可變參數(shù)宏?如何用預(yù)處理器“關(guān)掉”具有可變參數(shù)的函數(shù)調(diào)用? 110 10.27 如何在通用的調(diào)試宏中包含__FILE__和__LINE__宏? 111 第11章 ANSI/ISO標(biāo)準(zhǔn)C 113 標(biāo)準(zhǔn) 113 11.1 什么是“ANSI C標(biāo)準(zhǔn)”? 113 11.2 如何得到一份標(biāo)準(zhǔn)的副本? 114 *11.3 我在哪里可以找到標(biāo)準(zhǔn)的更新? 115 函數(shù)原型 115 11.4 為什么我的ANSI編譯器對(duì)用float聲明的參數(shù)會(huì)警告類(lèi)型不匹配? 115 11.5 能否混用舊式的和新型的函數(shù)語(yǔ)法? 116 *11.6 為什么下述聲明報(bào)出了一個(gè)奇怪的警告信息“Struct X declared inside parameter list”? extern int f(struct x *p); 116 11.7 有個(gè)問(wèn)題一直困擾著我,它是由這一行printf ("%d", n); 導(dǎo)致的,因?yàn)閚是個(gè)long int型。難道 ANSI 的函數(shù)原型不能檢查這種函數(shù)的參數(shù)不匹配問(wèn)題嗎? 116 11.8 我聽(tīng)說(shuō)必須在調(diào)用printf之前包含stdio.h。為什么? 117 const 限定詞 117 11.9 為什么不能在初始化和數(shù)組維度中使用const值?例如const int n = 5; int a[n]; 117 11.10 “const char *p”、“char const *p ”和“char * const p ”有何區(qū)別? 117 11.11 為什么不能向接受const char ** 的函數(shù)傳入char **? 118 11.12 我這樣聲明:typedef char * charp; const charp p; 為什么是p而不是它所指向的字符為const? 118 main()函數(shù)的使用 119 11.13 能否通過(guò)將main聲明為void來(lái)關(guān)掉“main沒(méi)有返回值”的警告? 119 11.14 main()的第3個(gè)參數(shù)envp是怎么回事? 120 11.15 我覺(jué)得把main()聲明為void也不會(huì)失敗,因?yàn)槲艺{(diào)用了exit()而不是return,況且我的操作系統(tǒng)也忽略了程序的退出/返回狀態(tài)!120 *11.16 那么到底會(huì)出什么問(wèn)題?真的有什么系統(tǒng)不支持void main()嗎? 120 11.17 為什么以前流行的那些C 語(yǔ)言書(shū)總是使用void main()? 120 11.18 在main()中調(diào)用exit(status)和返回同樣的status真的等價(jià)嗎? 121 預(yù)處理功能 121 11.19 我試圖用ANSI“字符串化”預(yù)處理操作符'#'向信息中插入符號(hào)常量的值,但它字符串化的總是宏的名字而不是它的值。為什么? 121 11.20 警告信息“warning: macro replacement within a string literal”是什么意思? 121 11.21 為什么在我用#ifdef去掉的代碼里出現(xiàn)了奇怪的語(yǔ)法錯(cuò)誤? 122 11.22 #pragma是什么,有什么用? 122 11.23 “#pragma once”什么意思?我在一些頭文件中看到了它!122 其他的ANSI C 問(wèn)題 123 11.24 char a[3] = "abc";合法嗎?它是什么意思? 123 11.25 既然對(duì)數(shù)組的引用會(huì)退化為指針,那么,如果array是數(shù)組,array和&array之間有什么區(qū)別呢? 123 11.26 為什么我不能對(duì)void *指針進(jìn)行算術(shù)運(yùn)算? 123 11.27 memcpy()和memmove() 有什么區(qū)別? 124 11.28 malloc(0)有什么用?返回一個(gè)空指針還是指向0字節(jié)的指針? 124 11.29 為什么ANSI 標(biāo)準(zhǔn)規(guī)定了外部標(biāo)識(shí)符的長(zhǎng)度和大小寫(xiě)限制? 125 11.30 noalias是怎么回事?在它身上發(fā)生了什么? 125 老的或非標(biāo)準(zhǔn)的編譯器 125 11.31 為什么我的編譯器對(duì)最簡(jiǎn)單的測(cè)試程序都報(bào)出了一大堆的語(yǔ)法錯(cuò)誤?對(duì)這段代碼的第一行就報(bào)錯(cuò)了:main(int argc. char **argv) { return0; } 125 11.32 為什么有些 ASNI/ISO 標(biāo)準(zhǔn)庫(kù)函數(shù)未定義?我明明使用的就是ANSI 編譯器。 126 11.33 誰(shuí)有可以在舊的C 程序和ANSI C 之間相互轉(zhuǎn)換的工具,或者自動(dòng)生成原型的工具? 127 11.34 為什么聲稱(chēng)兼容ANSI 的編譯器不能編譯這些代碼?我知道這些代碼是 ANSI 的,因?yàn)間cc 可以編譯!127 兼容性 127 11.35 人們好像有些在意實(shí)現(xiàn)定義的(implementation-defined)、不確定的(unspecified)和未定義的(undefined) 行為的區(qū)別。它們的區(qū)別到底在哪里? 128 *11.36 一個(gè)程序“合法(legal)”、“有效(valid)”或“符合標(biāo)準(zhǔn)的”(conforming )到底是什么意思? 128 11.37 我很吃驚,ANSI 標(biāo)準(zhǔn)竟然有那么多未定義的東西。標(biāo)準(zhǔn)的唯一任務(wù)不就是讓這些東西標(biāo)準(zhǔn)化嗎? 129 11.38 有人說(shuō)i=i++的行為是未定義的,但是我剛在一個(gè)兼容ANSI 的編譯器上測(cè)試,得到了我希望的結(jié)果。它真的是未定義的嗎? 129 第12章 標(biāo)準(zhǔn)輸入輸出庫(kù) 130 基本輸入輸出 130 12.1 這樣的代碼有什么問(wèn)題?char c; while((c = getchar()) != EOF) 130 12.2 我有個(gè)讀取直到EOF的簡(jiǎn)單程序,但是我如何才能在鍵盤(pán)上輸入那個(gè)“\EOF”呢?我看stdio.h 中定義的EOF 是-1,是不是說(shuō)我該輸入-1? 131 12.3 為什么這些代碼把最后一行復(fù)制了兩遍?while(!feof(infp)){fgets(buf, MAXLINE, infp); fputs(buf, outfp);} 131 12.4 我用fgets將文件的每行內(nèi)容讀入指針數(shù)組。為什么結(jié)果所有的行都是最后一行的內(nèi)容呢? 132 12.5 我的程序的屏幕提示和中間輸出有時(shí)沒(méi)有在屏幕上顯示,尤其是當(dāng)我用管道通過(guò)另一個(gè)程序輸出的時(shí)候。為什么? 132 12.6 我怎樣才能不等待回車(chē)鍵而一次輸入一個(gè)字符? 132 printf格式 132 12.7 如何在printf 的格式串中輸出一個(gè)'%'字符?我試過(guò)\%,但是不行。 132 12.8 為什么這么寫(xiě)不對(duì)?long int n = 123456; printf("%d\n", n); 133 12.9 有人告訴我不能在printf 中使用%lf。為什么printf() 用%f輸出double 型,而scanf 卻用%lf 呢? 133 *12.10 對(duì)于size_t 那樣的類(lèi)型定義,當(dāng)我不知道它到底是long 還是其他類(lèi)型的時(shí)候,我應(yīng)該使用什么樣的printf格式呢? 134 12.11 如何用printf 實(shí)現(xiàn)可變的域?qū)挾?就是說(shuō),我想在運(yùn)行時(shí)確定寬度而不是使用%8d? 134 12.12 如何輸出在千位上用逗號(hào)隔開(kāi)的數(shù)字?貨幣格式的數(shù)字呢? 135 12.13 為什么scanf("%d", i) 調(diào)用不行? 136 *12.14 為什么char s[30]; scamf("%s", s); 不用&也可以?我原以為傳給scanf的每個(gè)變量都要帶&。 136 12.15 為什么這些代碼不行?double d; scanf("%f", &d); 136 12.16 為什么這段代碼不行?short int s; scanf("%d", &s); 136 12.17 怎樣在scanf 格式串中指定可變的寬度? 136 12.18 怎樣從特定格式的數(shù)據(jù)文件中讀取數(shù)據(jù)?怎樣讀入10個(gè)float 而不用使用包含10次%f的奇怪格式?如何將一行的任意多個(gè)域讀入一個(gè)數(shù)組中? 137 scanf問(wèn)題 138 12.19 我像這樣用"%d\n"調(diào)用scanf 從鍵盤(pán)讀取數(shù)字:int n; scanf("%d\n",&n); printf("you typed %d\ n", n);好像要多輸入一行才返回。為什么? 138 12.20 我用scanf 和%d讀取一個(gè)數(shù)字,然后再用gets() 讀取字符串,但是編譯器好像跳過(guò)了gets() 調(diào)用! 139 12.21 我發(fā)現(xiàn)如果堅(jiān)持檢查返回值以確保用戶(hù)輸入的是我期待的數(shù)值,則scanf 的使用會(huì)安全很多。但有的時(shí)候好像會(huì)陷入無(wú)限循環(huán)。為什么? 139 12.22 為什么大家都說(shuō)不要使用scanf?那我該用什么來(lái)代替呢? 140 其他stdio 函數(shù) 141 12.23 我怎樣才知道對(duì)于任意的sprintf 調(diào)用需要多大的目標(biāo)緩沖區(qū)?怎樣才能避免sprintf 目標(biāo)緩沖區(qū)溢出? 141 12.24 sprintf的返回值是什么?是int 還是char *? 142 12.25 為什么大家都說(shuō)不要使用gets? 142 12.26 我覺(jué)得我應(yīng)該在一長(zhǎng)串的printf 調(diào)用之后檢查errno ,以確定是否有失敗的調(diào)用。為什么當(dāng)我將輸出重定向到文件的時(shí)候會(huì)輸出奇怪的“printf failed: Not a typewriter ”信息? 142 12.27 fgetops/fsetops和ftell/fseek之間有什么區(qū)別?fgetops和fsetops 到底有什么用處? 143 12.28 如何清除用戶(hù)的多余輸入,以防止在下一個(gè)提示符下讀入?用fflush(stdin) 可以嗎? 143 打開(kāi)和操作文件 144 12.29 我寫(xiě)了一個(gè)函數(shù)用來(lái)打開(kāi)文件:myfopen(char *filename, FILE *fp){fp = fopen(filename, "r");}可我這樣調(diào)用的時(shí)候:FILE *infp; myfopen("filename.dat", infp);,infp 指針并 沒(méi)有正確設(shè)置。為什么? 144 12.30 連一個(gè)最簡(jiǎn)單的fopen調(diào)用都不成功!這個(gè)調(diào)用有什么問(wèn)題?FILE *fp = fopen(filename, 'r'); 145 12.31 為什么我不能用完整路徑名打開(kāi)一個(gè)文件?這個(gè)調(diào)用總是失敗:fopen("c:\newdir\ file. dat", "r"); 145 12.32 我想用fopen模式"r+"打開(kāi)一個(gè)文件,讀出一個(gè)字符串,修改之后再寫(xiě)入,從而就地更新一個(gè)文件。可是這樣不行。為什么? 145 12.33 如何在文件中間插入或刪除一行(一條記錄)? 145 12.34 怎樣從打開(kāi)的流中恢復(fù)文件名? 145 重定向stdin 和stdout 146 12.35 怎樣在程序里把stdin或stdout重定向到文件? 146 12.36 一旦使用freopen之后,怎樣才能恢復(fù)原來(lái)的stdout (或stdin)? 146 12.37 如何判斷標(biāo)準(zhǔn)輸入或輸出是否經(jīng)過(guò)了重定向,即是否在命令行上使用了“”或“”? 147 12.38 我想寫(xiě)個(gè)像"more"那樣的程序。怎樣才能在stdin 被重定向之后再回到交互鍵盤(pán)? 147 *12.39 怎樣同時(shí)向兩個(gè)地方輸出,如同時(shí)輸出到屏幕和文件? 147 “二進(jìn)制”輸入輸出 148 12.40 我希望按字節(jié)在內(nèi)存和文件之間直接讀寫(xiě)數(shù)字,而不像fprintf和fscanf進(jìn)行格式化。我該怎么辦? 148 12.41 怎樣正確地讀取二進(jìn)制文件?有時(shí)看到0x0a和0x0d容易混淆,而且如果數(shù)據(jù)中包含0x1a的話(huà),我好像會(huì)提前遇到EOF!148 12.42 我在寫(xiě)一個(gè)二進(jìn)制文件的“過(guò)濾器”,但是stdin和stdout卻被作為文本流打開(kāi)了。怎樣才能把它們的模式改為二進(jìn)制? 148 12.43 文本和二進(jìn)制輸入輸出有什么區(qū)別? 149 12.44 如何在數(shù)據(jù)文件中讀寫(xiě)結(jié)構(gòu)? 149 12.45 怎樣編寫(xiě)符合舊的二進(jìn)制數(shù)據(jù)格式的代碼? 149 第13章 庫(kù)函數(shù) 151 字符串函數(shù) 151 13.1 怎樣把數(shù)字轉(zhuǎn)為字符串(與atoi相反)?有itoa函數(shù)嗎? 151 13.2 為什么strncpy不能總在目標(biāo)串放上終止符'\0'? 152 13.3 C 語(yǔ)言有類(lèi)似于其他語(yǔ)言中的“substr ”(取出子串)的例程嗎? 152 13.4 怎樣把一個(gè)字符串中所有字符轉(zhuǎn)換成大寫(xiě)或小寫(xiě)? 153 13.5 為什么有些版本的toupper對(duì)大寫(xiě)字符會(huì)有奇怪的反應(yīng)?為什么有的代碼在調(diào)用toupper 前先調(diào)用islower? 153 13.6 怎樣將字符串分割成用空白分隔的字段?怎樣實(shí)現(xiàn)類(lèi)似main 處理argc和argv的過(guò)程? 153 13.7 哪里可以找到處理正則表達(dá)式或通配符匹配的代碼? 155 排序 156 13.8 我想用strcmp作為比較函數(shù),調(diào)用qsort對(duì)一個(gè)字符串?dāng)?shù)組排序,但是不行。為什么? 156 13.9 我想用qsort()對(duì)一個(gè)結(jié)構(gòu)數(shù)組排序。我的比較函數(shù)接受結(jié)構(gòu)指針,但是編譯器認(rèn)為這個(gè)函數(shù)不是qsort需要的類(lèi)型。我要怎樣轉(zhuǎn)換這個(gè)函數(shù)指針才能避免這樣的警告? 156 13.10 怎樣對(duì)一個(gè)鏈表排序? 158 13.11 怎樣對(duì)大于內(nèi)存容量的數(shù)據(jù)排序? 158 日期和時(shí)間 159 13.12 怎樣在C 程序中取得當(dāng)前日期或時(shí)間? 159 13.13 我知道庫(kù)函數(shù)localtime可以把time_t轉(zhuǎn)換成結(jié)構(gòu)struct tm,而ctime可以把time_t轉(zhuǎn)換成為可打印的字符串。怎樣才能進(jìn)行反向操作,把struct tm或一個(gè)字符串轉(zhuǎn)換成time_t? 159 13.14 怎樣在日期上加n天?怎樣取得兩個(gè)日期的時(shí)間間隔? 160 隨機(jī)數(shù) 162 13.15 怎么生成一個(gè)隨機(jī)數(shù)? 162 13.16 怎樣獲得某一范圍內(nèi)的隨機(jī)整數(shù)? 163 13.17 每次執(zhí)行程序,rand都返回相同的數(shù)字序列。為什么? 164 13.18 我需要隨機(jī)的真/假值,所以我就直接用rand()%2,可是我得到交替的0, 1, 0, 1, 0 …。為什么? 164 13.19 如何獲取根本不重復(fù)的隨機(jī)數(shù)? 165 13.20 怎樣產(chǎn)生正態(tài)分布或高斯分布的隨機(jī)數(shù)? 165 13.21 我在移植一個(gè)程序,里邊調(diào)用了一個(gè)函數(shù)drand48 ,而我的庫(kù)又沒(méi)有這個(gè)。這是個(gè)什么函數(shù)? 167 其他庫(kù)函數(shù) 168 13.22 exit(status)是否真的跟從main 函數(shù)返回status 等價(jià)? 168 13.23 memcpy和memmove 有什么區(qū)別? 168 13.24 我想移植這個(gè)舊程序。為什么報(bào)出這些“undefined external”錯(cuò)誤:index? 、rindex?、bcopy?、bcmp?、bzero?? 168 13.25 我不斷得到庫(kù)函數(shù)未定義錯(cuò)誤,但是我已經(jīng)包含了所有用到的頭文件了。 168 13.26 雖然我在連接時(shí)明確地指定了正確的函數(shù)庫(kù),我還是得到庫(kù)函數(shù)未定義錯(cuò)誤!168 13.27 一個(gè)最簡(jiǎn)單的程序,不過(guò)在一個(gè)窗口里打印出“Hello,World”,為什么會(huì)編譯出巨大的可執(zhí)行代碼(數(shù)百K)?我該少包含一些頭文件嗎? 169 13.28 連接器報(bào)告_end未定義代表什么意思? 169 *13.29 我的編譯器提示printf未定義!這怎么可能? 169 第14章 浮點(diǎn)運(yùn)算 170 14.1 一個(gè)float變量賦值為3.1時(shí),為什么printf輸出的值為3.0999999? 170 14.2 我想計(jì)算一些平方根,我把程序簡(jiǎn)化成這樣:main(){printf ("%f\h", sqrt(144.)); 可得到的結(jié)果卻是瘋狂的數(shù)字。為什么? 170 14.3 我想做一些簡(jiǎn)單的三角函數(shù)運(yùn)算,也包含了math.h ,但連接器總是提示sin、cos這樣的函數(shù)未定義。為什么? 171 14.4 我的浮點(diǎn)數(shù)計(jì)算程序表現(xiàn)得很奇怪,在不同的機(jī)器上給出了不同的結(jié)果。為什么? 171 14.5 有什么好的方法來(lái)檢查浮點(diǎn)數(shù)在“足夠接近”情況下的相等? 171 14.6 怎樣取整? 172 14.7 為什么C語(yǔ)言不提供乘冪的操作符? 173 14.8 為什么我機(jī)器上的math.h沒(méi)有預(yù)定義常量M_PI? 173 14.9 怎樣將變量置為IEEE NaN(“Not a Number”)或檢測(cè)變量是否為NaN及其他特殊值? 173 14.10 如何簡(jiǎn)潔地處理浮點(diǎn)異常? 174 14.11 在C語(yǔ)言中如何很好地實(shí)現(xiàn)復(fù)數(shù)? 174 14.12 我要尋找一些實(shí)現(xiàn)以下功能的程序源代碼:快速傅立葉變換(FFT)、矩陣算術(shù)(乘法、求逆等函數(shù))、復(fù)數(shù)算術(shù)!175 14.13 Turbo C的程序崩潰,顯示錯(cuò)誤為“floating point formats not linked”(浮點(diǎn)格式未連接)。我還缺點(diǎn)兒什么呢? 175 第15章 可變參數(shù)列表 176 調(diào)用變參函數(shù) 176 15.1 為什么調(diào)用printf前必須要包含stdio.h? 176 15.2 為什么%f可以在printf參數(shù)中同時(shí)表示float和double?它們難道不是不同類(lèi)型嗎? 177 15.3 我遇到了一個(gè)令人十分受挫的問(wèn)題,后來(lái)發(fā)現(xiàn)是這行代碼造成的:printf("%d", n);原來(lái)n 是longint型。難道ANSI的函數(shù)原型不就是用來(lái)防止這類(lèi)的參數(shù)類(lèi)型不匹配嗎? 177 15.4 怎樣寫(xiě)一個(gè)接受可變參數(shù)的函數(shù)? 177 15.5 怎樣寫(xiě)一個(gè)函數(shù),像printf那樣接受一個(gè)格式串和可變參數(shù),然后再把參數(shù)傳給printf去完成大部分工作? 180 15.6 怎樣寫(xiě)類(lèi)似scanf的函數(shù),再把參數(shù)傳給scanf去完成大部分工作? 180 15.7 我用的是ANSI前的編譯器,沒(méi)有stdarg.h文件。我該怎么辦? 181 提取可變參數(shù) 182 15.8 怎樣知道實(shí)際上有多少個(gè)參數(shù)傳入函數(shù)? 182 15.9 為什么編譯器不允許我定義一個(gè)沒(méi)有固定參數(shù)項(xiàng)的可變參數(shù)函數(shù)? 182 15.10 我有個(gè)接受float型的變參函數(shù),為什么va_arg(argp, float)卻不行? 183 15.11 為什么va_arg不能得到類(lèi)型為函數(shù)指針的參數(shù)? 183 困難的問(wèn)題 184 15.12 怎樣實(shí)現(xiàn)一個(gè)可變參數(shù)函數(shù),它把參數(shù)再傳給另一個(gè)可變參數(shù)函數(shù)? 184 15.13 怎樣調(diào)用一個(gè)在運(yùn)行時(shí)才構(gòu)建參數(shù)列表的函數(shù)? 186 第16 章 奇怪的問(wèn)題 187 16.1 為什么這個(gè)循環(huán)只執(zhí)行了一次?for(i=start;i end ; i ++);{printf("%d\n",i);} 187 *16.2 遇到不可理解的不合理語(yǔ)法錯(cuò)誤,似乎大段的程序沒(méi)有編譯!187 *16.3 為什么過(guò)程調(diào)用不起作用?編譯器似乎直接跳過(guò)去了!187 16.4 程序在執(zhí)行之前就崩潰了!(用調(diào)試器單步跟蹤,在main函數(shù)的第一個(gè)語(yǔ)句之前就死了。)為什么? 188 16.5 程序執(zhí)行正確,但退出時(shí)在main函數(shù)的最后一個(gè)語(yǔ)句之后崩潰了。為什么會(huì)這樣? 188 16.6 程序在一臺(tái)機(jī)器上運(yùn)行完美,但在另一臺(tái)上卻得到怪異的結(jié)果。更奇怪的是,增加或去除調(diào)試的打印語(yǔ)句,就改變了癥狀…… 188 16.7 為什么下面的代碼會(huì)崩潰?char *p = "hello, world!"; p[0] = 'H'; 189 16.8 我有些代碼是用來(lái)解析外部結(jié)構(gòu)的,但它卻崩潰了,報(bào)了“unaligned access ”(未對(duì)齊的訪(fǎng)問(wèn))錯(cuò)誤。這是什么意思? 190 16.9 “Segmentation violation”、“Bus error”和“General protection fault”是什么意思? 191 第17章 風(fēng)格 192 17.1 什么是C最好的代碼布局風(fēng)格? 192 17.2 如何在源文件中合理分配函數(shù)? 193 17.3 用if(!strcmp(s1, s2))比較兩個(gè)字符串是否相等是個(gè)好風(fēng)格嗎? 193 17.4 為什么有的人用if(0== x)而不是if(x== 0)? 193 17.5 為什么有些代碼在每次調(diào)用printf 前增加了類(lèi)型轉(zhuǎn)換(void)? 194 17.6 既然NULL和0都是空指針常量,我到底該用哪一個(gè)? 194 17.7 是該用TRUE和FALSE這樣的符號(hào)名稱(chēng)還是直接用1和0來(lái)作布爾常量? 194 17.8 什么是“匈牙利表示法”(Hungarian Notation )?是否值得一試? 194 17.9 哪里可以找到“Indian Hill Style Guide ”及其他編碼標(biāo)準(zhǔn)? 194 17.10 有人說(shuō)goto是邪惡的,永遠(yuǎn)都不該用它。這是否太極端了? 195 17.11 人們總是說(shuō)良好的風(fēng)格很重要,但當(dāng)他們使用良好的風(fēng)格寫(xiě)出清晰易讀的程序后,又發(fā)現(xiàn)程序的效率似乎降低了。既然效率那么重要,是否可以為了效率犧牲一些風(fēng)格和可讀性呢? 196 第18章 工具和資源 197 18.1 能否列一個(gè)常用工具列表? 197 18.2 怎樣捕獲棘手的malloc問(wèn)題? 198 18.3 有什么免費(fèi)或便宜的編譯器可以使用? 198 lint 198 18.4 剛剛輸入完一個(gè)程序,但它表現(xiàn)得很奇怪。你能發(fā)現(xiàn)有什么錯(cuò)誤的地方嗎? 199 18.5 如何關(guān)掉lint對(duì)每個(gè)malloc調(diào)用報(bào)出的“warning: possible pointer alignment problem”警告消息? 199 18.6 哪里可以找到兼容ANSI的lint? 199 18.7 難道ANSI函數(shù)原型說(shuō)明沒(méi)有使lint過(guò)時(shí)嗎? 199 資源 200 18.8 網(wǎng)上有哪些C語(yǔ)言的教程或其他資源? 200 *18.9 哪里可以找到好的源代碼實(shí)例,以供研究和學(xué)習(xí)? 201 18.10 有什么好的學(xué)習(xí)C語(yǔ)言的書(shū)?有哪些高級(jí)的書(shū)和參考? 201 18.11 哪里能找到K&R的練習(xí)答案? 201 18.12 哪里能找到Numerical Recipes in C 、Plauger的The Standard C Library或Kernighan和Pike的The UNIX Programming Enviroment等書(shū)里的源碼? 201 18.13 哪里可以找到標(biāo)準(zhǔn)C函數(shù)庫(kù)的源代碼? 202 18.14 是否有一個(gè)在線(xiàn)的C參考指南? 202 18.15 我需要分析和評(píng)估表達(dá)式的代碼。從哪里可以找到? 202 18.16 哪里可以找到C的BNF或YACC語(yǔ)法? 202 *18.17 誰(shuí)有C編譯器的測(cè)試套件? 203 *18.18 哪里有一些有用的源代碼片段和例子的收集? 203 *18.19 我需要執(zhí)行多精度算術(shù)的代碼!203 18.20 在哪里和怎樣取得這些可自由發(fā)布的程序? 203 第19章 系統(tǒng)依賴(lài) 205 鍵盤(pán)和屏幕I/O 205 19.1 怎樣從鍵盤(pán)直接讀入字符而不用等回車(chē)鍵?怎樣防止字符輸入時(shí)的回顯? 205 19.2 怎樣知道有未讀的字符(如果有,有多少)?另外,如何在沒(méi)有字符的時(shí)候不阻塞讀入? 209 19.3 怎樣顯示一個(gè)在原地更新自己的百分比或“旋轉(zhuǎn)棒”的進(jìn)度指示器? 209 19.4 怎樣清屏?怎樣反色輸出?怎樣把光標(biāo)移動(dòng)到指定的x, y位置? 210 19.5 怎樣讀入方向鍵、功能鍵? 210 其他I/O 211 19.6 怎樣讀入鼠標(biāo)輸入? 211 19.7 怎樣做串口(“comm”)的輸入輸出? 211 19.8 怎樣直接輸出到打印機(jī)? 211 19.9 怎樣發(fā)送轉(zhuǎn)義字符序列控制終端或其他設(shè)備? 211 19.10 怎樣做圖形? 212 *19.11 怎樣顯示GIF和JPEG圖像? 212 文件和目錄 212 19.12 怎樣檢驗(yàn)一個(gè)文件是否存在?如果請(qǐng)求的輸入文件不存在,我希望向用戶(hù)提出警告!212 19.13 怎樣在讀入文件前,知道文件大。俊213 *19.14 怎樣得到文件的修改日期和時(shí)間? 213 19.15 怎樣原地縮短一個(gè)文件而不用清除或重寫(xiě)? 213 19.16 怎樣在文件中插入或刪除一行(或一條記錄)? 214 19.17 怎樣從一個(gè)打開(kāi)的流或文件描述符得到文件名? 214 19.18 怎樣刪除一個(gè)文件? 214 *19.19 怎樣復(fù)制文件? 215 19.20 為什么用了詳盡的路徑還不能打開(kāi)文件?下面的代碼會(huì)返回錯(cuò)誤。Fopen("c:\newdir\file.dat", "r") 215 *19.21 fopen不讓我打開(kāi)文件"$HOME/.profile"和"~/.myrcfile"。 215 *19.22 怎樣制止MS-DOS下令人恐怖的“Abort,Retry,Ignore? ”信息? 215 19.23 遇到“Too many open files(打開(kāi)文件太多)”的錯(cuò)誤,怎樣增加同時(shí)打開(kāi)文件的允許數(shù)目? 215 19.24 如何得到磁盤(pán)的可用空間大? 216 19.25 怎樣在C語(yǔ)言中讀入目錄? 216 19.26 如何創(chuàng)建目錄?如何刪除目錄(及其內(nèi)容)? 217 訪(fǎng)問(wèn)原始內(nèi)存 217 19.27 怎樣找出系統(tǒng)還有多少內(nèi)存可用? 217 19.28 怎樣分配大于64K的數(shù)組或結(jié)構(gòu)? 217 19.29 錯(cuò)誤信息“DGROUP data allocation exceeds 64K(DGROUP 數(shù)據(jù)分配內(nèi)存超過(guò)64K)”什么意思?我應(yīng)該怎么做?我以為使用了大內(nèi)存模型,就可以使用大于64K的數(shù)據(jù)! 217 19.30 怎樣訪(fǎng)問(wèn)位于某特定地址的內(nèi)存(內(nèi)存映射的設(shè)備或圖形顯示內(nèi)存)? 218 19.31 如何訪(fǎng)問(wèn)機(jī)器地址0處的中斷向量?如果將指針設(shè)為0,編譯器可能把它轉(zhuǎn)成一個(gè)非零的內(nèi)部空指針值!218 “系統(tǒng)”命令 219 19.32 怎樣在一個(gè)C程序中調(diào)用另一個(gè)程序(獨(dú)立可執(zhí)行的程序或系統(tǒng)命令)? 219 19.33 如果運(yùn)行時(shí)才知道要執(zhí)行的命令的參數(shù)(文件名等),應(yīng)該如何調(diào)用system? 219 19.34 在MS-DOS上如何得到system返回的準(zhǔn)確錯(cuò)誤狀態(tài)? 220 19.35 怎樣調(diào)用另一個(gè)程序或命令,然后獲取它的輸出? 220 進(jìn)程環(huán)境 220 19.36 怎樣才能發(fā)現(xiàn)程序自己的執(zhí)行文件的全路徑? 220 19.37 怎樣找出和執(zhí)行文件在同一目錄的配置文件? 221 19.38 進(jìn)程如何改變它的調(diào)用者的環(huán)境變量? 221 19.39 如何打開(kāi)命令行給出的文件并解析選項(xiàng)? 221 19.40 exit(status)是否真的和從main函數(shù)返回同樣的status等價(jià)? 221 19.41 怎樣讀入一個(gè)對(duì)象文件并跳躍到其中的函數(shù)? 221 其他系統(tǒng)相關(guān)的操作 222 19.42 怎樣以小于1秒的精度延時(shí)或計(jì)算用戶(hù)響應(yīng)時(shí)間? 222 19.43 怎樣捕獲或忽略control-C這樣的鍵盤(pán)中斷? 222 19.44 怎樣簡(jiǎn)潔地處理浮點(diǎn)異常? 223 19.45 怎樣使用socket?如何聯(lián)網(wǎng)?如何寫(xiě)客戶(hù)/服務(wù)器程序? 223 *19.46 怎樣調(diào)用BIOS函數(shù)?如何寫(xiě)ISR?如何創(chuàng)建TSR? 224 *19.47 什么是“near”和“far”指針? 224 回顧 224 19.48 我不能使用這些非標(biāo)準(zhǔn)、依賴(lài)系統(tǒng)的函數(shù),程序需要兼容ANSI! 224 19.49 為什么這些內(nèi)容沒(méi)有在C語(yǔ)言中進(jìn)行標(biāo)準(zhǔn)化?任何現(xiàn)實(shí)程序都會(huì)用到這些東西!224 第20章 雜項(xiàng) 226 20.1 怎樣從函數(shù)返回多個(gè)值? 226 20.2 用什么數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)文本行最好?我開(kāi)始用固定大小的char型數(shù)組的數(shù)組,但是有很多局限。 227 20.3 怎樣打開(kāi)命令行提到的文件并處理參數(shù)? 229 20.4 如何正確地使用errno? 231 20.5 怎樣寫(xiě)數(shù)據(jù)文件,使之可以在不同字大小、字節(jié)順序或浮點(diǎn)格式的機(jī)器上讀入? 232 20.6 怎樣用char *指針指向的函數(shù)名調(diào)用函數(shù)? 232 位和字節(jié) 233 20.7 如何操作各個(gè)位? 233 20.8 怎樣實(shí)現(xiàn)位數(shù)組或集合? 234 20.9 怎樣判斷機(jī)器的字節(jié)順序是高字節(jié)在前還是低字節(jié)在前? 235 *20.10 怎樣調(diào)換字節(jié)? 236 20.11 怎樣將整數(shù)轉(zhuǎn)換到二進(jìn)制或十六進(jìn)制? 237 20.12 可以使用二進(jìn)制常數(shù)(類(lèi)似0b101010這樣的東西)嗎?printf有二進(jìn)制的格式說(shuō)明符嗎? 237 效率 238 20.13 用什么方法計(jì)算整數(shù)中為1的位的個(gè)數(shù)最高效? 238 20.14 怎樣提高程序的效率? 238 20.15 指針真的比數(shù)組快嗎?函數(shù)調(diào)用會(huì)拖慢程序多少?++i比i=i+1快嗎? 240 20.16 用移位操作符替換乘法和除法是否有價(jià)值? 240 *20.17 人們說(shuō)編譯器優(yōu)化得很好,我們不再需要為速度而寫(xiě)匯編了,但我的編譯器連用移位代替i/=2都做不到。 240 *20.18 怎樣不用臨時(shí)變量而交換兩個(gè)值? 241 switch 語(yǔ)句 241 20.19 switch語(yǔ)句和if/else鏈哪個(gè)更高效? 241 20.20 是否有根據(jù)字符串進(jìn)行條件切換的方法? 241 20.21 是否有使用非常量case行標(biāo)的方法(如范圍或任意的表達(dá)式)? 242 各種語(yǔ)言功能 243 20.22 return語(yǔ)句外層的括號(hào)是否真的可選擇? 243 20.23 為什么C語(yǔ)言的注釋不能嵌套?怎樣注釋掉含有注釋的代碼?引號(hào)包含的字符串內(nèi)的注釋是否合法? 243 20.24 為什么C語(yǔ)言的操作符不設(shè)計(jì)得更全面一些?好像還缺了一些^^、&&=和-=這樣的操作符!244 *20.25 C語(yǔ)言有循環(huán)移位操作符嗎? 244 *20.26 C是個(gè)偉大的語(yǔ)言還是別的什么東西?哪個(gè)其他語(yǔ)言可以寫(xiě)出像a+++++b這樣的代碼? 244 20.27 如果賦值操作符是:=,是不是就不容易意外地寫(xiě)出if(a=b)了? 245 20.28 C語(yǔ)言有和Pascal 的with等價(jià)的語(yǔ)句嗎? 245 20.29 為什么C語(yǔ)言沒(méi)有嵌套函數(shù)? 245 *20.30 assert是什么?如何使用? 246 其他語(yǔ)言 246 20.31 怎樣從C中調(diào)用FORTRAN(C++、BASIC、Pascal、Ada、LISP)的函數(shù)?反之如何? 246 20.32 有什么程序可以將Pascal或FORTRAN(或LISP、Ada、awk、“老”C)程序轉(zhuǎn)化為C程序? 246 20.33 C++是C的超集嗎?可以用C++編譯器來(lái)編譯C代碼嗎? 247 20.34 我需要用到“近似”的strcmp例程,比較兩個(gè)字符串的近似度,并不需要完全一樣。有什么好辦法? 247 20.35 什么是散列法? 248 20.36 如何生成正態(tài)或高斯分布的隨機(jī)數(shù)? 248 20.37 如何知道某個(gè)日期是星期幾? 249 20.38 (year % 4== 0)是否足以判斷閏年?2000年是閏年嗎? 250 20.39 為什么tm結(jié)構(gòu)中的tm_sec的范圍是0到61,暗示一分鐘有62秒? 250 瑣事 250 20.40 一個(gè)難題:怎樣寫(xiě)一個(gè)輸出自己源代碼的程序? 250 20.41 什么是“達(dá)夫設(shè)備”(Duff’s Device)? 251 20.42 下屆國(guó)際C語(yǔ)言混亂代碼競(jìng)賽(International Obfuscated C Code Contest,IOCCC)什么時(shí)候進(jìn)行?哪里可以找到當(dāng)前和以前的獲勝代碼? 251 20.43 K&R1提到的關(guān)鍵字entry是什么? 252 20.44 C的名字從何而來(lái)? 252 20.45 “char”如何發(fā)音? 252 *20.46 “l(fā)value”和“rvalue”代表什么意思? 252 20.47 哪里可以獲得本書(shū)的在線(xiàn)版? 252 術(shù)語(yǔ)表 253 參考文獻(xiàn) 261
你還可能感興趣
我要評(píng)論
|