-- 會員 / 註冊 --  
 帳號:
 密碼:
  | 註冊 | 忘記密碼
3/26 新書到! 3/19 新書到! 3/14 新書到! 12/12 新書到!
購書流程Q & A站務留言版客服信箱
3ds MaxMayaRhinoAfter EffectsSketchUpZBrushPainterUnity
PhotoShopAutoCadMasterCamSolidWorksCreoUGRevitNuke
C#CC++Java遊戲程式Linux嵌入式PLCFPGAMatlab
駭客資料庫搜索引擎影像處理FluentVR+ARANSYS深度學習
單晶片AVROpenGLArduinoRaspberry Pi電路設計CadenceProtel
HadoopPythonStm32CortexLabview手機程式AndroidiPhone
可查書名,作者,ISBN,3dwoo書號
詳細書籍分類

你必須知道的495個C語言問題

( 簡體 字)
作者:[美] 史蒂夫 薩米特 ( Steve Summit ) 類別:1. -> 程式設計 -> C -> C
譯者:
出版社:人民郵電出版社你必須知道的495個C語言問題 3dWoo書號: 43664
詢問書籍請說出此書號!

缺書
NT售價: 225

出版日:4/1/2016
頁數:262
光碟數:0
站長推薦:
印刷:黑白印刷語系: ( 簡體 版 )
加入購物車 加到我的最愛
(請先登入會員)
ISBN:9787115376763
作者序 | 譯者序 | 前言 | 內容簡介 | 目錄 | 
(簡體書上所述之下載連結耗時費功, 恕不適用在台灣, 若讀者需要請自行嘗試, 恕不保證)
作者序:

譯者序:

前言:

內容簡介:

  《你必須知道的495個C語言問題》以問答的形式組織內容,討論了學習或使用C語言的過程中經常遇到的一些問題。書中列出了C用戶經常問的400多個經典問題,涵蓋了初始化、數組、指針、字符串、內存分配、庫函數、C預處理器等各個方面的主題,并分別給出了解答,而且結合代碼示例闡明要點。
《你必須知道的495個C語言問題》結構清晰,講解透徹,是各高校相關專業C語言課程很好的教學參考書,也是各層次C程序員的實踐指南。
目錄:

第1章 聲明和初始化 1

基本類型 1
1.1 我該如何決定使用哪種整數類型? 1 
1.2 為什么不精確定義標準類型的大小? 2
1.3 因為C語言沒有精確定義類型的大小,所以我一般都用typedef定義int16和int32。然后根據實際的機器環境把它們定義為int、short、long等類型。這樣看來,所有的問題都解決了,是嗎? 2 
1.4 新的64位機上的64位類型是什么樣的? 3

指針聲明 3
1.5 這樣的聲明有什么問題?char *p1, p2; 我在使用p2的時候報錯了。 3
1.6 我想聲明一個指針,并為它分配一些空間,但卻不行。這樣的代碼有什么問題?char *p; *p=malloc(10); 4

聲明風格 4
1.7 怎樣聲明和定義全局變量和函數最好? 4
1.8 如何在C中實現不透明(抽象)數據類型? 5
1.9 如何生成“半全局變量”,就是那種只能被部分源文件中的部分函數訪問的變量? 5

存儲類型 6
1.10 同一個靜態(static)函數或變量的所有聲明都必須包含static存儲類型嗎? 6
1.11 extern在函數聲明中是什么意思? 6
1.12 關鍵字auto到底有什么用途? 7

類型定義(typedef) 7
1.13 對于用戶定義類型,typedef 和#define有什么區別? 7
1.14 我似乎不能成功定義一個鏈表。我試過typedef struct{char *item; NODEPTR next;}* NODEPTR; 但是編譯器報了錯誤信息。難道在C語言中結構不能包含指向自己的指針嗎? 7 
1.15 如何定義一對相互引用的結構? 9
1.16 Struct{ } x1;和typedef struct{ } x2; 這兩個聲明有什么區別? 10
1.17 “typedef int(*funcptr)();”是什么意思? 10

const 限定詞 10
1.18 我有這樣一組聲明:typedef char *charp; const charp p; 為什么是p而不是它指向的字符為const? 10
1.19 為什么不能像下面這樣在初始式和數組維度值中使用const值?const int n=5; int a[n]; 10
1.20 const char *p、char const *p和char *const p有什么區別? 10

復雜的聲明  11
1.21 怎樣建立和理解非常復雜的聲明?例如定義一個包含N個指向返回指向字符的指針的函數的指針的數組? 11 
1.22 如何聲明返回指向同類型函數的指針的函數?我在設計一個狀態機,用函數表示每種狀態,每個函數都會返回一個指向下一個狀態的函數的指針。可我找不到任何方法來聲明這樣的函數——感覺我需要一個返回指針的函數,返回的指針指向的又是返回指針的函數……,如此往復,以至無窮。 12 

數組大小 13
1.23 能否聲明和傳入數組大小一致的局部數組,或者由其他參數指定大小的參數數組? 13
1.24 我在一個文件中定義了一個extern數組,然后在另一個文件中使用,為什么sizeof取不到數組的大小? 13

聲明問題 14
1.25 函數只定義了一次,調用了一次,但編譯器提示非法重聲明了。 14
*1.26 main的正確定義是什么?void main正確嗎? 15
1.27 我的編譯器總在報函數原型不匹配的錯誤,可我覺得沒什么問題。這是為什么? 15
1.28 文件中的第一個聲明就報出奇怪的語法錯誤,可我看沒什么問題。這是為什么? 15
1.29 為什么我的編譯器不允許我定義大數組,如double array[256][256]? 15

命名空間 15
1.30 如何判斷哪些標識符可以使用,哪些被保留了? 15

初始化 18
1.31 對于沒有顯式初始化的變量的初始值可以作怎樣的假定?如果一個全局變量初始值為“零”,它可否作為空指針或浮點零? 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"; 初始化有什么區別?當我向p[i] 賦值的時候,我的程序崩潰了。 19 
1.35 char a{[3]}= "abc"; 是否合法? 20
1.36 我總算弄清楚函數指針的聲明方法了,但怎樣才能初始化呢? 20
1.37 能夠初始化聯合嗎? 20

第2章 結構、聯合和枚舉 21

