C 語言常見問題集
原著:Steve Summit
翻譯:朱群英, 孫 雲
修訂版 0.9.4, 2005年6月23日
版權所有 © 2005
目錄
1
. 前言
2
. 聲明和初始化
2
.
1
我如何決定使用那種整數類型?
2
.
2
64 位機上的 64 位類型是什麼樣的?
2
.
3
怎樣定義和聲明全局變量和函數最好?
2
.
4
extern 在函數聲明中是什麼意思?
2
.
5
關鍵字 auto 到底有什麼用途?
2
.
6
我似乎不能成功定義一個鏈表。我試過 typedef struct { char *item; NODEPTR next; } *NODEPTR; 但是編譯器報了錯誤信息。難道在C語言中一個 結構不能包含指向自己的指針嗎?
2
.
7
怎樣建立和理解非常複雜的聲明?例如定義一個包含 N 個指向返 回指向字符的指針的函數的指針的數組?
2
.
8
函數只定義了一次, 調用了一次, 但編譯器提示非法重定義了。
2
.
9
main() 的正確定義是什麼? void main() 正確嗎?
2
.
10
對於沒有初始化的變量的初始值可以作怎樣的假定? 如果一個全局變量初始值為 ``零", 它可否作為空指針或浮點零?
2
.
11
代碼 int f() { char a[] =
"
Hello, world!
"
;} 不能編譯。
2
.
12
這樣的初始化有什麼問題?char *p = malloc(10); 編譯器提示 ``非法初始式" 云云。
2
.
13
以下的初始化有什麼區別?char a[] =
"
string literal
"
; char *p =
"
string literal
"
; 當我向 p[i] 賦值的時候, 我的 程序崩潰了。
2
.
14
我總算弄清除函數指針的聲明方法了, 但怎樣才能初始化呢?
3
. 結構、聯合和枚舉
3
.
1
聲明 struct x1 { ...}; 和 typedef struct { ...} x2; 有什麼不同?
3
.
2
為什麼 struct x { ...}; x thestruct; 不對?
3
.
3
一個結構可以包含指向自己的指針嗎?
3
.
4
在 C 語言中實現抽像數據類型什麼方法最好?
3
.
5
在 C 中是否有模擬繼承等面向對像程序設計特性的好方法?
3
.
6
我遇到這樣聲明結構的代碼: struct name { int namelen; char namestr[1];}; 然後又使用一些內存分配技巧使 namestr 數組用起來好像有多個元素。這樣合法和可移植嗎?
3
.
7
是否有自動比較結構的方法?
3
.
8
如何向接受結構參數的函數傳入常數值?
3
.
9
怎樣從/向數據文件讀/寫結構?
3
.
10
我的編譯器在結構中留下了空洞, 這導致空間浪費而且無法 與外部數據文件進行 "二進制" 讀寫。能否關掉填充, 或者控制結構域的 對齊方式?
3
.
11
為什麼 sizeof 返回的值大於結構的期望值, 是不是尾部有填充?
3
.
12
如何確定域在結構中的字節偏移?
3
.
13
怎樣在運行時用名字訪問結構中的域?
3
.
14
程序運行正確, 但退出時卻 ``core dump''了,怎麼回事?
3
.
15
可以初始化一個聯合嗎?
3
.
16
枚舉和一組預處理的 #define 有什麼不同?
3
.
17
有什麼容易的顯示枚舉值符號的方法?
4
. 表達式
4
.
1
為什麼這樣的代碼: a[i] = i++; 不能工作?
4
.
2
使用我的編譯器,下面的代碼 int i=7; printf(
"
%d\n
"
, i++ * i++); 返回 49?不管按什麼順序計算, 難道不該打印出56嗎?
4
.
3
對於代碼 int i = 3; i = i++; 不同編譯器給出不同的結果, 有的為 3, 有的為 4, 哪個是正確的?
4
.
4
這是個巧妙的表達式: a ^= b ^= a ^= b 它不需要臨時變量就可以交換 a 和 b 的值。
4
.
5
我可否用括號來強制執行我所需要的計算順序?
4
.
6
可是 && 和
||
運算符呢? 我看到過類似 while((c = getchar()) != EOF && c !=
'
\n
'
) 的代碼 ……
4
.
7
我怎樣才能理解複雜表達式?``序列點" 是什麼?
4
.
8
那麼, 對於 a[i] = i++; 我們不知道 a[] 的哪 一個份量會被改寫,但 i 的確會增加 1, 對嗎?
4
.
9
++i 和 i++ 有什麼區別?
4
.
10
如果我不使用表達式的值, 我應該用 ++i 或 i++ 來自增一個變量嗎?
4
.
11
為什麼如下的代碼 int a = 100, b = 100; long int c = a * b; 不能工作?
4
.
12
我需要根據條件把一個複雜的表達式賦值給兩個變量中的 一個。可以用下邊這樣的代碼嗎? ((condition) ? a : b) = complicated_expression;
5
. 指針
5
.
1
我想聲明一個指針並為它分配一些空間, 但卻不行。這些代碼有什麼問題? char *p; *p = malloc(10);
5
.
2
*p++ 自增 p 還是 p 所指向的變量?
5
.
3
我有一個 char * 型指針正巧指向一些 int 型變 量, 我想跳過它們。為什麼如下的代碼 ((int *)p)++; 不行?
5
.
4
我有個函數,它應該接受並初始化一個指針 void f(int *ip) { static int dummy = 5; ip = &dummy;} 但是當我如下調用時: int *ip; f(ip); 調用者的指針卻沒有任何變化。
5
.
5
我能否用 void** 指針作為參數, 使函數按引用接受一 般指針?
5
.
6
我有一個函數 extern int f(int *); 它接受指向 int 型的指針。我怎樣用引用方式傳入一個常數?下面這樣的 調用 f(&5); 似乎不行。
5
.
7
C 有 ``按引用傳遞" 嗎?
5
.
8
我看到了用指針調用函數的不同語法形式。到底怎麼回事?
5
.
9
我怎樣把一個 int 變量轉換為 char * 型? 我試了類型轉換, 但是不行。
6
. 空 (null) 指針
6
.
1
臭名昭著的空指針到底是什麼?
6
.
2
怎樣在程序裡獲得一個空指針?
6
.
3
用縮寫的指針比較 ``if(p)" 檢查空指針是否可靠? 如果空指針的內部表達不是 0 會怎麼樣?
6
.
4
NULL 是什麼, 它是怎麼定義的?
6
.
5
在使用非全零作為空指針內部表達的機器上, NULL 是如何定義的?
6
.
6
如果 NULL 定義成 #define NULL ((char *)0) 難道不就可以向函數傳入不加轉換的 NULL 了嗎?
6
.
7
如果 NULL 和 0 作為空指針常數是等價的, 那我到底該用哪一個呢?
6
.
8
但是如果 NULL 的值改變了, 比如在使用非零內部空指針的機器上, 難道用 NULL (而不是 0) 不是更好嗎?
6
.
9
用預定義宏 #define Nullptr(type) (type *)0 幫助創建正確 類型的空指針。
6
.
10
這有點奇怪。NULL 可以確保是 0, 但空 (null) 指針卻不一定?
6
.
11
為什麼有那麼多關於空指針的疑惑?為什麼這些問題如此經常地出現?
6
.
12
我很困惑。我就是不能理解這些空指針一類的東西。
6
.
13
考慮到有關空指針的所有這些困惑, 難道把要求它們內部表達都必須 為 0 不是更簡單嗎?
6
.
14
說真的, 真有機器用非零空指針嗎, 或者不同類型用不同的表達?
6
.
15
運行時的 ``空指針賦值" 錯誤是什麼意思?
7
. 數組和指針
7
.
1
我在一個源文件中定義了 char a[6], 在另一個中聲明了 extern char *a 。為什麼不行 ?
7
.
2
可是我聽說 char a[ ] 和 char *a 是一樣的。
7
.
3
那麼, 在 C 語言中 ``指針和數組等價" 到底是什麼意思 ?
7
.
4
那麼為什麼作為函數形參的數組和指針申明可以互換呢 ?
7
.
5
如果你不能給它賦值, 那麼數組如何能成為左值呢 ?
7
.
6
現實地講, 數組和指針地區別是什麼 ?
7
.
7
有人跟我講, 數組不過是常指針。
7
.
8
我遇到一些 ``搞笑" 的代碼, 包含 5[
"
abcdef
"
] 這樣的 ``表達式"。 這為什麼是合法的 C 表達式呢 ?
7
.
9
既然數組引用會蛻化為指針, 如果 arr 是數組, 那麼 arr 和 &arr 又有什麼區別呢 ?
7
.
10
我如何聲明一個數組指針 ?
7
.
11
我如何在運行期設定數組的大小 ? 我怎樣才能避免固定大小的數組 ?
7
.
12
我如何聲明大小和傳入的數組一樣的局部數組 ?
7
.
13
我該如何動態分配多維數組 ?
7
.
14
有個靈巧的竅門: 如果我這樣寫 int realarray[10]; int *array = &realarray[-1]; 我就可以把 ``array" 當作下標從 1 開始的數組。
7
.
15
當我向一個接受指針的指針的函數傳入二維數組的時候, 編譯器報錯了。
7
.
16
我怎樣編寫接受編譯時寬度未知的二維數組的函數 ?
7
.
17
我怎樣在函數參數傳遞時混用靜態和動態多維數組 ?
7
.
18
當數組是函數的參數時, 為什麼 sizeof 不能正確報告數組的大小 ?
8
. 內存分配
8
.
1
為什麼這段代碼不行?char *answer; printf(
"
Type something:\n
"
); gets(answer); printf(
"
You typed \
"
%s\
"
\n
"
, answer);
8
.
2
我的 strcat() 不行.我試了 char *s1 =
"
Hello,
"
; char *s2 =
"
world!
"
; char *s3 = strcat(s1, s2); 但是我得到了奇怪的結果。
8
.
3
但是 strcat 的手冊頁說它接受兩個 char * 型參數。 我怎麼知道 (空間) 分配的事情呢?
8
.
4
我剛才試了這樣的代碼 char *p; strcpy(p,
"
abc
"
); 而它運行正常?怎麼回事? 為什麼它沒有崩潰?
8
.
5
一個指針變量分配多少內存?
8
.
6
我有個函數, 本該返回一個字符串, 但當它返回調用者的時候, 返回串卻是垃圾信息。
8
.
7
那麼返回字符串或其它集合的爭取方法是什麼呢?
8
.
8
為什麼在調用 malloc() 時, 我得到 ``警告: 整數賦向指針需要類型轉換"?
8
.
9
為什麼有些代碼小心地把 malloc 返回的值轉換為分配的指針類型。
8
.
10
在調用 malloc() 的時候, 錯誤 ``不能把 void * 轉換為 int *" 是什麼意思?
8
.
11
我見到了這樣的代碼 char *p = malloc(strlen(s) + 1); strcpy(p, s); 難道不應該是 malloc((strlen(s) + 1) * sizeof(char))?
8
.
12
我如何動態分配數組?
8
.
13
我聽說有的操作系統程序使用的時候才真正分配 malloc 申請 的內存。這合法嗎?
8
.
14
我用一行這樣的代碼分配一個巨大的數組, 用於數字運算: double *array = malloc(300 * 300 * sizeof( double )); malloc() 並沒有返回 null, 但是程序運行得有些奇怪, 好像改寫了某些內存, 或者 malloc() 並沒有分配我申請的那麼多內存, 云云。
8
.
15
我的 PC 有 8 兆內存。為什麼我只能分配 640K 左右的內存?
8
.
16
我的程序總是崩潰, 顯然在 malloc 內部的某個地方。 但是我看不出 哪裡有問題。是 malloc() 有 bug 嗎?
8
.
17
動態分配的內存一旦釋放之後你就不能再使用, 是吧?
8
.
18
為什麼在調用 free() 之後指針沒有變空?使用 (賦值, 比較) 釋放之後的指針有多麼不安全?
8
.
19
當我 malloc() 為一個函數的局部指針分配內存時, 我還需要用 free() 明確的釋放嗎?
8
.
20
我在分配一些結構, 它們包含指向其它動態分配的對象的指針。 我在釋放結構的時候, 還需要釋放每一個下級指針嗎?
8
.
21
我必須在程序退出之前釋放分配的所有內存嗎?
8
.
22
我有個程序分配了大量的內存, 然後又釋放了。但是從操作系統看, 內存的佔用率卻並沒有回去。
8
.
23
free() 怎麼知道有多少字節需要釋放?
8
.
24
那麼我能否查詢 malloc 包, 可分配的最大塊是多大?
8
.
25
向 realloc() 的第一個參數傳入空指針合法嗎?你為什麼要這樣做?
8
.
26
calloc() 和 malloc() 有什麼區別?利用 calloc 的零填充功能安全嗎? free() 可以釋放 calloc() 分配的內存嗎, 還是需要一個 cfree()?
8
.
27
alloca() 是什麼?為什麼不提倡使用它?
9
. 字符和字符串
9
.
1
為什麼 strcat(string,
'!'
); 不行?
9
.
2
我在檢查一個字符串是否跟某個值匹配。 為什麼這樣不行? char *string; ... if(string ==
"
value
"
) { /* string matches "value" */ ... }
9
.
3
如果我可以寫 char a[] =
"
Hello, world!
"
; 為什麼我不能寫 char a[14]; a =
"
Hello, world!
"
;
9
.
4
我怎麼得到對應字符的數字 (字符集) 值, 或者相反?
9
.
5
我認為我的編譯器有問題: 我注意到 sizeof('a') 是 2 而不是 1 (即, 不是 sizeof(char))。
10
. 布爾表達式和變量
10
.
1
C 語言中布爾值的候選類型是什麼?為什麼它不是一個 標準類型?我應該用 #define 或 enum 定義 true 和 false 值嗎?
10
.
2
因為在 C 語言中所有的非零值都被看作 ``真", 是不是把 TRUE 定義為 1 很危險?如果某個內置的函數或關係操作符 ``返回" 不是 1 的 其它值怎麼辦?
10
.
3
當 p 是指針時, if(p) 是合法的表達式嗎?
11
. C 預處理器
11
.
1
這些機巧的預處理宏: #define begin { #define end } 你覺得怎麼樣?
11
.
2
怎麼寫一個一般用途的宏交換兩個值?
11
.
3
書寫多語句宏的最好方法是什麼?
11
.
4
我第一次把一個程序分成多個源文件, 我不知道該把什麼放到 .c 文件, 把什麼放到 .h 文件。(``.h" 到底是什麼意思?)
11
.
5
一個頭文件可以包含另一頭文件嗎?
11
.
6
#include <> 和 #include 有什麼區別?
11
.
7
完整的頭文件搜索規則是怎樣的?
11
.
8
我在文件的第一個聲明就遇到奇怪的語法錯誤, 但是看上去沒什麼問題。
11
.
9
我包含了我使用的庫函數的正確頭文件, 可是連接器還是說它沒有定義。
11
.
10
我在編譯一個程序, 看起來我好像缺少需要的一個或多個頭文件。 誰能發給我一份?
11
.
11
我怎樣構造比較字符串的 #if 預處理表達式?
11
.
12
sizeof 操作符可以用於 #if 預編譯指令中嗎?
11
.
13
我可以在 #include 行裡使用 #ifdef 來定義兩個不同的東西嗎?
11
.
14
對 typdef 的類型定義有沒有類似 #ifdef的東西?
11
.
15
我如何用 #if 表達式來判斷機器是高字節在前還是低字節在前?
11
.
16
我得到了一些代碼, 裡邊有太多的 #ifdef。 我不想使用預處理器 把所有的 #include 和 #ifdef 都擴展開, 有什麼辦法只保留一種條件的 代碼呢?
11
.
17
如何列出所有的預定義標識符?
11
.
18
我有些舊代碼, 試圖用這樣的宏來構造標識符 #define Paste(a, b) a/**/b 但是現在不行了。
11
.
19
為什麼宏 #define TRACE(n) printf(
"
TRACE: %d\n
"
, n) 報出警告 ``用字符串常量代替宏"?它似乎應該把 TRACE(count); 擴展為 printf(
"
TRACE: %d\count
"
, count);
11
.
20
使用 # 操作符時, 我在字符串常量內使用宏參數有問題。
11
.
21
我想用預處理做某件事情, 但卻不知道如何下手。
11
.
22
怎樣寫參數個數可變的宏?
12
. ANSI/ISO 標準 C
12
.
1
什麼是 ``ANSI C 標準"?
12
.
2
我如何得到一份標準的副本?
12
.
3
我在哪裡可以找到標準的更新?
12
.
4
很多 ANSI 編譯器在遇到以下代碼時都會警告類型不匹配。 extern int func(float); int func(x) float x; { ...
12
.
5
能否混用舊式的和新型的函數語法?
12
.
6
為什麼聲明 extern int f(struct x *p); 報出了一個奇怪的警告信息 ``結構 x 在參數列表中聲明"?
12
.
7
我不明白為什麼我不能像這樣在初始化和數組維度中使用常量: const int n = 5; int a[n];
12
.
8
既然不能修改字符串常量, 為什麼不把它們定義為字符常量的數組?
12
.
9
``const char *p" 和 ``char * const p" 有何區別?
12
.
10
為什麼我不能向接受 const char ** 的函數傳入 char **?
12
.
11
怎樣正確聲明 main()?
12
.
12
我能否把 main() 定義為 void, 以避免擾人的 ``main無返回值" 警告?
12
.
13
可 main() 的第三個參數 envp 是怎麼回事?
12
.
14
我覺得把 main() 聲明為 void 不會失敗, 因為我調用了 exit() 而不是 return , 況且我的操作系統也忽略了程序的退出/返回狀態。
12
.
15
那麼到底會出什麼問題?真的有什麼系統不支持 void main() 嗎?
12
.
16
我一直用的那本書《熟練傻瓜C語言》總是使用 void main()。
12
.
17
從 main() 中, exit(status) 和返回同樣的 status 真的等價嗎?
12
.
18
我試圖用 ANSI ``字符串化" 預處理操作符 # 向信息中插入符號 常量的值, 但它字符串化的總是宏的名字而不是它的值。
12
.
19
警告信息 ``warning: macro replacement within a string literal" 是什麼意思?
12
.
20
在我用 #ifdef 去掉的代碼裡出現了奇怪的語法錯誤。
12
.
21
#pragma 是什麼, 有什麼用?
12
.
22
``#pragma once" 是什麼意思?我在一些頭文件中看到了它。
12
.
23
a[3] =
"
abc
"
; 合法嗎?它是什麼意思?
12
.
24
為什麼我不能對 void* 指針進行運算?
12
.
25
memcpy() 和 memmove() 有什麼區別?
12
.
26
malloc(0) 有什麼用?返回一個控指針還是指向 0 字節的指針?
12
.
27
為什麼 ANSI 標準規定了外部標示符的長度和大小寫限制?
12
.
28
我的編譯對最簡單的測試程序報出了一大堆的語法錯誤。
12
.
29
為什麼有些 ASNI/ISO 標準庫函數未定義?我明明使用 的就是 ANSI 編譯器。
12
.
30
誰有把舊的 C 程序轉化為 ANSI C 或相反的工具, 或者自動生成原型的工具?
12
.
31
為什麼聲稱兼容 ANSI 的 Frobozz Magic C 編譯器不能 編譯這些代碼?我知道這些代碼是 ANSI 的, 因為 gcc 可以編譯。
12
.
32
人們好像有些在意實現定義 (implementation-defin-ed)、未明確 (unspecified) 和無定義 (undefined) 行為的區別。它們的區別到底在哪裡?
12
.
33
一個程序的 ``合法", ``有效" 或 ``符合" 到底是什麼意思?
12
.
34
我很吃驚, ANSI 標準竟然有那麼多沒有定義的東西。 標準的唯一任務不就是讓這些東西標準化嗎?
12
.
35
有人說 i = i++ 的行為是未定義的, 但是我剛在一個兼容 ANSI 的編譯器上測試, 得到了我希望的結果。
13
. 標準輸入輸出庫
13
.
1
這樣的代碼有什麼問題? char c; while((c = getchar()) != EOF) ...
13
.
2
我有個讀取直到 EOF 的簡單程序, 但是我如何才能在鍵盤上輸入那個 ``EOF" 呢?
13
.
3
為什麼這些代碼 while(!feof(infp)) { fgets(buf, MAXLINE, infp); fputs(buf, outfp); } 把最後一行複製了兩遍?
13
.
4
我的程序的屏幕提示和中間輸出有時顯示在屏幕上, 尤其是當我用管道向 另一個程序輸出的時候。
13
.
5
我怎樣不等待回車鍵一次輸入一個字符?
13
.
6
我如何在 printf 的格式串中輸出一個
'
%
'
? 我試過 \%, 但是不行。
13
.
7
有人告訴我在 printf 中使用 %lf 不正確。那麼, 如果 scanf() 需要 %lf, 怎麼可以用在 printf() 中用 %f 輸出雙精度數呢?
13
.
8
對於 size_t 那樣的類型定義, 當我不知道它到底是 long 還是其它類型的時候, 我應該使用什麼樣的 printf 格式呢?
13
.
9
我如何用 printf 實現可變的域寬度?就是說, 我想在運行時確定寬度 而不是使用 %8d?
13
.
10
如何輸出在千位上用逗號隔開的數字?金額數字呢?
13
.
11
為什麼 scanf(
"
%d
"
, i) 調用不行?
13
.
12
為什麼 char s[30]; scanf(
"
%s
"
, s); 不用 & 也可以?
13
.
13
為什麼這些代碼 double d; scanf(
"
%f
"
, &d); 不行?
13
.
14
怎樣在 scanf() 格式串中指定可變的寬度?
13
.
15
當我用 ``%d\n" 調用 scanf 從鍵盤讀取數字 的時候, 好像要多輸入一行函數才返回。
13
.
16
我用 scanf %d 讀取一個數字, 然後再用 gets() 讀取字符串, 但是 編譯器好像跳過了 gets() 調用!
13
.
17
我發現如果堅持檢查返回值以確保用戶輸入的是我期待的數值, 則 scanf() 的使用會安全很多, 但有的時候好像會陷入無限循環。
13
.
18
為什麼大家都說不要使用 scanf()?那我該用什麼來代替呢?
13
.
19
我怎樣才知道對於任意的 sprintf 調用需要多大的目標緩衝區? 怎樣才能避免 sprintf() 目標緩衝區溢出?
13
.
20
為什麼大家都說不要使用 gets()?
13
.
21
為什麼調用 printf() 之後 errno 內有 ENOTTY?
13
.
22
fgetops/fsetops 和 ftell/fseek 之間有什麼區別? fgetops() 和 fsetops() 到底有什麼用處?
13
.
23
如何清除多餘的輸入, 以防止在下一個提示符下讀入? fflush(stdin) 可以嗎?
13
.
24
既然 fflush() 不能, 那麼怎樣才能清除輸入呢?
13
.
25
對某些路徑文件名調用 fopen() 總是失敗。
13
.
26
我想用 ``r+" 打開一個文件, 讀出一個字符串, 修改之後再寫入, 從而就地更新一個文件。可是這樣不行。
13
.
27
怎樣在程序裡把 stdin 或 stdout 重定向到文件?
13
.
28
一旦使用 freopen() 之後, 怎樣才能恢復原來的 stdout (或 stdin)?
13
.
29
怎樣同時向兩個地方輸出, 如同時輸出到屏幕和文件?
13
.
30
怎樣正確的讀取二進制文件?我有時看到 0x0a 和 0x0d 混淆了, 而且如果數據中包含 0x1a 的話, 我好像會提前遇到 EOF。
14
. 庫函數
14
.
1
怎樣把數字轉為字符串 (與 atoi 相反)?有 itoa() 函數嗎?
14
.
2
為什麼 strncpy() 不能總在目標串放上終止符
'
\0
'
?
14
.
3
為什麼有些版本的 toupper() 對大寫字符會有奇怪的反應? 為什麼有的代碼在調用 toupper() 前先調用 tolower()?
14
.
4
怎樣把字符串分隔成用空白作間隔符的段?怎樣實現類似傳遞給 main() 的 argc 和 argv?
14
.
5
我需要一些處理正則表達式或通配符匹配的代碼。
14
.
6
我想用 strcmp() 作為比較函數, 調用 qsort() 對一個字符串數組 排序, 但是不行。
14
.
7
我想用 qsort() 對一個結構數組排序。我的比較函數接受結構指針, 但是編譯器認為這個函數對於 qsort() 是錯誤類型。我要怎樣轉換這個函數指針 才能避免這樣的警告?
14
.
8
怎樣對一個鏈表排序?
14
.
9
怎樣對多於內存的數據排序?
14
.
10
怎樣在 C 程序中取得當前日期或時間?
14
.
11
我知道庫函數 localtime() 可以把 time_t 轉換成結構 struct tm, 而 ctime() 可以把 time_t 轉換成為可打印的字符串。 怎樣才能進行反向操作, 把 struct tm 或一個字符串轉換成 time_t?
14
.
12
怎樣在日期上加 N 天?怎樣取得兩個日期的時間間隔?
14
.
13
我需要一個隨機數生成器。
14
.
14
怎樣獲得在一定範圍內的隨機數?
14
.
15
每次執行程序, rand() 都返回相同順序的數字。
14
.
16
我需要隨機的真/假值, 所以我用直接用 rand() % 2, 可是我得到 交替的 0, 1, 0, 1, 0 ……
14
.
17
怎樣產生標準分佈或高斯分佈的隨機數?
14
.
18
我不斷得到庫函數未定義錯誤, 但是我已經 #inlude 了所有用到的頭文件了。
14
.
19
雖然我在連接時明確地指定了正確的函數庫, 我還是得到庫函數未定義錯誤。
14
.
20
連接器說 _end 未定義代表什麼意思?
14
.
21
我的編譯器提示 printf 未定義!這怎麼可能?
15
. 浮點運算
15
.
1
一個 float 變量賦值為 3.1 時, 為什麼 printf 輸出的值為 3.0999999?
15
.
2
執行一些開方根運算, 可是得到一些瘋狂的數字。
15
.
3
做一些簡單的三角函數運算, 也引用了 #include <math.h>, 可是一直得到編譯錯誤 ``undefined: sin" (函數 sin 未定義)。
15
.
4
浮點計算程序表現奇怪, 在不同的機器上給出不同的結果。
15
.
5
有什麼好的方法來驗對浮點數在 ``足夠接近" 情況下的等值?
15
.
6
怎樣取整數?
15
.
7
為什麼 C 不提供乘冪的運算符?
15
.
8
為什麼我機器上的 <math.h> 沒有預定 義常數 M_PI?
15
.
9
怎樣測試 IEEE NaN 以及其它特殊值?
15
.
10
在 C 中如何很好的實現複數?
15
.
11
我要尋找一些實現以下功能的程序源代碼: 快速傅立葉變換 (FFT)、矩陣算術 (乘法、倒置等函數)、 複數算術。
15
.
12
Turbo C 的程序崩潰, 顯示錯誤為 ``floating point formats not linked" (浮點格式未連接)。
16
. 可變參數
16
.
1
為什麼調用 printf() 前, 必須要用 #include <stdio.h>?
16
.
2
為什麼 %f 可以在 printf() 參數中, 同時表示 float 和 double?他們難道不是不同類型嗎?
16
.
3
為什麼當 n 為 long int, printf(
"
%d
"
, n); 編譯時沒有匹配警告?我以為 ANSI 函數原型可以防止這樣的類型不匹配。
16
.
4
怎樣寫一個有可變參數的函數?
16
.
5
怎樣寫類似 printf() 的函數, 再把參數轉傳給 printf() 去 完成大部分工作?
16
.
6
怎樣寫類似 scanf() 的函數, 再把參數轉傳給 scanf() 去 完成大部分工作?
16
.
7
怎樣知道實際上有多少個參數傳入函數?
16
.
8
為什麼編譯器不讓我定義一個沒有固定參數項的可變參數函數?
16
.
9
我有個接受 float 的可變參函數, 為什麼 va_arg(argp, float) 不工作?
16
.
10
va_arg() 不能得到類型為函數指針的參數。
16
.
11
怎樣實現一個可變參數函數, 它把參數再傳給另一個可變參數函數?
16
.
12
怎樣調用一個參數在執行是才建立的函數?
17
. 奇怪的問題
17
.
1
遇到不可理解的不合理語法錯誤, 似乎大段的程序沒有編譯。
17
.
2
為什麼過程調用不工作?編譯器似乎直接跳過去了。
17
.
3
程序在執行用之前就崩潰了, 用調試器單步跟進, 在 main() 之前就死了。
17
.
4
程序執行正確, 但退出時崩潰在 main() 最後一個語句之後。 為什麼會這樣?
17
.
5
程序在一台機器上執行完美, 但在另一台上卻得到怪異的結果。更奇怪的是, 增加或去除調試的打印語句, 就改變了症狀……
17
.
6
為什麼代碼: char *p =
"
hello, worl!
"
; p[0] =
'
H
'
; 會崩潰?
17
.
7
``Segmentation violation", ``Bus error" 和 ``General protection fault" 意味著什麼?
18
. 風格
18
.
1
什麼是 C 最好的代碼佈局風格?
18
.
2
用 if(!strcmp(s1, s2)) 比較兩個字符串等值,是否是個好風格?
18
.
3
為什麼有的人用 if (0 == x) 而不是 if (x == 0)?
18
.
4
原型說明 extern int func __((int, int)); 中, 那些多出來的括號和下劃線代表了什麼?
18
.
5
為什麼有些代碼在每次調用 printf() 前, 加了類型轉換 (void)?
18
.
6
什麼是 ``匈牙利標誌法" (Hungarian Notation)?是否值得用?
18
.
7
哪裡可以找到 ``印第安山風格指南" (Indian Hill Style Guide) 及其它編碼標準?
18
.
8
有些人說 goto 是邪惡的, 我應該永不用它。那是否太極端了?
19
. 工具和資源
19
.
1
常用工具列表。
19
.
2
怎樣抓捕棘手的 malloc 問題?
19
.
3
有什麼免費或便宜的編譯器可以使用?
19
.
4
剛剛輸入完一個程序, 但它表現的很奇怪。你可以發現有什麼錯誤的地方嗎?
19
.
5
哪裡可以找到兼容 ANSI 的 lint?
19
.
6
難道 ANSI 函數原型說明沒有使 lint 過時嗎?
19
.
7
網上有哪些 C 的教程或其它資源?
19
.
8
哪裡可以找到好的源代碼實例, 以供研究和學習?
19
.
9
有什麼好的學習 C 的書?有哪些高級的書和參考?
19
.
10
哪裡可以找到標準 C 函數庫的源代碼?
19
.
11
是否有一個在線的 C 參考指南?
19
.
12
哪裡可以得到 ANSI/ISO C 標準?
19
.
13
我需要分析和評估表達式的代碼。
19
.
14
哪裡可以找到 C 的 BNF 或 YACC 語法?
19
.
15
誰有 C 編譯器的測試套件?
19
.
16
哪裡有一些有用的源代碼片段和例子的收集?
19
.
17
我需要執行多精度算術的代碼。
19
.
18
在哪裡和怎樣取得這些可自由發佈的程序?
20
. 系統依賴
20
.
1
怎樣從鍵盤直接讀入字符而不用等 RETURN 鍵?怎樣 防止字符輸入時的回顯?
20
.
2
怎樣知道有未讀的字符, 如果有, 有多少?如果沒有字符, 怎樣使讀入不阻斷?
20
.
3
怎樣顯示一個百分比或 ``轉動的短棒" 的進展表示器?
20
.
4
怎樣清屏?怎樣輸出彩色文本?怎樣移動光標到指定位置?
20
.
5
怎樣讀入方向鍵, 功能鍵?
20
.
6
怎樣讀入鼠標輸入?
20
.
7
怎樣做串口 (``comm") 的輸入輸出?
20
.
8
怎樣直接輸出到打印機?
20
.
9
怎樣發送控制終端或其它設備的逃逸指令序列?
20
.
10
怎樣直接訪問輸入輸出板?
20
.
11
怎樣做圖形?
20
.
12
怎樣顯示 GIF 和 JPEG 圖像?
20
.
13
怎樣檢驗一個文件是否存在?
20
.
14
怎樣在讀入文件前, 知道文件大小?
20
.
15
怎樣得到文件的修改日期和時間?
20
.
16
怎樣縮短一個文件而不用清除或重寫?
20
.
17
怎樣在文件中插入或刪除一行 (或記錄)?
20
.
18
怎樣從一個打開的流或文件描述符得到文件名?
20
.
19
怎樣刪除一個文件?
20
.
20
怎樣複製一個文件?
20
.
21
為什麼用了詳盡的路徑還不能打開文件? fopen(
"
c:\ newdir \file.dat
"
,
"
r
"
) 返回錯誤。
20
.
22
fopen() 不讓我打開文件:
"
$HOME/.profile
"
和
"
~/ .myrcfile
"
。
20
.
23
怎樣制止 MS-DOS 下令人擔憂的 ``Abort, Retry, Ignore?" 信息?
20
.
24
遇到 ``Too many open files (打開文件太多)" 的錯誤, 怎樣增加同時打開文件的允許數目?
20
.
25
怎樣在 C 中讀入目錄?
20
.
26
怎樣找出系統還有多少內存可用?
20
.
27
怎樣分配大於 64K 的數組或結構?
20
.
28
錯誤信息 ``DGROUP data allocation exceeds 64K (DGROUP 數據分配內存超過 64K)" 說明什麼?我應該 怎麼做?我以為使用了大內存模型, 那我就可以使用多於 64K 的數據!
20
.
29
怎樣訪問位於某的特定地址的內存 (內存映射的設備或圖顯內存)?
20
.
30
怎樣在一個 C 程序中調用另一個程序 (獨立可執行的程序, 或系統命令)?
20
.
31
怎樣調用另一個程序或命令, 同時收集它的輸出?
20
.
32
怎樣才能發現程序自己的執行文件的全路徑?
20
.
33
怎樣找出和執行文件在同一目錄的配置文件?
20
.
34
一個進程如何改變它的調用者的環境變量?
20
.
35
怎樣讀入一個對像文件並跳躍到其中的地址?
20
.
36
怎樣實現精度小於秒的延時或記錄用戶回應的時間?
20
.
37
怎樣抓獲或忽略像 control-C 這樣的鍵盤中斷?
20
.
38
怎樣很好地處理浮點異常?
20
.
39
怎樣使用 socket? 網絡化? 寫客戶/服務器程序?
20
.
40
怎樣調用 BIOS 函數?寫 ISR?創建 TSR?
20
.
41
編譯程序, 編譯器出示 ``union REGS" 未定義錯誤信息, 連接器出示 ``int86()" 的未定義錯誤信息。
20
.
42
什麼是 ``near" 和 ``far" 指針?
20
.
43
我不能使用這些非標準、依賴系統的函數, 程序需要兼容 ANSI!
21
. 雜項
21
.
1
怎樣從一個函數返回多個值?
21
.
2
怎樣訪問命令行參數?
21
.
3
怎樣寫數據文件, 使之可以在不同字大小、字節順序或浮點 格式的機器上讀入?
21
.
4
怎樣調用一個由 char * 指針指向函數名的函數?
21
.
5
怎樣實現比特數組或集合?
21
.
6
怎樣判斷機器的字節順序是高字節在前還是低字節在前?
21
.
7
怎樣掉換字節?
21
.
8
怎樣轉換整數到二進制或十六進制?
21
.
9
我可以使用二進制常數嗎?有 printf() 的二 進制的格式符嗎?
21
.
10
什麼是計算整數中比特為 1 的個數的最有效的方法?
21
.
11
什麼是提高程序效率的最好方法?
21
.
12
指針真得比數組快嗎?函數調用會拖慢程序多少? ++i 比 i = i +1 快嗎?
21
.
13
人們說編譯器優化的很好, 我們不在 需要為速度而寫彙編了, 但我的編譯器連用移位代替 i/=2 都做不到。
21
.
14
怎樣不用臨時變量而交換兩個值?
21
.
15
是否有根據字符串做切換的方法?
21
.
16
是否有使用非常量 case 標誌的方法 (例如範圍或任意的表達式)?
21
.
17
return 語句外層的括號是否真的可選擇?
21
.
18
為什麼 C 註釋不能嵌套?怎樣註釋掉含有註釋的代碼?引用字符串 內的註釋是否合法?
21
.
19
C 是個偉大的語言還是別的?哪個其它語言可以寫象 a+++++b 這樣的代碼?
21
.
20
為什麼 C 沒有嵌套函數?
21
.
21
assert() 是什麼?怎樣用它?
21
.
22
怎樣從 C 中調用 FORTRAN (C++, BASIC, Pascal, Ada, LISP) 的函數?反之亦然?
21
.
23
有什麼程序可以做從 Pascal 或 Fortran (或 LISP, Ada, awk, ``老" C) 到 C 的轉換?
21
.
24
C++ 是 C 的超集嗎?可以用 C++ 編譯器來編譯 C 代碼嗎?
21
.
25
需要用到 ``近似" 的 strcmp, 比較兩個字符串的近似度, 並不需要完全一樣。
21
.
26
什麼是散列法?
21
.
27
由一個日期, 怎樣知道是星期幾?
21
.
28
(year%4 == 0) 是否足夠判斷潤年?2000 年是閏年嗎?
21
.
29
一個難題: 怎樣寫一個輸出自己源代碼的程序?
21
.
30
什麼是 ``達夫設備" (Duff's Device)?
21
.
31
下屆國際 C 混亂代碼競賽 (IOCCC) 什麼時候進行?哪裡可以找到當前和 以前的獲勝代碼?
21
.
32
[K&R1] 提到的關健字 entry 是什麼?
21
.
33
C 的名字從何而來?
21
.
34
``char" 如何發音?
21
.
35
``lvalue" 和 ``rvalue" 代表什麼意思?
21
.
36
哪裡可以取得本 FAQ (英文版) 的額外副本?
22
. 感謝
文獻
翻譯朱群英、孫雲, LaTeX2HTML 編譯 朱群英 (2005-06-23)