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