結構聲明 21
2.1 struct x1{ };和typedef struct{ }x2; 有什么不同? 21
2.2 這樣的代碼為什么不對?struct x{ }; x thestruct; 22
2.3 結構可以包含指向自己的指針嗎? 22
2.4 在C語言中用什么方法實現抽象數據類型最好? 22
*2.5 在C語言中是否有模擬繼承等面向對象程序設計特性的好方法? 22
2.6 為什么聲明extern f(struct x *p); 給我報了一個晦澀難懂的警告信息? 23
2.7 我遇到這樣聲明結構的代碼:struct name {int namelen; char namestr[1];};然后又使用一些內存分配技巧使namestr數組用起來好像有多個元素,namelen記錄了元素個數。它是怎樣工作的?這樣是合法的和可移植的嗎? 23 
2.8 我聽說結構可以賦給變量也可以對函數傳入和傳出。為什么K&R1卻明確說明不能這樣做? 25
2.9 為什么不能用內建的==和!=操作符比較結構?  26
2.10 結構傳遞和返回是如何實現的? 26
2.11 如何向接受結構參數的函數傳入常量值?怎樣創建無名的中間的常量結構值? 26
2.12 怎樣從/向數據文件讀/寫結構? 27

結構填充 27
2.13 為什么我的編譯器在結構中留下了空洞?這導致空間浪費而且無法與外部數據文件進行“二進制”讀寫。能否關掉填充,或者控制結構域的對齊方式? 27 
2.14 為什么sizeof返回的值大于結構大小的期望值,是不是尾部有填充? 28
2.15 如何確定域在結構中的字節偏移量? 28
2.16 怎樣在運行時用名字訪問結構中的域? 29
2.17 C語言中有和Pascal的with等價的語句嗎?  29
2.18 既然數組名可以用作數組的基地址,為什么對結構不能這樣? 29
2.19 程序運行正確,但退出時卻“core dump ”(核心轉儲)了,怎么回事? 29

聯合 30
2.20 結構和聯合有什么區別? 30
2.21 有辦法初始化聯合嗎? 30
2.22 有沒有一種自動方法來跟蹤聯合的哪個域在使用? 30

枚舉 31
2.23 枚舉和一組預處理的#define有什么不同?  31
2.24 枚舉可移植嗎? 31
2.25 有什么顯示枚舉值符號的容易方法嗎? 31

位域 31
2.26 一些結構聲明中的這些冒號和數字是什么意思? 31
2.27 為什么人們那么喜歡用顯式的掩碼和位操作而不直接聲明位域? 32

第3章 表達式  33

求值順序 33
3.1 為什么這樣的代碼不行?a[i]= i++; 33
3.2 使用我的編譯器,下面的代碼int i= 7; printf("%d\n", i++ * i++); 打印出49。不管按什么順序計算,難道不該是56嗎? 33 
3.3 對于代碼int i=3; i=i++; 不同編譯器給出不同的i值,有的為3,有的為4,哪個是正確的? 34 
*3.4 有這樣一個巧妙的表達式:a^= b^= a^= b; 它不需要臨時變量就可以交換a和b的值。 34
3.5 可否用顯式括號來強制執行我所需要的計算順序并控制相關的副作用?就算括號不行,操作符優先級是否能夠控制計算順序呢? 35 
3.6 可是&&和||操作符呢?我看到過類似while((c = getchar()) != EOF && c != \n)的代碼…… 35
3.7 是否可以安全地認為,一旦&&和||左邊的表達式已經決定了整個表達式的結果,則右邊的表達式不會被求值? 36 
3.8 為什么表達式printf("%d %d", f1(), f2()); 先調用了f2?我覺得逗號表達式應該確保從左到右的求值順序。 36 
3.9 怎樣才能理解復雜表達式并避免寫出未定義的表達式?“序列點”是什么? 36
3.10 在a[i] = i++;中,如果不關心a[]的哪一個分量會被寫入,這段代碼就沒有問題,i也的確會增加1,對嗎? 38 
3.11 人們總是說i=i++的行為是未定義的。可我剛剛在一個ANSI編譯器上嘗試過,其結果正如我所期望的。 38 
3.12 我不想學習那些復雜的規則,怎樣才能避免這些未定義的求值順序問題呢? 38

其他的表達式問題 39
*3.13 ++i和i++有什么區別? 39
3.14 如果我不使用表達式的值,那我應該用i++還是++i來做自增呢? 39
3.15 我要檢查一個數是不是在另外兩個數之間,為什么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 需要根據條件把一個復雜的表達式賦給兩個變量中的一個。可以用下面這樣的代碼嗎?((condition) ? a : b)= complicated_expression; 41 
3.19 我有些代碼包含這樣的表達式。a ? b=c : d 有些編譯器可以接受,有些卻不能。為什么? 41

保護規則 42
3.20 “semantics of‘’change in ANSI C”的警告是什么意思? 42
3.21 “無符號保護”和“值保護”規則的區別在哪里? 42

第4章 指針 45

基本的指針應用 45
4.1 指針到底有什么好處? 45
4.2 我想聲明一個指針并為它分配一些空間,但卻不行。這些代碼有什么問題呢?char *p; *p =malloc(10); 45 
4.3 *p++自增p還是p所指向的變量? 46

指針操作 46
4.4 我用指針操作int數組的時候遇到了麻煩。 46
4.5 我有一個char *型指針碰巧指向一些int型變量,我想跳過它們。為什么((int *)p)++; 這樣的代碼不行? 47
4.6 為什么不能對void *指針進行算術操作? 47
4.7 我有些解析外部結構的代碼,但是它卻崩潰了,顯示出了“unaligned access”(未對齊的訪問)的信息。這是什么意思? 47

作為函數參數的指針 47
4.8 我有個函數,它應該接受并初始化一個指針:void f(int *ip){ static int dummy = 5; ip = &dummy;}但是當我如下調用時:int *ip; f(ip); 調用者的指針沒有任何變化。 47 
4.9 能否用void ** 通用指針作為參數,使函數模擬按引用傳遞參數?  48
4.10 我有一個函數extern intf(int *); ,它接受指向int型的指針。我怎樣用引用方式傳入一個常數?調用f(&5);似乎不行。 49 
4.11 C語言可以“按引用傳參”嗎? 50

其他指針問題 50
4.12 我看到了用指針調用函數的不同語法形式。到底怎么回事? 50
4.13 通用指針類型是什么?當我把函數指針賦向void *類型的時候,編譯通不過。 51
4.14 怎樣在整型和指針之間進行轉換?能否暫時把整數放入指針變量中,或者相反? 51
*4.15 我怎樣把一個int變量轉換為char *型?我試了類型轉換,但是不行。 52

第5章 空指針  53

空指針和空指針常量 53
5.1 臭名昭著的空指針到底是什么? 53
5.2 怎樣在程序里獲得一個空指針? 54
5.3 用縮寫的指針比較“if(p)”檢查空指針是否有效?如果空指針的內部表達不是0會怎樣? 55

