-
xzsdn_08



- 注册时间 01-04-2009
- 江苏徐州
- 发帖总数 641
|
- 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 (英文版) 的额外副本?
21.1 怎样从一个函数返回多个值? 可以传入多个指针指向不同的地址, 函数可以填入, 或者使函数返回一个包含了需要值的结构, 又或者理论上你可以使用全局变量。参见问题 4.4 和 7.6。
21.2 怎样访问命令行参数? 当 main() 被调用时, 它们储存在数组 argv 中。参见问题 8.2, 13.5 和 19.25。
参考资料: [K&R1, Sec. 5.11 pp. 110-114]; [K&R2, Sec. 5.10 pp. 114-118]; [ISO, Sec. 5.1.2.2.1]; [H&S, Sec. 20.1 p. 416]; [PCS, Sec. 5.6 pp. 81-2, Sec. 11 p. 159, pp. 339-40 Appendix F]; [Schumacher, ed., Sec. 4 pp. 75-85]。
21.3 怎样写数据文件, 使之可以在不同字大小、字节顺序或浮点格式的机器上读入?
最可移植的方法是是用文本文件 (通常是 ASCII), 用 fprintf() 写入, 用 fscanf() 读入, 或类似的函数。同理, 这也适用于网络协议。不必太相信那些说文本文件太大或读写太慢的论点。大多数现实情况下, 操作的效率是可接受的, 而可以在不同机器间交换和用标准工具就可以对其进行操作是个巨大的优势。
如果你必须使用二进制文件, 你可以通过使用某些标准格式来提高可移植性, 还可以利用已经写好的 I/O 函数库。这些格式包括: Sun 的 XDR (RFC 1014)、 OSI 的 ASN.1 (在 CCITT X.409 和 ISO 8825 ``Basic Encoding Rules" 中都有引用)、 CDF、 netCDF 或 HDF。参见问题 2.10 和 12.30。
参考资料: [PCS, Sec. 6 pp. 86, 88]。
21.4 怎样调用一个由 char * 指针指向函数名的函数? 最直接的方法就是维护一个名字和函数指针的列表:
int one_func(), two_func();
int red_func(), blue_func();
struct { char *name; int (*funcptr)(); } symtab[] = {
"one_func", one_func,
"two_func", two_func,
"red_func", red_func,
"blue_func",blue_func,
};
然后搜索函数名, 就可以调用关联的函数指针。参见问题 2.13, 18.13 和 19.35。
参考资料: [PCS, Sec. 11 p. 168]。
21.5 怎样实现比特数组或集合? 使用 int 或 char 数组, 再加上访问所需比特的几个宏。这里有一些简单的宏定义, 用于 char 数组:
#include <limits.h> /* for CHAR_BIT */
#define BITMASK(b) (1 << ((b) % CHAR_BIT))
#define BITSLOT(b) ((b) / CHAR_BIT)
#define BITSET(a, b) ((a)[BITSLOT(b)] |= BITMASK(b))
#define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))
如果你没有 <limits.h>, 可以定义 CHAR_BIT 为 8。
参考资料: [H&S, Sec. 7.6.7 pp. 211-216]。
21.6 怎样判断机器的字节顺序是高字节在前还是低字节在前? 有个使用指针的方法:
int x = 1;
if(*(char *)&x == 1)
printf("little-endian\n");
else
printf("big-endian\n");
另外一个可能是用联合。
参见问题 10.15 和 20.7。
参考资料: [H&S, Sec. 6.1.2 pp. 163-4]。
21.7 怎样掉换字节? V7 Unix 有一个 swap() 的函数, 但似乎被遗忘了。
使用明示的字节调换代码有个问题, 你必须决定是否要调用; 参见问题 20.6。更好的方法是使用函数 (例如 BSD 系统中网络函数 ntohs() 等), 函数会进行已知字符顺序和机器顺序 (未知) 之间的转换, 对于已经和机器匹配的字符顺序, 函数不作任何转换。
如果你必须自己写字符转换的代码, 两个明显的方法就是使用指针或联合, 就象问题 20.6 一样。
参考资料: [PCS, Sec. 11 p. 179]。
21.8 怎样转换整数到二进制或十六进制? 确定你真的知道你在问什么。整数是以二进制存储的, 虽然对于大多数情况下, 把它们当成是八进制、十进制或十六进制并没有错, 只要方便就好。数字表达的进制只有在读入或写出到外部世界时才起作用。
在源程序中, 非十进制的数字由在前的 0 或 0x 表示 (分别位八进制和十六进制)。在进行 I/O 操作时, 数字格式的进制在 printf 和 scanf 这类函数里, 由格式符决定 (%d, %o 和 %x 等); 在 strtol() 和 strtoul() 中, 则由他们的第三个参数决定。 如果你想要输出任意进制的数字字符串, 你需要自己提供相关的函数 (基本上是 strtol 的反函数)。在进行二进制 I/O 时, 进制就不相干了。
更多的有关二进制的 I/O, 参见问题 2.9。还有问题 8.4 和 13.1。
参考资料: [ISO, Secs. 7.10.1.5,7.10.1.6]。
21.9 我可以使用二进制常数吗?有 printf() 的二进制的格式符吗? 两个都不行。你可以用 strtol() 把二进制的字符串转换成整数。参见问题 20.8。
21.10 什么是计算整数中比特为 1 的个数的最有效的方法? 许多象这样的比特问题可以使用查找表格来提供效率和速度 (参见问题 20.11)。
21.11 什么是提高程序效率的最好方法?
选择好的算法, 小心地实现, 同时确定程序不做额外的事。例如, 即使世界上最优化的字符复制循环也比不上不用复制。
当担心效率时, 要保持几样事情在视野中, 这很重要。首先, 虽然效率是个非常流行的话题, 它并不总是象人们想的那样重要。大多数程序的大多数代码并不是时间紧要的。当代码不是时间紧要时, 通常把代码写得清楚和可移植比达到最大效率更重要。记住, 电脑运行得非常非常快, 那些看起来 ``低效率" 的代码, 也许可以编译得比较有效率, 而运行起来也没有明显的延时。
试图预知程序的 ``热点" 是个非常困难的事。当要关心效率时, 使用 profiling 软件来确定程序中需要得到关注的地方。通常, 实际计算时间都被外围任务占用了 (例如 I/O 或内存的分配), 可以通过使用缓冲和超高速缓存来提高速度。
即使对于时间紧要的代码, 最无效的优化技巧是忙乱于代码细节。许多常被建议的 ``有效的代码技巧", 即使是很简单的编译器也会自动完成 (例如, 用移位运算符代替二的幂次方乘)。非常多的手动优化有可能是代码变得笨重而使效率反而低下了, 同时几乎不可移植。例如, 也许可以在某台机器上提了速, 但在另一台机器上去变慢了。任何情况下, 修整代码通常最多得到线性信能提高; 更好的算法可以得到更好的回报。
有关效率的更多讨论, 以及当效率很重要时, 如何提高效率的建议, 可以从以下书中得到: Kernighan 和 Plauger 的 《The Elements of Programming Style》[K&P] 中的第七章, 和 Jon Bentley 的 《Writing Efficient Programs》[Bentley]。
21.12 指针真得比数组快吗?函数调用会拖慢程序多少? ++i 比 i = i +1 快吗? 这些问题的精确回答, 跟你所用的处理器和编译器有关。如果你必须知道, 你就得小心的给程序计时。通常, 差别是很小的, 小到要经过千万次迭代才能看到不同。如果可能, 查看编译器的汇编输出, 看看这两种方法是否被编译的一样。
一般的机器, 通常遍历大的数组时, 用指针比用数组要快, 但是某些处理器就相反。
函数调用, 虽然明显比内联代码要慢, 但是它对程序的模块化和代码清晰度的贡献, 很少有好的理由来避免它。
在修整象 i = i + 1 这样的代码前, 记住你是在跟编译器打交道, 而不是键击编程的计算器。对于 ++i, i += 1 和 i = i + 1, 任何好的编译器都会生成完全一样的代码。使用任何一种形式只跟风格有关, 于效率无关。参见问题 3.10。
21.13 人们说编译器优化的很好, 我们不在需要为速度而写汇编了, 但我的编译器连用移位代替 i/=2 都做不到。
i 是有符号还是无符号?如果是有符号, 移位并不等价 (提示: 想想如果 i 是个负的奇数), 所以编译器没有使用是对的。
21.14 怎样不用临时变量而交换两个值? 一个标准而古老的汇编程序员的技巧是:
a ^= b;
b ^= a;
a ^= b;
但是这样的代码在现代高级程序设计语言中没什么用处。临时变量基本上是自由使用的, 一般上的三个赋值是:
int t = a;
a = b;
b = t;
这不只对读者更清晰, 更有可能被编译器辨别出来而变成最有效的代码 (例如有可能使用 EXCH 指令)。后面的代码明显的可以用于指针和浮点值, 而不象 XOR 技巧只能用于整型。参见问题 3.4 和 10.2。
21.15 是否有根据字符串做切换的方法? 没有直接的方法。有些时候, 更适合使用一个单独的函数以映射字符串到整数代码, 然后根据整数代码做切换。否则, 你当然也可以使用 strcmp() 和传统的 if/else 链。参见问题 10.11, 20.16 和 20.26。
参考资料: [K&R1, Sec. 3.4 p. 55]; [K&R2, Sec. 3.4 p. 58]; [ISO, Sec. 6.6.4.2]; [H&S, Sec. 8.7 p. 248]。
21.16 是否有使用非常量 case 标志的方法 (例如范围或任意的表达式)? 没有。最初设计 switch 语句就是为编译器能简单的做转换, 所以 case 标志被限制在单个、整形、常量的表达式。如果你不介意详述的列出所有的情况, 你可以把几个 case 标志连到同个语句, 这样你可以覆盖一个小的范围。
如果你想要根据任意范围或非常量表达式进行选择, 你只能用 if/else 链。
参见问题 20.15。
参考资料: [K&R1, Sec. 3.4 p. 55]; [K&R2, Sec. 3.4 p. 58]; [ISO, Sec. 6.6.4.2]; [Rationale, Sec. 3.6.4.2]; [H&S, Sec. 8.7 p. 248]。
21.17 return 语句外层的括号是否真的可选择? 是的。
很久以前, 在 C 刚起步的时候, 它们是必须的, 刚好那时有足够的人学习了 C, 他们写的代码如今还在使用, 所以还是需要括号的想法被广泛的流传。
碰巧的是, 在某些起况下, sizeof 运算符的括号也是可选择的。
参考资料: [K&R1, Sec. A18.3 p. 218]; [ISO, Sec. 6.3.3, Sec. 6.6.6]; [H&S, Sec. 8.9 p. 254.]。
21.18 为什么 C 注释不能嵌套?怎样注释掉含有注释的代码?引用字符串内的注释是否合法? C 注释不能嵌套最可能的原因是 PL/I 的注释也不可以, C 是借鉴了它而成的。所以, 通常使用 #ifdef 或 #if 0 来 ``注释" 掉大段代码, 其中可能含有注释 (参见问题 11.20)。
字符序列 /* 和 */ 在双引号内的字符串没有特殊含义, 所以不要在其中加入注释, 程序可能想输出它们 (特别是要产生 C 代码作为输出的程序)。
注意 // 在 C99 中才成为合法的注释符。
参考资料: [K&R1, Sec. A2.1 p. 179]; [K&R2, Sec. A2.2 p. 192]; [ISO, Sec. 6.1.9, Annex F; Rationale Sec. 3.1.9]; [H&S, Sec. 2.2 pp. 18-9]; [PCS, Sec. 10 p. 130]。
21.19 C 是个伟大的语言还是别的?哪个其它语言可以写象 a+++++b 这样的代码? 在 C 中, 写成这样也是没有意义的。词汇分析的规则规定, 在一个简单的从左到右扫描中的每个点, 最长的记号被划分, 不管这样出来的记号序列是否有意义。问题中的片段被解释为:
a ++ ++ + b
语法上是个不合法的表达式。
参考资料: [K&R1, Sec. A2 p. 179]; [K&R2, Sec. A2.1 p. 192]; [ISO, Sec. 6.1]; [H&S, Sec. 2.3 pp. 19-20]。
21.20 为什么 C 没有嵌套函数? 实现嵌套函数不是件简单的事, 它们需要可以正当的访问包含函数的本地变量, 为了简单化, 这个功能是被故意舍弃的。gcc 的扩展功能允许函数嵌套。 许多可能使用嵌套函数的地方 (例如 qsort 的比较函数), 一个充分但少许麻烦的解决方法是使用一个定义为静态 (static) 的邻近函数, 如果需要, 可以通过少量静态变量进行通讯。一个干净些的方法是传递一个包含所需内容的结构指针, 虽然 qsort 不支持这种方法。
21.21 assert() 是什么?怎样用它? 这是个定义在 <assert.h> 中的宏, 用来测试断言。一个断言本质上是写下程序员的假设, 如果假设被违反, 那表明有个严重的程序错误。例如, 一个假设只接受非空指针的函数, 可以写:
assert(p != NULL);
一个失败的断言会中断程序。断言不应该用来捕捉意料中的错误, 例如 malloc() 或 fopen() 的失败。
参考资料: [K&R2, Sec. B6 pp. 253-4]; [ISO, Sec. 7.2]; [H&S, Sec. 19.1 p. 406]。
21.22 怎样从 C 中调用 FORTRAN (C++, BASIC, Pascal, Ada, LISP) 的函数?反之亦然? 这完全依赖于机器以及使用的各个编译器的特别调用顺序, 有可能完全做不到。仔细阅读编译器的文档, 有些时候有个 ``混合语言编程指南", 尽管传递参数以及保证正确的运行启动的技巧通常很晦涩难懂。
对于 FORTRAN, 更多的信息可以从 Glenn Geers 的 FORT.gz 找到, 这个文档可以从匿名 ftp 网站 suphys.physics.su.oz.au 的 src 目录取得。 Burkhard Burow 写的头文件 cfortran.h 简化了许多流行机器上的 C/FORTRAN 接口。可以从匿名 ftp 网站 zebra.desy.de 或 http://www-zeus.desy.de/~burow 取得。
C++ 中, 外部函数说明的 ``C" 修改量表明函数应该按 C 的调用约定使用。
参考资料: [H&S, Sec. 4.9.8 pp. 106-7]。
21.23 有什么程序可以做从 Pascal 或 Fortran (或 LISP, Ada, awk, ``老" C) 到 C 的转换? 有几个自由发布的程序可以使用: p2c 由 Dave Gillespie 写的 Pascal 到 C 的转换器, 发布于新闻组 comp.sources.unix 1990 年三月 (第 21 卷); 也可以从 ftp://csvax.cs.caltech.edu/pub/p2c-1.20.tar.Z 取得。
ptoc 另外一个 Pascal 到 C 的转换器, 它是用 Pascal 写的。 (comp.sources.unix, 第 10 卷, 补丁在 第 13 卷)。
f2c Fortran 到 C 的转换器, 由 Bell Labs, Bellcore 和 Carnegie Mellon 的人员共同开发的。可以用以下方法得到更多的 f2c 信息: 发 email 信息 ``send index from f2c" 到 netlib@research.att.com 或者 research!netlib。(在匿名 ftp 网站 netlib.att.com 的 netlib/f2c 目录也可取得。)
本 FAQ 的维护者也有一个别的转换器的列表。
参见问题 11.30 和 18.18。
21.24 C++ 是 C 的超集吗?可以用 C++ 编译器来编译 C 代码吗? C++ 源自 C, 而且大部分都建立在 C 的基础上, 但是有一些合法的 C 代码在 C++ 中不合法。相反的, ANSI C 继承了 C++ 的几个特性, 包括原型和常量, 所以这两个语言并不是另一个的超集或子集;而且它们在一些通用构造的定义上也不同。尽管有这些不同, 许多 C 程序在 C++ 环境中编译正确, 许多最新的编译器同时提供 C 和 C++ 的编译模式。但是, 把 C 代码当成 C++ 来编译通常是个坏的注意; 两个语言的差异普遍上足够让你得到不好的结果。 参见问题 8.5 和 20.18。
参考资料: [H&S, p. xviii, Sec. 1.1.5 p. 6, Sec. 2.8 pp. 36-7, Sec. 4.9 pp. 104-107]。
21.25 需要用到 ``近似" 的 strcmp, 比较两个字符串的近似度, 并不需要完全一样。
Sun Wu 和 Udi Manber 写的文章 ``AGREP - A Fast Approximate Pattern-Matching Toolciteagrep 中有一些有用的信息, 近似字符串匹配的算法以及有用的参考文献。
另外一个方法牵涉到 ``soundex" 算法, 它把发音相近的词映射到同一个代码。它是为发现近似发音的名字而设计的 (作为电话号码目录的帮助), 但是它可以调整用于任意词处理的服务。
参考资料: [Knuth, Sec. 6 pp. 391-2 Volume 3]; [AGREP]。
21.26 什么是散列法? 散列法是把字符串映射到整数的处理, 通常是到一个相对小的范围。一个 ``散列函数" 映射一个字符串 (或其它的数据结构) 到一个有界的数字 (散列存贮桶), 这个数字可以更容易的用于数组的索引或者进行反复的比较。明显的, 一个从潜在的有很多组的字符串到小范围整数的映射不是唯一的。任何使用散列的算法都要处理 ``冲突" 的可能。有许多散列函数和相关的算法被开发了出来; 一个全面的说明已经超出了本文的范围。
参考资料: [K&R2, Sec. 6.6]; [Knuth, Sec. 6.4 pp. 506-549 Volume 3]; [Sedgewick, Sec. 16 pp. 231-244]。
21.27 由一个日期, 怎样知道是星期几? 用 mktime() 或 localtime() (参见问题 13.11 和 13.12, 如果 tm_hour 的值位 0, 要注意 DST (夏时制) 的调整); 或者 Zeller 的 congruence (参阅 sci.math FAQ); 或者这个由 Tomohiko Sakamoto 提供的优雅的代码:
int dayofweek(int y, int m, int d) /* 0 = Sunday */
{
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
y -= m < 3;
return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}
参见问题 13.12 和 20.28。
参考资料: [ISO, Sec. 7.12.2.3]。
21.28 (year%4 == 0) 是否足够判断润年?2000 年是闰年吗? 这个测试并不足够 (2000 年是闰年)。对于当前用的格里高力历法, 完整的表达式为:
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
详情请参阅一本好的天文历法的书或其它参考资料。预防无休止的辩论; 那些主张还有一个 4000 年规则的参考资料是错的。参见问题 13.12。
21.29 一个难题: 怎样写一个输出自己源代码的程序? 要写一个可移植的自我再生的程序是件很困难的事, 部分原因是因为引用和字符集的难度。
这里是个经典的例子 (应该以一行表示的, 虽然第一次执行后它后自我修复):
char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";
main(){printf(s,34,s,34);}
这段程序有一些依赖, 忽略了 #include <stdio.h>, 还假设了双引号 " 的值为 34, 和 ASCII 中的值一样。
这里还有一个有 James Hu 发布的改进版:
#define q(k)main(){return!puts(#k"\nq("#k")");}
q(#define q(k)main(){return!puts(#k"\nq("#k")");})
21.30 什么是 ``达夫设备" (Duff's Device)? 这是个很棒的迂回循环展开法, 由 Tom Duff 在 Lucasfilm 时所设计。它的 ``传统" 形态, 是用来复制多个字节:
register n = (count + 7) / 8; /* count > 0 assumed */
switch (count % 8)
{
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while (--n > 0);
}
这里 count 个字节从 from 指向的数组复制到 to 指向的内存地址 (这是个内存映射的输出寄存器, 这也是为什么它没有被增加)。它把 swtich 语句和复制 8 个字节的循环交织在一起, 从而解决了剩余字节的处理问题 (当 count 不是 8 的倍数时)。相信不相信, 象这样的把 case 标志放在嵌套在 swtich 语句内的模块中是合法的。当他公布这个技巧给 C 的开发者和世界时, Duff 注意到 C 的 swtich 语法, 特别是 ``跌落" 行为, 一直是被争议的, 而 ``这段代码在争论中形成了某种论据, 但我不清楚是赞成还是反对"。
21.31 下届国际 C 混乱代码竞赛 (IOCCC) 什么时候进行?哪里可以找到当前和以前的获胜代码?
竞赛的时间表随着时间而变化; 当前详情请参考 http://www.ioccc.org/index.html。
竞赛的优胜者通常在 Usenix 会议上公布, 结果会在晚些时候公布在网上。前几年 (追述到 1984 年) 的获胜代码在 ftp.uu.net 有档案 (参见问题 18.18), 在目录 pub/ioccc/ 下; 参阅 http://www.ioccc.org/index.html。
21.32 [K&R1] 提到的关健字 entry 是什么? 它是保留起来允许可能有某些函数有多个不同名字的进入点, 就象 FORTRAN 那样。据所有人所知, 它从没被实现过 (也没人记得为它设想的语法是怎样的)。它被放弃了, 也不是 ANSI C 的关健字。参见问题 1.5。
参考资料: [K&R2, p. 259 Appendix C]
21.33 C 的名字从何而来? C 源自 Ken Thompson 的实验性语言 B, 而 B 由 Martin Richards 的 BCPL (Basic Combined Programming Language) 得到灵感, 而 BCPL 是 CPL (Combined Programming Language 或也许是 Cambridge Programming Language) 的简化版。有一段时间, 人们猜测 C 的后继者会命名为 P (BCPL 的第三个字母) 而不是 D, 当然, 如今最显见的后裔语言是 C++。
21.34 ``char" 如何发音? C 关健字 ``char" 至少有三种发音: 象英文词``char", ``care" 或 ``car" (又或者``character"); 你可以任选一个。
21.35 ``lvalue" 和 ``rvalue" 代表什么意思? 简单的说, ``lvalue" 是个可以出现在赋值语句左方的表达式; 你也可以把它想象成有地址的对象。有关数组的, 参见问题 6.5。``rvalue" 就是有值的表达式, 所以可以用在赋值语句的右方。
21.36 哪里可以取得本 FAQ (英文版) 的额外副本? 最新的副本可以从 ftp.eskimo.com 的目录 u/s/scs/C-faq/ 取得. 你也可以从网上下载。通常, 本 FAQ 在每个月的第一天会发布在新闻组 comp.lang.c。其中含有期限行, 应该可以保留一个月。同时, 还有一个简略的版本 (也发布在新闻组), 以及对于每一个有显著更新的版本, 都会有个改变列表。
本 FAQ 的各个版本也会发布在新闻组 comp.answers 和 news.answers。有几个网站归档了 news.answers 的帖子和其它 FAQ 单子, 包括本文; 其中的两个网站: rtfm.mit.edu (目录 pub/usenet/news.answers/C-faq/ 和 pub/usenet/comp.lang.c/); ftp.uu.net (目录 usenet/news.answers/C-faq/)。如果你没有 ftp 的访问, rtfm.mit.edu 有个邮件服务器可以电邮给你 FAQ 的名单: 发个只有一个词 ``help" 的电邮到 mail-server@rtfm.mit.edu。更多的信息, 请参阅 news.answers 中的 meta-FAQ。
本 FAQ 还有一个超文本 (HTML) 的版本在万维网上; URL http://www.eskimo.com/~scs/C-faq/top.html。一个非常全面的含有所有 Usenet FAQ 的网站是 http://www.faqs.org/faqs/。
本 FAQ 的扩展版本已经由 Addison-Wesley 出版了: 《C Programming FAQs: Frequently Asked Questions》 (ISBN 0-201-84519-9) [CFAQ]。勘误表在 http://www.eskimo.com/~scs/C-faq/book/Errata.html 以及 ftp://ftp.eskimo.com/u/s/scs/ftp/C-faq/book/Errata。
【译者注】 最新的 HTML 中译版本可以在 http://c-faq-chn.sourceforge.net/ 取得。另外在同一地址还提供 PDF 版本的下载。
22. 感谢
感谢:Jamshid Afshar, Lauri Alanko, Michael B. Allen, David Anderson, Jens Andreasen, Tanner Andrews, Sudheer Apte, Joseph Arceneaux, Randall Atkinson, Kaleb Axon, Daniel Barker, Rick Beem, Peter Bennett, Mathias Bergqvist, Wayne Berke, Dan Bernstein, Tanmoy Bhattacharya, John Bickers, Kevin Black, Gary Blaine, Yuan Bo, Mark J. Bobak, Anthony Borla, Dave Boutcher, Alan Bowler, breadbox@muppetlabs.com, Michael Bresnahan, Walter Briscoe, Vincent Broman, Robert T. Brown, Stan Brown, John R. Buchan, Joe Buehler, Kimberley Burchett, Gordon Burditt, Scott Burkett, Eberhard Burr, Burkhard Burow, Conor P. Cahill, D'Arcy J.M. Cain, Christopher Calabrese, Ian Cargill, Vinit Carpenter, Paul Carter, Mike Chambers, Billy Chambless, C. Ron Charlton, Franklin Chen, Jonathan Chen, Raymond Chen, Richard Cheung, Avinash Chopde, Steve Clamage, Ken Corbin, Dann Corbit, Ian Cottam, Russ Cox, Jonathan Coxhead, Lee Crawford, Nick Cropper, Steve Dahmer, Jim Dalsimer, Andrew Daviel, James Davies, John E. Davis, Ken Delong, Norm Diamond, Jamie Dickson, Bob Dinse, dlynes@plenary-software, Colin Dooley, Jeff Dunlop, Ray Dunn, Stephen M. Dunn, Andrew Dunstan, Michael J. Eager, Scott Ehrlich, Arno Eigenwillig, Yoav Eilat, Dave Eisen, Joe English, Bjorn Engsig, David Evans, Andreas Fassl, Clive D.W. Feather, Dominic Feeley, Simao Ferraz, Pete Filandr, Bill Finke Jr., Chris Flatters, Rod Flores, Alexander Forst, Steve Fosdick, Jeff Francis, Ken Fuchs, Tom Gambill, Dave Gillespie, Samuel Goldstein, Willis Gooch, Tim Goodwin, Alasdair Grant, W. Wesley Groleau, Ron Guilmette, Craig Gullixson, Doug Gwyn, Michael Hafner, Zhonglin Han, Darrel Hankerson, Tony Hansen, Douglas Wilhelm Harder, Elliotte Rusty Harold, Joe Harrington, Guy Harris, John Hascall, Adrian Havill, Richard Heathfield, Des Herriott, Ger Hobbelt, Sam Hobbs, Joel Ray Holveck, Jos Horsmeier, Syed Zaeem Hosain, Blair Houghton, Phil Howard, Peter Hryczanek, James C. Hu, Chin Huang, Jason Hughes, David Hurt, Einar Indridason, Vladimir Ivanovic, Jon Jagger, Ke Jin, Kirk Johnson, David Jones, Larry Jones, Morris M. Keesan, Arjan Kenter, Bhaktha Keshavachar, James Kew, Bill Kilgore, Darrell Kindred, Lawrence Kirby, Kin-ichi Kitano, Peter Klausler, John Kleinjans, Andrew Koenig, Thomas Koenig, Adam Kolawa, Jukka Korpela, Przemyslaw Kowalczyk, Ajoy Krishnan T, Anders Kristensen, Jon Krom, Markus Kuhn, Deepak Kulkarni, Yohan Kun, B. Kurtz, Kaz Kylheku, Oliver Laumann, John Lauro, Felix Lee, Mike Lee, Timothy J. Lee, Tony Lee, Marty Leisner, Eric Lemings, Dave Lewis, Don Libes, Brian Liedtke, Philip Lijnzaad, James D. Lin, Keith Lindsay, Yen-Wei Liu, Paul Long, Patrick J. LoPresti, Christopher Lott, Tim Love, Paul Lutus, Mike McCarty, Tim McDaniel, Michael MacFaden, Allen Mcintosh, J. Scott McKellar, Kevin McMahon, Stuart MacMartin, John R. MacMillan, Robert S. Maier, Andrew Main, Bob Makowski, Evan Manning, Barry Margolin, George Marsaglia, George Matas, Brad Mears, Wayne Mery, De Mickey, Rich Miller, Roger Miller, Bill Mitchell, Mark Moraes, Darren Morby, Bernhard Muenzer, David Murphy, Walter Murray, Ralf Muschall, Ken Nakata, Todd Nathan, Taed Nelson, Pedro Zorzenon Neto, Daniel Nielsen, Landon Curt Noll, Tim Norman, Paul Nulsen, David O'Brien, Richard A. O'Keefe, Adam Kolawa, Keith Edward O'hara, James Ojaste, Max Okumoto, Hans Olsson, Thomas Otahal, Lloyd Parkes, Bob Peck, Harry Pehkonen, Andrew Phillips, Christopher Phillips, Francois Pinard, Nick Pitfield, Wayne Pollock, Polver@aol.com, Dan Pop, Don Porges, Claudio Potenza, Lutz Prechelt, Lynn Pye, Ed Price, Kevin D. Quitt, Pat Rankin, Arjun Ray, Eric S. Raymond, Christoph Regli, Peter W. Richards, James Robinson, Greg Roelofs, Eric Roode, Manfred Rosenboom, J.M. Rosenstock, Rick Rowe, Michael Rubenstein, Erkki Ruohtula, John C. Rush, John Rushford, Kadda Sahnine, Tomohiko Sakamoto, Matthew Saltzman, Rich Salz, Chip Salzenberg, Matthew Sams, Paul Sand, DaviD W. Sanderson, Frank Sandy, Christopher Sawtell, Jonas Schlein, Paul Schlyter, Doug Schmidt, Rene Schmit, Russell Schulz, Dean Schulze, Jens Schweikhardt, Chris Sears, Peter Seebach, Gisbert W. Selke, Patricia Shanahan, Girija Shanker, Clinton Sheppard, Aaron Sherman, Raymond Shwake, Nathan Sidwell, Thomas Siegel, Peter da Silva, Andrew Simmons, Joshua Simons, Ross Smith, Thad Smith, Henri Socha, Leslie J. Somos, Eric Sosman, Henry Spencer, David Spuler, Frederic Stark, James Stern, Zalman Stern, Michael Sternberg, Geoff Stevens, Alan Stokes, Bob Stout, Dan Stubbs, Tristan Styles, Richard Sullivan, Steve Sullivan, Melanie Summit, Erik Talvola, Christopher Taylor, Dave Taylor, Clarke Thatcher, Wayne Throop, Chris Torek, Steve Traugott, Brian Trial, Nikos Triantafillis, Ilya Tsindlekht, Andrew Tucker, Goran Uddeborg, Rodrigo Vanegas, Jim Van Zandt, Momchil Velikov, Wietse Venema, Tom Verhoeff, Ed Vielmetti, Larry Virden, Chris Volpe, Mark Warren, Alan Watson, Kurt Watzka, Larry Weiss, Martin Weitzel, Howard West, Tom White, Freek Wiedijk, Stephan Wilms, Tim Wilson, Dik T. Winter, Lars Wirzenius, Dave Wolverton, Mitch Wright, Conway Yee, James Youngman, Ozan S. Yigit, and Zhuo Zang。他们为本文提供了直接或间接的贡献。
感谢对出版版本进行审核的:Mark Brader, Vinit Carpenter, Stephen Clamage, Jutta Degener, Doug Gwyn, Karl Heuer, and Joseph Kent. 感谢 Addison-Wesley 的 Debbie Lafferty 和 Tom Stone 的鼓励,以及允许从书中引入新的内容到本文。特别感谢 Karl Heuer, Jutta Degener, 特别是 Mark Brader, 他 (借用 Steve Johnson 的一句话) 为了不断的追求一个更好的 FAQ 而鞭策我超越自己的爱好,偶而超出了我的忍耐性。
Steve Summit
scs@eskimo.com
文献
ANSI American National Standards Institute, 《American National Standard for Information Systems - Programming Language - C》, ANSI X3.159-1989, (参见问题 11.2)
Rationale American National Standards Institute, 《Rationale for American National Standard for Information Systems - Programming Language - C》(参见问题 11.2)
Bentley Jon Bentley, 《Writing Efficient Programs》, Prentice-Hall, 1982, ISBN 0-13-970244-X.
Burki David Burki, ``Date Conversions," 《The C Users Journal》, February 1993, pp. 29-34.
LINT Ian F. Darwin, 《Checking C Programs with lint》, O'Reilly, 1988, ISBN 0-937175-30-7.
Goldberg David Goldberg, ``What Every Computer Scientist Should Know about Floating-Point Arithmetic," 《ACM Computing Surveys》, Vol. 23 #1, March, 1991, pp. 5-48.
H&S Samuel P. Harbison and Guy L. Steele, Jr., 《C: A Reference Manual》, Fourth Edition, Prentice-Hall, 1995, ISBN 0-13-326224-3. [There is also a fifth edition: 2002, ISBN 0-13-089592-X.]
PCS Mark R. Horton, 《Portable C Software》, Prentice Hall, 1990, ISBN 0-13-868050-7.
POSIX Institute of Electrical and Electronics Engineers, 《Portable Operating System Interface (POSIX) - Part 1: System Application Program Interface (API) [C Language]》, IEEE Std. 1003.1, ISO/IEC 9945-1.
ISO International Organization for Standardization, ISO 9899:1990 (参见问题 11.2)
C9X International Organization for Standardization, WG14/N794 Working Draft (参见问题 11.1 和 11.3)
K&P Brian W. Kernighan and P.J. Plauger, 《The Elements of Programming Style》, Second Edition, McGraw-Hill, 1978, ISBN 0-07-034207-5.
K&R1 Brian W. Kernighan and Dennis M. Ritchie, 《The C Programming Language》, Prentice-Hall, 1978, ISBN 0-13-110163-3.
K&R2 Brian W. Kernighan and Dennis M. Ritchie, 《The C Programming Language》, Second Edition, Prentice Hall, 1988, ISBN 0-13-110362-8, 0-13-110370-9. (参见问题 18.9)
Knuth Donald E. Knuth, 《The Art of Computer Programming》. Volume 1: 《Fundamental Algorithms》, Third Edition, Addison-Wesley, 1997, ISBN 0-201-89683-4. Volume 2: 《Seminumerical Algorithms》, Third Edition, 1997, ISBN 0-201-89684-2. Volume 3: 《Sorting and Searching》, Second Edition, 1998, ISBN 0-201-89685-0.
CT&P Andrew Koenig, 《C Traps and Pitfalls》, Addison-Wesley, 1989, ISBN 0-201-17928-8.
Marsaglia&Bray G. Marsaglia and T.A. Bray,``A Convenient Method for Generating Normal Variables," 《SIAM Review》, Vol. 6 #3, July, 1964.
P&M Stephen K. Park and Keith W. Miller, ``Random Number Generators: Good Ones are Hard to Find," 《Communications of the ACM》, Vol. 31 #10, October, 1988, pp. 1192-1201 (also technical correspondence August, 1989, pp. 1020-1024, and July, 1993, pp. 108-110).
Plauger P.J. Plauger, 《The Standard C Library》, Prentice Hall, 1992, ISBN 0-13-131509-9.
Plum Thomas Plum, 《C Programming Guidelines》, Second Edition, Plum Hall, 1989, ISBN 0-911537-07-4.
Press et al. William H. Press, Saul A. Teukolsky, William T. Vetterling, and Brian P. Flannery, 《Numerical Recipes in C》, Second Edition, Cambridge University Press, 1992, ISBN 0-521-43108-5.
Sedgewick Robert Sedgewick, 《Algorithms in C》, Addison-Wesley, 1990, ISBN 0-201-51425-7. (A new edition is being prepared; the first two volumes are ISBN 0-201-31452-5 and 0-201-31663-3.)
Simonyi&Heller Charles Simonyi and Martin Heller,``The Hungarian Revolution," 《Byte》, August, 1991, pp. 131-13.
Straker David Straker, 《C Style: Standards and Guidelines》, Prentice Hall, ISBN 0-13-116898-3.
CFAQ Steve Summit, 《C Programming FAQs: Frequently Asked Questions》, Addison- Wesley, 1995, ISBN 0-201-84519-9. [The book version of this FAQ list; see also http://www.eskimo.com/~scs/C-faq/book/Errata.html .]
Expert Peter van der Linden, 《Expert C Programming: Deep C Secrets》, Prentice Hall, 1994, ISBN 0-13-177429-8.
AGREP Sun Wu and Udi Manber, ``AGREP - A Fast Approximate Pattern-Matching Tool," USENIX Conference Proceedings, Winter, 1992, pp. 153-162.
Schumacher, ed. Schumacher, ed., Software Solutions in C。
IHSG 印第安山风格指南(参见问题 17.7)的修订版有另外一个参考书目。参见问题 18.9。
|
|