NULL 宏 56
5.4 NULL是什么,它是怎么定義的? 56
5.5 在使用非零位模式作為空指針的內部表示的機器上,NULL 是如何定義的? 56
5.6 如果NULL定義成#define NULL((char *)0) ,不就可以向函數傳入不加轉換的NULL 了嗎? 57
5.7 我的編譯器提供的頭文件中定義的NULL為0L。為什么? 57
5.8 NULL可以合法地用作函數指針嗎? 57
5.9 如果NULL和0作為空指針常量是等價的,那我到底該用哪一個呢? 58
5.10 但是如果NULL的值改變了,比如在使用非零內部空指針的機器上,用NULL(而不是0)
不是更好嗎? 58 
5.11 我曾經使用過一個編譯器,不使用NULL就不能編譯。 58
5.12 我用預處理宏#define Nullptr(type)(type *)0幫助創建正確類型的空指針。 59

回顧 59
5.13 這有點奇怪:NULL可以確保是0,但空(null)指針卻不一定? 59
5.14 為什么有那么多關于空指針的疑惑?為什么這些問題如此頻繁地出現? 60
5.15 有沒有什么簡單點兒的辦法理解所有這些與空指針有關的東西呢? 60
5.16 考慮到有關空指針的所有這些困惑,要求它們的內部表示都必須為0不是更簡單嗎? 60
5.17 說真的,真有機器用非零空指針嗎,或者不同類型用不同的表示? 61

地址0 上到底有什么? 61
5.18 運行時的整數值0轉換為指針以后一定是空指針嗎? 61
5.19 如何訪問位于機器地址0處的中斷向量?如果我將指針值設為0,編譯器可能會自動將它轉換為非零的空指針內部表示。 62 
5.20 運行時的“null pointer assignment”錯誤是什么意思?應該怎樣捕捉它? 62

第6章 數組和指針 63

數組和指針的基本關系 63
6.1 我在一個源文件中定義了char a[6],在另一個源文件中聲明了extern char *a。為什么不行? 63
6.2 可是我聽說char a[]和char *a是等價的。是這樣的嗎? 63
6.3 那么,在C語言中“指針和數組等價”到底是什么意思? 64
6.4 既然它們這么不同,那為什么作為函數形參的數組和指針聲明可以互換呢? 65

數組不能被賦值 66
6.5 為什么不能這樣向數組賦值?extern char *getpass(); char str[10]; str=getpass("Enter password:"); 66 
6.6 既然不能向數組賦值,那這段代碼為什么可以呢?int f(char str[]){ if(str[0] == \0) str="none";…} 66 
6.7 如果你不能給它賦值,那么數組如何能成為左值呢? 66

回顧 67
6.8 現實地講,數組和指針的區別是什么? 67
6.9 有人跟我講,數組不過是常指針。這樣講準確嗎? 67
6.10 我還是很困惑。到底指針是一種數組,還是數組是一種指針? 67
6.11 我看到一些“搞笑”的代碼,包含5["abcdef"]這樣的“表達式”。這為什么是合法的C語言表達式呢? 68

數組的指針  68
6.12 既然數組引用會退化為指針,如果array是數組,那么array和&array又有什么區別呢? 68
6.13 如何聲明一個數組的指針? 69

動態數組分配 70
6.14 如何在運行時設定數組的大小?怎樣才能避免固定大小的數組? 70
6.15 我如何聲明大小和傳入的數組一樣的局部數組? 70
6.16 如何動態分配多維數組? 71
6.17 有個很好的竅門,如果我這樣寫:int realarray[10]; int *array = &realarray[-1]; 我就可以把“array”當作下標從1 開始的數組。 72

函數和多維數組 73
6.18 當我向一個接受指針的指針的函數傳入二維數組的時候,編譯器報錯了。 73
6.19 我怎樣編寫接受編譯時寬度未知的二維數組的函數? 74
6.20 我怎樣在函數參數傳遞時混用靜態和動態多維數組? 74

數組的大小  75
6.21 當數組是函數的參數時,為什么sizeof不能正確報告數組的大小? 76
6.22 如何在一個文件中判斷聲明為extern的數組的大小(例如,數組定義和大小在另一個文件中)?sizeof操作符似乎不行。 76 
6.23 sizeof返回的大小是以字節計算的,怎樣才能判斷數組中有多少個元素呢? 76

第7 章 內存分配 77

基本的內存分配問題 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);但是我得到了奇怪的結果。 78 
7.3 但是strcat的文檔說它接受兩個char *型參數。我怎么知道(空間)分配的事情呢? 78
*7.4 我剛才試了這樣的代碼:char *p; strcpy(p, "abc");它運行正常。怎么回事?為什么它沒有出錯? 79 
*7.5 一個指針變量分配多少內存? 79
7.6 我使用fgets將文件的所有行讀入一個數組,為什么讀入的每一行都是最后一行的內容呢? 79
7.7 我有個函數,本該返回一個字符串,但當它返回調用者的時候,返回的字符串卻是垃圾信息。
為什么?  80
*7.8 那么返回字符串或其他聚集的正確方法是什么呢? 81

調用malloc 81
7.9 為什么在調用malloc()時報出了“waring: assignment of pointer from integer lacks a cast”? 81
7.10 為什么有些代碼小心翼翼地把malloc返回的值轉換為分配的指針類型? 81
*7.11 在調用malloc()的時候,錯誤“不能把void * 轉換為int * ”是什么意思? 82
7.12 我看到下面這樣的代碼:char *p = malloc(strlen(s) + 1); strcpy(p,s); 難道不應該是malloc ((strlen(s) + 1) * sizeof(char)) 嗎? 82 
7.13 我為malloc寫了一個小小的封裝函數。它為什么不行? 82
7.14 我想聲明一個指針并向它分配一些內存,但是不行。這樣的代碼有什么問題?char *p; *p = malloc(10); 82 
7.15 我如何動態分配數組? 83
7.16 怎樣判斷還有多少內存? 83
7.17 malloc(0)是返回空指針還是指向0個字節的指針? 83
7.18 我聽說有的操作系統在程序使用的時候才真正分配malloc申請的內存。這合法嗎? 83

有關malloc 的問題 83
7.19 為什么malloc返回了離譜的指針值?我的確讀過問題7.9,而且也在調用之前包含了extern void *malloc();聲明。  83 
7.20 我用一行這樣的代碼分配一個巨大的數組,用于數值運算:double *array = malloc (256 *256 *sizeof(double));malloc()并沒有返回空指針,但是程序運行得有些奇怪,好像改寫了某些內存,或者malloc()并沒有分配我申請的那么多內存。為什么? 84 
7.21 我的PC機有8兆內存。為什么我只能分配640K左右的內存? 84
7.22 我的應用程序非常依賴數據結構的節點的動態分配,而malloc/free的代價成了瓶頸。我該怎么做? 84
7.23 我的程序總是崩潰,顯然發生在malloc內部的某個地方。但是我看不出哪里有問題。是malloc有bug嗎? 84

釋放內存 85
7.24 動態分配的內存一旦釋放之后就不能再使用,是吧? 85
7.25 為什么在調用free()之后指針沒有變空?使用(賦值、比較)釋放之后的指針有多么不安全? 86
7.26 當我調用malloc()為一個函數的局部指針分配內存時,我還需要用free()顯式地釋放嗎? 86
7.27 我在分配一些結構,它們包含指向其他動態分配的對象的指針。我在釋放結構的時候,還需要釋放每一個下級指針嗎? 86 
7.28 我必須在程序退出之前釋放分配的所有內存嗎? 86
7.29 我有個程序分配了大量的內存,然后又釋放了。但是從操作系統看,內存的占用率卻并沒有變回去。 87 

分配內存塊的大小 87 
7.30 free()怎么知道有多少字節需要釋放? 87
7.31 那么我能否查詢malloc包,以查明可分配的最大塊是多大? 87
7.32 為什么sizeof不能告訴我它所指的內存塊的大小? 87

其他分配函數 88
7.33 (像問題6.14中那樣)動態分配數組之后,還能改變它的大小嗎? 88
7.34 向realloc()的第一個參數傳入空指針合法嗎?你為什么要這樣做? 89
7.35 calloc()和malloc()有什么區別?應該用哪一個?利用calloc 的零填充功能安全嗎?free()可以釋放calloc()分配的內存嗎,還是需要一個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);可得到的結果很奇怪。 93 
8.5 char a[]= "string literal"; 和char *p= "string literal"; 初始化有什么區別?當我對p[i]賦值的時候,程序崩潰了。 93 
8.6 我怎么得到與字符相對應的數字(即ASCII 或其他字符集下的)值?反過來又該怎么做? 94
8.7 C語言有類似其他語言的"substr"(提取子串)這樣的函數嗎? 94
8.8 我將用戶鍵入的字符串讀入數組,然后再顯示出來。當用戶鍵入\n這樣的序列時,為什么不能正確處理呢? 94 
8.9 我注意到sizeof(a)是2而不是1(即不是sizeof(char)),是不是我的編譯器有問題? 94
8.10 我正開始考慮多語言字符集的問題。是否有必要擔心sizeof(char)會被定義為2,以便表達16位的字符集呢? 95 

第9章 布爾表達式和變量 96
9.1 C語言中布爾值該用什么類型?為什么它不是一個標準類型?我應該用#define或enum定義真值和假值嗎? 96 
9.2 既然在C 語言中所有的非零值都被看作“真”,那是不是把TRUE 定義為1很危險?如果某個內建的函數或關系操作符“返回”不是1的其他值怎么辦?  97 
9.3 當p是指針時,if(p)是合法的條件表達式嗎? 98
9.4 我該使用像TRUE和FALSE這樣的符號名稱還是直接用1和0來作布爾常量? 98
9.5 我準備使用的一個第三方頭文件定義了自己的TRUE和FALSE,它們跟我已經開發的部分不兼容。我該怎么辦? 98 

第10章 C預處理器 99

宏定義 99
10.1 我想定義一些函數式的宏,例如:#define square(x)x * x但它們并不總是正確的。為什么? 99
10.2 這里有一些的預處理宏,使用它們,我可以寫出更像Pascal的C代碼。你覺得怎么樣? 100
10.3 怎么寫一個交換兩個值的通用宏?  101
10.4 書寫多語句宏的最好方法是什么?  101
10.5 用typdef和預處理宏生成用戶定義類型有什么區別? 102

頭文件 102
10.6 我第一次把一個程序分成多個源文件,我不知道該把什么放到.c文件,把什么放到.h文件。(“.h”到底是什么意思?) 102 
10.7 可以在一個頭文件中包含另一頭文件嗎? 103
10.8 完整的頭文件搜索規則是怎樣的?  104
10.9 我在文件的第一個聲明就遇到奇怪的語法錯誤,但是看上去沒什么問題。 104
10.10 我使用了來自兩個不同的第三方庫的頭文件,它們都定義了相同的宏,如TRUE、FALSE、Min()和Max()等,但是它們的定義相互沖突,而且跟我在自己的頭文件中的定義也有沖突。我該怎么辦? 104 
10.11 我在編譯一個程序,看起來我好像缺少需要的一個或多個頭文件。誰能發給我一份? 105

條件編譯  105
10.12 怎樣構造比較字符串的#if預處理表達式? 105
10.13 sizeof操作符可以用在#if預處理指令中嗎? 106
10.14 我可以像這樣在#define行里使用#ifdef來定義兩個不同的東西嗎? 106
10.15 對typedef的類型定義有沒有類似#ifdef的東西? 106
10.16 我如何用#if表達式來判斷機器是高字節在前還是低字節在前? 107
10.17 為什么在我用#ifdef關掉的代碼行中報出了奇怪的語法錯誤? 107
10.18 我拿到了一些代碼,里邊有太多的#ifdef。我不想使用預處理器把所有的#include 和#ifdef都擴展開,有什么辦法只保留一種條件的代碼呢? 107 
10.19 如何列出所有的預定義宏? 107

奇異的處理 108
10.20 我有些舊代碼,試圖用這樣的宏來構造標識符:#define Paste(a, b) a/**/b 但是現在不行了。為什么? 108 
10.21 我有一個舊宏:#define CTRL(c) (c & 037)現在不能用了。為什么? 108
10.22 為什么宏#define TRACE(n) printf("TRACE: \%d\n", n) 報出警告“macro replacement within a string literal ”?它似乎把TRACE(count);擴展成了printf("TRACE: \%d\count", count); 109 
10.23 如何在宏擴展的字符串字面量中使用宏參數? 109
10.24 我想用ANSI 的“字符串化”預處理操作符#將符號常量的值放入消息中,但它總是對宏名稱而不是它的值進行字符串化。這是什么原因? 109 
10.25 我想用預處理器做某件事情,但卻不知道如何下手。 110

可變參數列表的宏 110
10.26 怎樣寫可變參數宏?如何用預處理器“關掉”具有可變參數的函數調用? 110
10.27 如何在通用的調試宏中包含__FILE__和__LINE__宏? 111

第11章 ANSI/ISO標準C 113

標準 113
11.1 什么是“ANSI C標準”? 113
11.2 如何得到一份標準的副本? 114
*11.3 我在哪里可以找到標準的更新? 115

函數原型  115
11.4 為什么我的ANSI編譯器對用float聲明的參數會警告類型不匹配? 115
11.5 能否混用舊式的和新型的函數語法? 116
*11.6 為什么下述聲明報出了一個奇怪的警告信息“Struct X declared inside parameter list”? extern int f(struct x *p); 116 
11.7 有個問題一直困擾著我,它是由這一行printf ("%d", n); 導致的,因為n是個long int型。難道 ANSI 的函數原型不能檢查這種函數的參數不匹配問題嗎? 116 
11.8 我聽說必須在調用printf之前包含stdio.h。為什么? 117

const 限定詞 117
11.9 為什么不能在初始化和數組維度中使用const值?例如const int n = 5; int a[n]; 117
11.10 “const char *p”、“char const *p ”和“char * const p ”有何區別? 117
11.11 為什么不能向接受const char ** 的函數傳入char **? 118
11.12 我這樣聲明:typedef char * charp; const charp p; 為什么是p而不是它所指向的字符為const?  118 

main()函數的使用 119 
11.13 能否通過將main聲明為void來關掉“main沒有返回值”的警告? 119
11.14 main()的第3個參數envp是怎么回事?  120
11.15 我覺得把main()聲明為void也不會失敗,因為我調用了exit()而不是return,況且我的操作系統也忽略了程序的退出/返回狀態。 120
*11.16 那么到底會出什么問題?真的有什么系統不支持void main()嗎? 120
11.17 為什么以前流行的那些C 語言書總是使用void main()?  120
11.18 在main()中調用exit(status)和返回同樣的status真的等價嗎? 121

預處理功能 121
11.19 我試圖用ANSI“字符串化”預處理操作符#向信息中插入符號常量的值,但它字符串化的總是宏的名字而不是它的值。為什么? 121 
11.20 警告信息“warning: macro replacement within a string literal”是什么意思? 121
11.21 為什么在我用#ifdef去掉的代碼里出現了奇怪的語法錯誤? 122
11.22 #pragma是什么,有什么用? 122
11.23 “#pragma once”什么意思?我在一些頭文件中看到了它。 122

其他的ANSI C 問題 123
11.24 char a[3] = "abc";合法嗎?它是什么意思? 123
11.25 既然對數組的引用會退化為指針,那么,如果array是數組,array和&array之間有什么區別呢? 123
11.26 為什么我不能對void *指針進行算術運算? 123
11.27 memcpy()和memmove() 有什么區別? 124
11.28 malloc(0)有什么用?返回一個空指針還是指向0字節的指針? 124
11.29 為什么ANSI 標準規定了外部標識符的長度和大小寫限制? 125
11.30 noalias是怎么回事?在它身上發生了什么? 125

老的或非標準的編譯器 125
11.31 為什么我的編譯器對最簡單的測試程序都報出了一大堆的語法錯誤?對這段代碼的第一行就報錯了:main(int argc. char **argv) { return0; } 125 
11.32 為什么有些 ASNI/ISO 標準庫函數未定義?我明明使用的就是ANSI 編譯器。 126
11.33 誰有可以在舊的C 程序和ANSI C 之間相互轉換的工具,或者自動生成原型的工具? 127
11.34 為什么聲稱兼容ANSI 的編譯器不能編譯這些代碼?我知道這些代碼是 ANSI 的,因為gcc 可以編譯。 127 

兼容性 127 
11.35 人們好像有些在意實現定義的(implementation-defined)、不確定的(unspecified)和未定義的(undefined) 行為的區別。它們的區別到底在哪里? 128 
*11.36 一個程序“合法(legal)”、“有效(valid)”或“符合標準的”(conforming )到底是什么意思? 128 
11.37 我很吃驚,ANSI 標準竟然有那么多未定義的東西。標準的唯一任務不就是讓這些東西標準化嗎? 129
11.38 有人說i=i++的行為是未定義的,但是我剛在一個兼容ANSI 的編譯器上測試,得到了我希望的結果。它真的是未定義的嗎? 129 

第12章 標準輸入輸出庫 130

基本輸入輸出 130
12.1 這樣的代碼有什么問題?char c; while((c = getchar()) != EOF) 130
12.2 我有個讀取直到EOF的簡單程序,但是我如何才能在鍵盤上輸入那個“\EOF”呢?我看stdio.h 中定義的EOF 是-1,是不是說我該輸入-1?  131 
12.3 為什么這些代碼把最后一行復制了兩遍?while(!feof(infp)){fgets(buf, MAXLINE, infp); fputs(buf, outfp);} 131 
12.4 我用fgets將文件的每行內容讀入指針數組。為什么結果所有的行都是最后一行的內容呢? 132
12.5 我的程序的屏幕提示和中間輸出有時沒有在屏幕上顯示,尤其是當我用管道通過另一個程序輸出的時候。為什么? 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 那樣的類型定義,當我不知道它到底是long 還是其他類型的時候,我應該使用什么樣的printf格式呢? 134 
12.11 如何用printf 實現可變的域寬度?就是說,我想在運行時確定寬度而不是使用%8d? 134
12.12 如何輸出在千位上用逗號隔開的數字?貨幣格式的數字呢? 135
12.13 為什么scanf("%d", i) 調用不行? 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 怎樣從特定格式的數據文件中讀取數據?怎樣讀入10個float 而不用使用包含10次%f的奇怪格式?如何將一行的任意多個域讀入一個數組中? 137

scanf問題 138
12.19 我像這樣用"%d\n"調用scanf 從鍵盤讀取數字:int n; scanf("%d\n",&n); printf("you typed %d\ n", n);好像要多輸入一行才返回。為什么? 138 
12.20 我用scanf 和%d讀取一個數字,然后再用gets() 讀取字符串,但是編譯器好像跳過了gets() 調用!  139
12.21 我發現如果堅持檢查返回值以確保用戶輸入的是我期待的數值,則scanf 的使用會安全很多。但有的時候好像會陷入無限循環。為什么? 139 
12.22 為什么大家都說不要使用scanf?那我該用什么來代替呢? 140
其他stdio 函數 141
12.23 我怎樣才知道對于任意的sprintf 調用需要多大的目標緩沖區?怎樣才能避免sprintf 目標緩沖區溢出? 141 
12.24 sprintf的返回值是什么?是int 還是char *? 142
12.25 為什么大家都說不要使用gets?  142
12.26 我覺得我應該在一長串的printf 調用之后檢查errno ,以確定是否有失敗的調用。為什么當我將輸出重定向到文件的時候會輸出奇怪的“printf failed: Not a typewriter ”信息? 142 
12.27 fgetops/fsetops和ftell/fseek之間有什么區別?fgetops和fsetops 到底有什么用處? 143
12.28 如何清除用戶的多余輸入,以防止在下一個提示符下讀入?用fflush(stdin) 可以嗎? 143 

打開和操作文件 144
12.29 我寫了一個函數用來打開文件:myfopen(char *filename, FILE *fp){fp = fopen(filename, "r");}可我這樣調用的時候:FILE *infp; myfopen("filename.dat", infp);,infp 指針并
沒有正確設置。為什么? 144 
12.30 連一個最簡單的fopen調用都不成功!這個調用有什么問題?FILE *fp = fopen(filename, r); 145 
12.31 為什么我不能用完整路徑名打開一個文件?這個調用總是失敗:fopen("c:\newdir\ file. dat", "r"); 145 
12.32 我想用fopen模式"r+"打開一個文件,讀出一個字符串,修改之后再寫入,從而就地更新一個文件。可是這樣不行。為什么? 145 
12.33 如何在文件中間插入或刪除一行(一條記錄)? 145
12.34 怎樣從打開的流中恢復文件名? 145

重定向stdin 和stdout  146
12.35 怎樣在程序里把stdin或stdout重定向到文件? 146
12.36 一旦使用freopen之后,怎樣才能恢復原來的stdout (或stdin)? 146
12.37 如何判斷標準輸入或輸出是否經過了重定向,即是否在命令行上使用了“”或“”? 147
12.38 我想寫個像"more"那樣的程序。怎樣才能在stdin 被重定向之后再回到交互鍵盤? 147
*12.39 怎樣同時向兩個地方輸出,如同時輸出到屏幕和文件? 147

“二進制”輸入輸出 148
12.40 我希望按字節在內存和文件之間直接讀寫數字,而不像fprintf和fscanf進行格式化。我該怎么辦? 148
12.41 怎樣正確地讀取二進制文件?有時看到0x0a和0x0d容易混淆,而且如果數據中包含0x1a的話,我好像會提前遇到EOF。 148 
12.42 我在寫一個二進制文件的“過濾器”,但是stdin和stdout卻被作為文本流打開了。怎樣才能把它們的模式改為二進制? 148 
12.43 文本和二進制輸入輸出有什么區別? 149
12.44 如何在數據文件中讀寫結構? 149
12.45 怎樣編寫符合舊的二進制數據格式的代碼? 149

第13章 庫函數 151

字符串函數 151
13.1 怎樣把數字轉為字符串(與atoi相反)?有itoa函數嗎? 151
13.2 為什么strncpy不能總在目標串放上終止符\0? 152
13.3 C 語言有類似于其他語言中的“substr ”(取出子串)的例程嗎? 152
13.4 怎樣把一個字符串中所有字符轉換成大寫或小寫? 153
13.5 為什么有些版本的toupper對大寫字符會有奇怪的反應?為什么有的代碼在調用toupper 前先調用islower? 153
13.6 怎樣將字符串分割成用空白分隔的字段?怎樣實現類似main 處理argc和argv的過程? 153
13.7 哪里可以找到處理正則表達式或通配符匹配的代碼? 155

排序 156
13.8 我想用strcmp作為比較函數,調用qsort對一個字符串數組排序,但是不行。為什么? 156
13.9 我想用qsort()對一個結構數組排序。我的比較函數接受結構指針,但是編譯器認為這個函數不是qsort需要的類型。我要怎樣轉換這個函數指針才能避免這樣的警告? 156 
13.10 怎樣對一個鏈表排序? 158
13.11 怎樣對大于內存容量的數據排序? 158
日期和時間 159
13.12 怎樣在C 程序中取得當前日期或時間? 159
13.13 我知道庫函數localtime可以把time_t轉換成結構struct tm,而ctime可以把time_t轉換成為可打印的字符串。怎樣才能進行反向操作,把struct tm或一個字符串轉換成time_t?  159 
13.14 怎樣在日期上加n天?怎樣取得兩個日期的時間間隔? 160

隨機數 162
13.15 怎么生成一個隨機數? 162
13.16 怎樣獲得某一范圍內的隨機整數? 163
13.17 每次執行程序,rand都返回相同的數字序列。為什么? 164
13.18 我需要隨機的真/假值,所以我就直接用rand()%2,可是我得到交替的0, 1, 0, 1, 0 …。為什么? 164
13.19 如何獲取根本不重復的隨機數? 165
13.20 怎樣產生正態分布或高斯分布的隨機數?  165
13.21 我在移植一個程序,里邊調用了一個函數drand48 ,而我的庫又沒有這個。這是個什么函數? 167

其他庫函數 168
13.22 exit(status)是否真的跟從main 函數返回status 等價? 168
13.23 memcpy和memmove 有什么區別? 168
13.24 我想移植這個舊程序。為什么報出這些“undefined external”錯誤:index? 、rindex?、bcopy?、bcmp?、bzero??  168 
13.25 我不斷得到庫函數未定義錯誤,但是我已經包含了所有用到的頭文件了。 168
13.26 雖然我在連接時明確地指定了正確的函數庫,我還是得到庫函數未定義錯誤。 168
13.27 一個最簡單的程序,不過在一個窗口里打印出“Hello,World”,為什么會編譯出巨大的可執行代碼(數百K)?我該少包含一些頭文件嗎? 169 
13.28 連接器報告_end未定義代表什么意思? 169
*13.29 我的編譯器提示printf未定義!這怎么可能? 169

第14章 浮點運算 170
14.1 一個float變量賦值為3.1時,為什么printf輸出的值為3.0999999? 170
14.2 我想計算一些平方根,我把程序簡化成這樣:main(){printf ("%f\h", sqrt(144.)); 可得到的結果卻是瘋狂的數字。為什么? 170
14.3 我想做一些簡單的三角函數運算,也包含了math.h ,但連接器總是提示sin、cos這樣的函數未定義。為什么? 171 
14.4 我的浮點數計算程序表現得很奇怪,在不同的機器上給出了不同的結果。為什么? 171
14.5 有什么好的方法來檢查浮點數在“足夠接近”情況下的相等? 171
14.6 怎樣取整? 172
14.7 為什么C語言不提供乘冪的操作符? 173
14.8 為什么我機器上的math.h沒有預定義常量M_PI? 173
14.9 怎樣將變量置為IEEE NaN(“Not a Number”)或檢測變量是否為NaN及其他特殊值? 173
14.10 如何簡潔地處理浮點異常? 174
14.11 在C語言中如何很好地實現復數? 174
14.12 我要尋找一些實現以下功能的程序源代碼:快速傅立葉變換(FFT)、矩陣算術(乘法、求逆等函數)、復數算術。 175 
14.13 Turbo C的程序崩潰,顯示錯誤為“floating point formats not linked”(浮點格式未連接)。我還缺點兒什么呢? 175 

第15章 可變參數列表 176

調用變參函數 176
15.1 為什么調用printf前必須要包含stdio.h?  176
15.2 為什么%f可以在printf參數中同時表示float和double?它們難道不是不同類型嗎? 177
15.3 我遇到了一個令人十分受挫的問題,后來發現是這行代碼造成的:printf("%d", n);原來n 是longint型。難道ANSI的函數原型不就是用來防止這類的參數類型不匹配嗎? 177 
15.4 怎樣寫一個接受可變參數的函數?  177
15.5 怎樣寫一個函數,像printf那樣接受一個格式串和可變參數,然后再把參數傳給printf去完成大部分工作? 180
15.6 怎樣寫類似scanf的函數,再把參數傳給scanf去完成大部分工作? 180
15.7 我用的是ANSI前的編譯器,沒有stdarg.h文件。我該怎么辦? 181

提取可變參數 182
15.8 怎樣知道實際上有多少個參數傳入函數? 182
15.9 為什么編譯器不允許我定義一個沒有固定參數項的可變參數函數? 182
15.10 我有個接受float型的變參函數,為什么va_arg(argp, float)卻不行? 183
15.11 為什么va_arg不能得到類型為函數指針的參數? 183

困難的問題 184
15.12 怎樣實現一個可變參數函數,它把參數再傳給另一個可變參數函數? 184
15.13 怎樣調用一個在運行時才構建參數列表的函數? 186

第16 章 奇怪的問題 187

16.1 為什么這個循環只執行了一次?for(i=start;i end ; i ++);{printf("%d\n",i);} 187
*16.2 遇到不可理解的不合理語法錯誤,似乎大段的程序沒有編譯。 187
*16.3 為什么過程調用不起作用?編譯器似乎直接跳過去了。 187
16.4 程序在執行之前就崩潰了!(用調試器單步跟蹤,在main函數的第一個語句之前就死了。)為什么? 188 
16.5 程序執行正確,但退出時在main函數的最后一個語句之后崩潰了。為什么會這樣? 188
16.6 程序在一臺機器上運行完美,但在另一臺上卻得到怪異的結果。更奇怪的是,增加或去除調試的打印語句,就改變了癥狀…… 188 
16.7 為什么下面的代碼會崩潰?char *p = "hello, world!"; p[0] = H; 189
16.8 我有些代碼是用來解析外部結構的,但它卻崩潰了,報了“unaligned access ”(未對齊的訪問)錯誤。這是什么意思? 190
16.9 “Segmentation violation”、“Bus error”和“General protection fault”是什么意思? 191

第17章 風格  192

17.1 什么是C最好的代碼布局風格? 192
17.2 如何在源文件中合理分配函數? 193
17.3 用if(!strcmp(s1, s2))比較兩個字符串是否相等是個好風格嗎? 193
17.4 為什么有的人用if(0== x)而不是if(x== 0)? 193
17.5 為什么有些代碼在每次調用printf 前增加了類型轉換(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 ”及其他編碼標準? 194
17.10 有人說goto是邪惡的,永遠都不該用它。這是否太極端了? 195
17.11 人們總是說良好的風格很重要,但當他們使用良好的風格寫出清晰易讀的程序后,又發現程序的效率似乎降低了。既然效率那么重要,是否可以為了效率犧牲一些風格和可讀性呢? 196

第18章 工具和資源 197
18.1 能否列一個常用工具列表? 197
18.2 怎樣捕獲棘手的malloc問題? 198
18.3 有什么免費或便宜的編譯器可以使用? 198

lint 198
18.4 剛剛輸入完一個程序,但它表現得很奇怪。你能發現有什么錯誤的地方嗎? 199
18.5 如何關掉lint對每個malloc調用報出的“warning: possible pointer alignment problem”警告消息? 199 
18.6 哪里可以找到兼容ANSI的lint? 199
18.7 難道ANSI函數原型說明沒有使lint過時嗎? 199

資源 200
18.8 網上有哪些C語言的教程或其他資源? 200
*18.9 哪里可以找到好的源代碼實例,以供研究和學習? 201
18.10 有什么好的學習C語言的書?有哪些高級的書和參考? 201
18.11 哪里能找到K&R的練習答案? 201
18.12 哪里能找到Numerical Recipes in C 、Plauger的The Standard C Library或Kernighan和Pike的The UNIX Programming Enviroment等書里的源碼? 201 
18.13 哪里可以找到標準C函數庫的源代碼? 202
18.14 是否有一個在線的C參考指南? 202
18.15 我需要分析和評估表達式的代碼。從哪里可以找到? 202
18.16 哪里可以找到C的BNF或YACC語法?  202
*18.17 誰有C編譯器的測試套件? 203
*18.18 哪里有一些有用的源代碼片段和例子的收集? 203
*18.19 我需要執行多精度算術的代碼。 203
18.20 在哪里和怎樣取得這些可自由發布的程序? 203

第19章 系統依賴 205

鍵盤和屏幕I/O 205
19.1 怎樣從鍵盤直接讀入字符而不用等回車鍵?怎樣防止字符輸入時的回顯? 205
19.2 怎樣知道有未讀的字符(如果有,有多少)?另外,如何在沒有字符的時候不阻塞讀入? 209
19.3 怎樣顯示一個在原地更新自己的百分比或“旋轉棒”的進度指示器? 209
19.4 怎樣清屏?怎樣反色輸出?怎樣把光標移動到指定的x, y位置? 210
19.5 怎樣讀入方向鍵、功能鍵? 210

其他I/O 211
19.6 怎樣讀入鼠標輸入? 211
19.7 怎樣做串口(“comm”)的輸入輸出? 211
19.8 怎樣直接輸出到打印機? 211
19.9 怎樣發送轉義字符序列控制終端或其他設備? 211
19.10 怎樣做圖形? 212
*19.11 怎樣顯示GIF和JPEG圖像? 212

文件和目錄 212
19.12 怎樣檢驗一個文件是否存在?如果請求的輸入文件不存在,我希望向用戶提出警告。 212
19.13 怎樣在讀入文件前,知道文件大小? 213
*19.14 怎樣得到文件的修改日期和時間? 213
19.15 怎樣原地縮短一個文件而不用清除或重寫? 213
19.16 怎樣在文件中插入或刪除一行(或一條記錄)? 214
19.17 怎樣從一個打開的流或文件描述符得到文件名? 214
19.18 怎樣刪除一個文件? 214
*19.19 怎樣復制文件? 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(打開文件太多)”的錯誤,怎樣增加同時打開文件的允許數目? 215
19.24 如何得到磁盤的可用空間大小? 216
19.25 怎樣在C語言中讀入目錄? 216
19.26 如何創建目錄?如何刪除目錄(及其內容)? 217

訪問原始內存 217
19.27 怎樣找出系統還有多少內存可用? 217
19.28 怎樣分配大于64K的數組或結構? 217
19.29 錯誤信息“DGROUP data allocation exceeds 64K(DGROUP 數據分配內存超過64K)”什么意思?我應該怎么做?我以為使用了大內存模型,就可以使用大于64K的數據! 217 
19.30 怎樣訪問位于某特定地址的內存(內存映射的設備或圖形顯示內存)? 218
19.31 如何訪問機器地址0處的中斷向量?如果將指針設為0,編譯器可能把它轉成一個非零的內部空指針值。 218

“系統”命令 219
19.32 怎樣在一個C程序中調用另一個程序(獨立可執行的程序或系統命令)? 219
19.33 如果運行時才知道要執行的命令的參數(文件名等),應該如何調用system? 219
19.34 在MS-DOS上如何得到system返回的準確錯誤狀態? 220
19.35 怎樣調用另一個程序或命令,然后獲取它的輸出? 220

進程環境  220
19.36 怎樣才能發現程序自己的執行文件的全路徑? 220
19.37 怎樣找出和執行文件在同一目錄的配置文件? 221
19.38 進程如何改變它的調用者的環境變量? 221
19.39 如何打開命令行給出的文件并解析選項?  221
19.40 exit(status)是否真的和從main函數返回同樣的status等價? 221
19.41 怎樣讀入一個對象文件并跳躍到其中的函數? 221

其他系統相關的操作 222
19.42 怎樣以小于1秒的精度延時或計算用戶響應時間? 222
19.43 怎樣捕獲或忽略control-C這樣的鍵盤中斷? 222
19.44 怎樣簡潔地處理浮點異常? 223
19.45 怎樣使用socket?如何聯網?如何寫客戶/服務器程序? 223
*19.46 怎樣調用BIOS函數?如何寫ISR?如何創建TSR?  224
*19.47 什么是“near”和“far”指針? 224

回顧 224
19.48 我不能使用這些非標準、依賴系統的函數,程序需要兼容ANSI! 224
19.49 為什么這些內容沒有在C語言中進行標準化?任何現實程序都會用到這些東西。 224

第20章 雜項 226
20.1 怎樣從函數返回多個值? 226
20.2 用什么數據結構存儲文本行最好?我開始用固定大小的char型數組的數組,但是有很多局限。 227
20.3 怎樣打開命令行提到的文件并處理參數? 229
20.4 如何正確地使用errno? 231
20.5 怎樣寫數據文件,使之可以在不同字大小、字節順序或浮點格式的機器上讀入? 232
20.6 怎樣用char *指針指向的函數名調用函數? 232

位和字節  233
20.7 如何操作各個位? 233 
20.8 怎樣實現位數組或集合? 234 
20.9 怎樣判斷機器的字節順序是高字節在前還是低字節在前? 235 
*20.10 怎樣調換字節? 236 
20.11 怎樣將整數轉換到二進制或十六進制? 237 
20.12 可以使用二進制常數(類似0b101010這樣的東西)嗎?printf有二進制的格式說明符嗎? 237 

效率 238
20.13 用什么方法計算整數中為1的位的個數最高效? 238
20.14 怎樣提高程序的效率? 238 
20.15 指針真的比數組快嗎?函數調用會拖慢程序多少?++i比i=i+1快嗎? 240
20.16 用移位操作符替換乘法和除法是否有價值? 240
*20.17 人們說編譯器優化得很好,我們不再需要為速度而寫匯編了,但我的編譯器連用移位代替i/=2都做不到。 240
*20.18 怎樣不用臨時變量而交換兩個值? 241

switch 語句 241
20.19 switch語句和if/else鏈哪個更高效? 241
20.20 是否有根據字符串進行條件切換的方法? 241
20.21 是否有使用非常量case行標的方法(如范圍或任意的表達式)? 242

各種語言功能 243
20.22 return語句外層的括號是否真的可選擇?  243
20.23 為什么C語言的注釋不能嵌套?怎樣注釋掉含有注釋的代碼?引號包含的字符串內的注釋是否合法? 243 
20.24 為什么C語言的操作符不設計得更全面一些?好像還缺了一些^^、&&=和-=這樣的操作符。 244
*20.25 C語言有循環移位操作符嗎? 244
*20.26 C是個偉大的語言還是別的什么東西?哪個其他語言可以寫出像a+++++b這樣的代碼? 244
20.27 如果賦值操作符是:=,是不是就不容易意外地寫出if(a=b)了? 245
20.28 C語言有和Pascal 的with等價的語句嗎? 245
20.29 為什么C語言沒有嵌套函數? 245
*20.30 assert是什么?如何使用? 246

其他語言  246
20.31 怎樣從C中調用FORTRAN(C++、BASIC、Pascal、Ada、LISP)的函數?反之如何? 246
20.32 有什么程序可以將Pascal或FORTRAN(或LISP、Ada、awk、“老”C)程序轉化為C程序? 246
20.33 C++是C的超集嗎?可以用C++編譯器來編譯C代碼嗎? 247
20.34 我需要用到“近似”的strcmp例程,比較兩個字符串的近似度,并不需要完全一樣。有什么好辦法? 247
20.35 什么是散列法? 248
20.36 如何生成正態或高斯分布的隨機數? 248
20.37 如何知道某個日期是星期幾? 249
20.38 (year % 4== 0)是否足以判斷閏年?2000年是閏年嗎? 250
20.39 為什么tm結構中的tm_sec的范圍是0到61,暗示一分鐘有62秒? 250

瑣事 250
20.40 一個難題:怎樣寫一個輸出自己源代碼的程序? 250
20.41 什么是“達夫設備”(Duff’s Device)?  251
20.42 下屆國際C語言混亂代碼競賽(International Obfuscated C Code Contest,IOCCC)什么時候進行?哪里可以找到當前和以前的獲勝代碼? 251 
20.43 K&R1提到的關鍵字entry是什么? 252
20.44 C的名字從何而來? 252
20.45 “char”如何發音? 252
*20.46 “lvalue”和“rvalue”代表什么意思? 252
20.47 哪里可以獲得本書的在線版? 252

術語表 253
參考文獻 261
序: