top/contents search

1. 声明与初始化

1.1 我应该如何选择要使用的整数类型?

1.2 为什么标准类型的尺寸没有被精确定义?

1.3 C 没有精确定义尺寸,所以我一直使用这样的 typedef:int16int32这样的 typedef。我可以根据我使用的机器,将这些 typedef 定义为int, short, long等等。这样应该可以解决所有问题,对吧?

1.4 在一个可以支持它的机器上,64 位类型应该是多少?

1.5 这个声明有什么问题?

char* p1, p2;
当我尝试使用p2.

1.6 我正在尝试声明一个指针并为其分配一些空间,但它不起作用。这段代码有什么问题?

char *p;
*p = malloc(10);

1.7 声明和定义全局变量和函数有什么最佳方法?

1.8 如何在 C 中实现不透明(抽象)数据类型?

1.9 如何创建一个“半全局”变量,即一个对分散在多个源文件中的几个函数私有的变量?

1.10 同一个声明的所有...静态函数或变量的所有声明是否都必须包含存储类别?静态?

1.11 ...是什么意思?extern是什么意思?

1.12 ...是什么?auto关键字有什么用?

1.13 使用 ... 和 ... 有什么区别?typedef#define定义用户自定义类型有什么区别?

1.14 我似乎无法成功定义一个链表。我试过

	typedef struct {
		char *item;
		NODEPTR next;
	} *NODEPTR;
但编译器给出了错误消息。C 中的结构不能包含指向自身的指针吗?

1.15 如何定义一对相互引用的结构?我试过

	typedef struct {
		int afield;
		BPTR bpointer;
	} *APTR;

	typedef struct {
		int bfield;
		APTR apointer;
	} *BPTR;
但编译器在第一个结构声明中使用BPTR时并不知道它。

1.16 这两个声明有什么区别?

	struct x1 { ... };
	typedef struct { ... } x2;

1.17 ...是什么意思?

typedef int (*funcptr)();
是什么意思?

1.18 我有声明

	typedef char *charp;
	const charp p;
为什么p变成const,而不是它指向的字符?

1.19 我不明白为什么我不能使用const值,例如

	const int n = 5;
	int a[n];

1.20 ...和...有什么区别?const char *p, char const *p,而char * const p?

1.20b

函数参数const是什么意思?这两个const

	int f(const * const p)
是什么意思?

1.21 如何构造复杂类型的声明,例如“指向返回指向返回指向char的指针的 N 个指针的数组”,或者如何理解类似复杂的声明?

1.22 一个函数如何能返回一个指向同类型函数的指针?我正在构建一个状态机,每个状态都有一个函数,每个函数都返回指向下一个状态的函数的指针。但我找不到声明函数的方法——我似乎需要一个返回指向函数指针的函数,该函数指针又返回一个函数指针...无穷无尽。

1.23 能否声明一个局部数组(或参数数组),其大小与传入的数组匹配,或由另一个参数设置?

1.24 我有一个extern数组定义在一个文件中,并在另一个文件中使用

file1.c:			file2.c:

int array[] = {1, 2, 3};	extern int array[];
为什么不sizeofarrayfile2.c?

1.25 我的编译器抱怨函数重声明无效,但我只定义和调用它一次。

1.25b ...的正确声明是什么?main?
void main()正确的吗?

1.26 我的编译器抱怨函数原型不匹配,但它们在我看来是好的。

1.27 我在文件的第一个声明中出现了一些奇怪的语法错误,但它看起来是正确的。

1.28 我的编译器不允许我声明一个像这样的数组

double array[256][256];

1.29 如何确定哪些标识符可以安全使用,哪些是保留的?

1.30 对于未显式初始化的变量和数组,我被允许假设它们的初始值是什么?
如果全局变量最初为“零”,这对空指针和浮点零是否足够好?

1.31 这段直接来自书籍的代码无法编译

int f()
{
	char a[] = "Hello, world!";
}

1.31b 此初始化有什么问题?

char *p = malloc(10);
我的编译器抱怨“无效的初始化列表”或类似的消息。

1.32 这些初始化之间有什么区别?

char a[] = "string literal";
char *p  = "string literal";
如果我尝试为p[i].

1.33char a[3] = "abc";合法的?

1.34 我终于弄明白了声明函数指针的语法,但现在如何初始化它?

1.35 可以初始化联合体吗?


2. 结构、联合和枚举

2.1 这两个声明有什么区别?

	struct x1 { ... };
	typedef struct { ... } x2;

2.2 为什么不...

struct x { ... };
x thestruct;
的函数调用是否会工作?

2.3 结构可以包含指向自身的指针吗?

2.4 如何在 C 中实现不透明(抽象)数据类型?

2.4b 有没有模拟 OOP 风格继承或其他 OOP 特征的好方法?

2.5 为什么声明

extern int f(struct x *p);
会在参数列表中给出关于“struct x 已声明”的晦涩警告消息?

2.6 我看到一些代码声明结构像这样

struct name {
	int namelen;
	char namestr[1];
};
然后进行了一些棘手的分配,使namestr数组表现得好像有几个元素,数量由namelen记录。这如何运作?这是合法的还是可移植的?

2.7 我听说结构可以赋值给变量并作为参数传递给函数,但 K&R1 说不行。

2.8 有办法自动比较结构吗?

2.9 结构传递和返回是如何实现的?

2.10 如何将常量值传递给接受结构参数的函数?如何创建无名、即时、常量结构值?

2.11 如何从数据文件中读取/写入结构?

2.12 为什么我的编译器会在结构中留空,浪费空间并阻止“二进制” I/O 到外部数据文件?我能否关闭此功能,或以其他方式控制结构字段的对齐?

2.13 为什么...sizeof报告的大小比我预期的结构类型要大,好像在末尾有填充?

2.14 如何确定字段在结构中的字节偏移量?

2.15 如何在运行时按名称访问结构字段?

2.16 C 是否有等同于 Pascal 的with语句吗?

2.17 如果数组名像数组基址的指针一样,为什么结构不是如此?

2.18 这个程序运行正常,但在结束时会核心转储。为什么?

	struct list {
		char *item;
		struct list *next;
	}

	/* Here is the main program. */

	main(argc, argv)
	{ ... }

2.19 结构和联合体之间有什么区别?

2.20 可以初始化联合体吗?

2.21 有没有自动跟踪联合体哪个字段正在使用的方法?

2.22 枚举和一组预处理器宏有什么区别?#define有什么区别?

2.23 枚举真的可以移植吗?
它们不像 Pascal 吗?

2.24 有没有简单的方法以符号方式打印枚举值?

2.25 我看到一些结构声明,字段旁边有冒号和数字,像这样

struct record {
	char *name;
	int refcount : 4;
	unsigned dirty : 1;
};
这是怎么回事?

2.26 人们为什么如此频繁地使用显式掩码和位操作代码,而不是声明位字段?


3. 表达式

3.1 为什么这段代码不...

a[i] = i++;
的函数调用是否会工作?

3.2 在我的编译器下,这段代码

int i = 7;
printf("%d\n", i++ * i++);
打印出 49。无论求值顺序如何,难道不应该打印出 56 吗?

3.3 我实验过代码

int i = 3;
i = i++;
有的给了i值为 3,有的给了 4。哪个编译器是正确的?

3.3b 这是一个很棒的表达式

a ^= b ^= a ^= b
它交换了abb

3.4 能否使用显式括号来强制我想要的求值顺序,并控制这些副作用?即使我不这样做,优先级不是也决定了它吗?

3.5 但是关于...&&||我看到像“
while((c = getchar()) != EOF && c != '\n')这样的代码'' ...

3.6 ...的右侧是否可以安全地假定?&&||运算符?

3.7 为什么...

printf("%d %d", f1(), f2());
先调用了f2?我以为逗号运算符保证了从左到右的求值。

3.8 如何理解像本节中的复杂表达式,并避免编写未定义的表达式?什么是“序列点”?

3.9 那么,如果我写

a[i] = i++;
并且我不关心a[]的哪个单元格被写入,这段代码就是正确的,并且i会增加一,对吗?

3.10a 人们一直在说,...的行为i = i++的行为是未定义的,但我刚刚在一个符合 ANSI 标准的编译器上尝试了它,并得到了我预期的结果。

3.10b 人们告诉我,如果我评估了一个未定义的表达式,或者访问了一个未初始化的变量,我会得到一个随机的、垃圾值。但我试过了,得到了。这是怎么回事?

3.11 如果我不想学习复杂的规则,我该如何避免这些未定义的求值顺序问题?

3.12a ...和...有什么区别?++ii++?

3.12b 如果我不使用表达式的值,我应该使用++ii++来递增变量吗?

3.13 我需要检查一个数字是否在另外两个数字之间。为什么不...

if(a < b < c)
的函数调用是否会工作?

3.14 为什么这段代码不...

int a = 1000, b = 1000;
long int c = a * b;
的函数调用是否会工作?

3.14b 如何确保整数算术不会溢出?

3.15 为什么代码...

double degC, degF;
degC = 5 / 9 * (degF - 32);
总是给我 0?

3.16 我有一个复杂的表达式,我必须根据条件将其分配给两个变量中的一个。我可以使用这样的代码吗?

	((condition) ? a : b) = complicated_expression;

3.17 我有一些代码包含像...这样的表达式

a ? b = c : d
之类的表达式,有些编译器接受它,但有些则不接受。

3.18 警告“...的语义”是什么意思?>`

3.19 “无符号保留”和“值保留”规则之间有什么区别?


4. 指针

4.1 指针到底有什么用?

4.2 我正在尝试声明一个指针并为其分配一些空间,但它不起作用。这段代码有什么问题?

char *p;
*p = malloc(10);

4.3 ...吗?*p++递增p或者它指向的对象?

4.4 我正在尝试使用指针来操作一个...数组int数组。这段代码有什么问题?

	int array[5], i, *ip;
	for(i = 0; i < 5; i++) array[i] = i;
	ip = array;
	printf("%d\n", *(ip + 3 * sizeof(int)));
我期望最后一行打印 3,但它打印的是垃圾值。

4.5 我有一个char *指针,它碰巧指向一些int,我想逐个遍历它们。为什么不行?

((int *)p)++;
的函数调用是否会工作?

4.6 为什么我不能对...执行算术运算?void *指针执行算术运算?

4.7 我有一些代码试图解包外部结构,但它因“未对齐访问”的消息而崩溃。这是什么意思?

4.8 我有一个函数接受并应该初始化一个指针

	void f(int *ip)
	{
		static int dummy = 5;
		ip = &dummy;
	}
但是当我像这样调用它时
	int *ip;
	f(ip);
调用者中的指针保持不变。

4.9 假设我想写一个接受通用指针作为参数的函数,并且我想模拟通过引用传递它。我能给形式参数类型void **,并执行类似这样的操作?

	void f(void **);
	double *dp;
	f((void **)&dp);

4.10 我有一个函数

	extern int f(int *);
它接受一个指向int的指针。我该如何通过引用传递一个常量?像这样的调用
	f(&5);
似乎行不通。

4.11 C 甚至有“引用传递”吗?

4.12 我见过用于通过指针调用函数的不同语法。这是怎么回事?

4.13 什么是总的通用指针类型?当我尝试将函数指针塞进一个...时,我的编译器抱怨void *.

4.14 整数如何转换为指针,反之亦然?我能否暂时将整数塞进指针,或反之?

4.15 如何将一个...int转换为char *?我尝试了强制类型转换,但它不起作用。

4.16 这个声明有什么问题?

char* p1, p2;
当我尝试使用p2.

4.17 “近”指针和“远”指针是什么意思?


5. 空指针

5.1 这个臭名昭著的空指针到底是什么?

5.2 如何在我的程序中获得空指针?

5.3 缩写的指针比较“...if(p)”用于检查非空指针是否有效?如果空指针的内部表示不是零呢?

5.4 ...是什么?NULL,它是如何定义的?

5.5 应该如何...NULL应该如何定义?

5.6 如果...NULL定义如下:

	#define NULL ((char *)0)
那么传递未转换的NULL的函数调用是否会工作?

5.7 我的供应商提供了一些头文件,它们...#define NULL0L。这是为什么?

5.8 是...NULL是否有效?

5.9 如果...NULL0作为空指针常量是等效的,我应该使用哪一个?

5.10 但使用...会不会更好?NULL的值改变(可能在具有非零内部空指针的机器上),使用0(而不是NULL)不是更好吗?

5.11 我曾经用过一个需要...的编译器。NULL没有被使用,它就无法工作。

5.12 我使用预处理器宏

#define Nullptr(type) (type *)0
来帮助我构建正确类型的空指针。

5.13 这很奇怪。NULL保证是0,但空指针却不是?

5.14 为什么围绕空指针会有这么多困惑?为什么这些问题如此频繁地出现?

5.15 我很困惑。我就是无法理解所有这些空指针的东西。

5.16 考虑到围绕空指针的困惑,要求它们在内部表示为零会不会更简单?

5.17 严重地,真的有实际机器使用非零空指针,或者对不同类型的指针使用不同的表示吗?

5.18 运行时值为 0 的整数,强制转换为指针,是否保证为空指针?

5.19 如何访问位于机器地址 0 的中断向量?如果我将指针设置为0,编译器可能会将其转换为某个非零的内部空指针值。

5.20 运行时“空指针赋值”错误是什么意思?如何跟踪它?


6. 数组和指针

6.1 我有定义char a[6],而在另一个文件中,我声明了extern char *a。为什么它不起作用?

6.2 但我听说...char a[]char *a.

6.3 那么 C 中“指针和数组的等价性”是什么意思?

6.4 如果它们如此不同,那么为什么数组和指针声明作为函数形式参数是可互换的?

6.4b 那么数组是按引用传递的,即使 C 的其余部分是按值传递的?

6.5 为什么我不能这样做?

	extern char *getpass();
	char str[10];
	str = getpass("Enter password: ");

6.6 如果不能对数组赋值,那么如何...

	int f(char str[])
	{
		if(str[0] == '\0')
			str = "none";
		...
	}
的函数调用是否会工作?

6.6b 还有这个呢?这难道不是数组赋值吗?

	char a[] = "Hello, world!\n";

6.7 既然不能给数组赋值,数组如何成为左值?

6.8 实际上,数组和指针的区别是什么?

6.9 有人向我解释说数组实际上就是常量指针。

6.10 我仍然很困惑。指针是一种数组,还是数组是一种指针?

6.11 我遇到了一些“笑话”代码,其中包含“表达式”5["abcdef"]这怎么会是合法的 C 代码?

6.12 由于数组引用会衰减为指针,如果arr是一个数组,那么arr&arr?

6.13 如何声明指向数组的指针?

6.14 如何在运行时设置数组的大小?
我怎样才能避免使用固定大小的数组?

6.15 如何声明与传入数组大小匹配的局部数组?

6.16 如何动态分配多维数组?

6.17 这是一个很棒的技巧:如果我写

	int realarray[10];
	int *array = &realarray[-1];
我可以把array当作是基于 1 的数组。

6.18 当我将二维数组传递给期望指向指针的指针的函数时,我的编译器抱怨了。

6.19 如何编写接受二维数组的函数,但宽度在编译时未知?

6.20 在将静态和动态分配的多维数组传递给函数时,如何可互换地使用它们?

6.21 为什么不...sizeof当数组是函数参数时,不能正确报告数组的大小?我有一个测试例程

	f(char a[10])
	{
		int i = sizeof(a);
		printf("%d\n", i);
	}
它打印 4,而不是 10。

6.22 在声明数组的文件中,代码如何...extern(即,它在一个其他文件中定义,并确定其大小)确定数组的大小?sizeof似乎行不通。

6.23 我想知道数组中有多少个元素,但是...sizeof返回字节大小。

6.24 有没有办法拥有一个位数组?


7. 内存分配

7.1 为什么这段代码片段不起作用?

	char *answer;
	printf("Type something:\n");
	gets(answer);
	printf("You typed \"%s\"\n", answer);

7.2 我无法让...strcat工作。我试过

	char *s1 = "Hello, ";
	char *s2 = "world!";
	char *s3 = strcat(s1, s2);
但我得到了奇怪的结果。

7.3 但是 man 页strcat说它接受两个char *作为参数。我应该如何知道分配内存?

7.3b 我刚才试了这段代码

char *p;
strcpy(p, "abc");
它居然能运行。怎么回事?为什么没有崩溃?

7.3c 指针变量分配多少内存?

7.4 我正在用这段代码从文件中读取行到数组中

	char linebuf[80];
	char *lines[100];
	int i;

	for(i = 0; i < 100; i++) {
		char *p = fgets(linebuf, 80, fp);
		if(p == NULL) break;
		lines[i] = p;
	}
为什么所有行最终都包含最后一行副本?

7.5a 我有一个函数应该返回一个字符串,但当它返回给调用者时,返回的字符串是垃圾。

7.5b 那么返回字符串或其他聚合体的正确方法是什么?

7.6 为什么我对调用...的“警告:从整数赋值指针缺少类型转换”malloc?

7.7 为什么有些代码会仔细地转换...的返回值?malloc返回的值转换为正在分配的指针类型?

7.7b 转换...有什么问题?malloc的返回值有什么问题?

7.7c 在调用...中malloc时,像“无法将 `void *' 转换为 `int *''' 这样的错误是什么意思?

7.8 我看到像这样的代码

	char *p = malloc(strlen(s) + 1);
	strcpy(p, s);
难道不应该是malloc((strlen(s) + 1) * sizeof(char))?

7.9 我写了一个小的包装器malloc,但它不工作

	#include <stdio.h>
	#include <stdlib.h>

	mymalloc(void *retp, size_t size)
	{
		retp = malloc(size);
		if(retp == NULL) {
			fprintf(stderr, "out of memory\n");
			exit(EXIT_FAILURE);
		}
	}

7.10 我正在尝试声明一个指针并为其分配一些空间,但它不起作用。这段代码有什么问题?

char *p;
*p = malloc(10);

7.10a 此初始化有什么问题?

char *p = malloc(10);
我的编译器抱怨“无效的初始化列表”或类似的消息。

7.10b 如何关闭...给我的“警告:可能的指针对齐问题”消息?lint对...的每一次调用?malloc?

7.11 如何动态分配数组?

7.12 如何查找有多少可用内存?

7.13 应该如何...应该做什么?返回一个空指针还是指向 0 字节的指针?

7.14 我听说有些操作系统实际上并没有分配...malloc分配的内存,直到程序试图使用它。这合法吗?

7.15 malloc返回了奇怪的指针值,但我确实读了问题 7.6,并且我包含了这一行

	extern void *malloc();
在我调用它之前。

7.16 我正在为一些数字工作分配一个大数组,使用以下行

	double *array = malloc(300 * 300 * sizeof(double));
malloc没有返回 null,但程序行为异常,就好像它覆盖了内存,或者malloc没有分配我要求的那么多,或者诸如此类的。

7.17 我的 PC 有 8MB 内存。为什么我似乎只能...malloc640K 左右?

7.18 我的应用程序严重依赖节点对数据结构的动态分配,而...malloc/free的开销正成为瓶颈。我该怎么办?

7.19 我的程序正在崩溃,似乎在某个地方卡在...malloc内部,但我看不出有什么不对。是malloc?

7.19b

我正在动态分配一个数组,像这样

	int *iarray = (int *)malloc(nints);
malloc没有返回 NULL,但代码不起作用。

7.20 你不能在使用后使用动态分配的内存,对吗?

7.21 为什么在调用...之后指针不是空的?free?
释放指针后使用(赋值、比较)指针值有多不安全?

7.22 当我打电话给...malloc为一个函数中的局部指针分配内存时,我是否必须显式地free它?

7.23 我正在分配包含指向其他动态分配对象的指针的结构。当我释放一个结构时,是否也必须释放每个附属指针?

7.24 在程序退出前必须释放分配的内存吗?

7.25 我有一个程序,它...malloc了很多内存,之后又free了很多内存,但从操作系统上看,内存使用量并没有真正减少。

7.26 ...是如何工作的?free如何知道需要释放多少字节?

7.27 那么我能否查询 malloc 包以找出分配块的大小?

7.28 为什么不...sizeof能否告诉我一个指针指向的内存块的大小?

7.29 动态分配了数组(如问题 6.14 所示),能否更改其大小?

7.30 将空指针作为第一个参数传递给...是否合法?realloc是否合法?为什么会有人这样做?

7.31 ...和...有什么区别?callocmalloc?我应该使用哪个?利用calloc的零填充是否安全?free是否适用于用calloc分配的内存,还是需要cfree?

7.32 ...是什么?alloca为什么不推荐使用它?


8. 字符和字符串

8.1 为什么不...

strcat(string, '!');
的函数调用是否会工作?

8.2 我正在检查一个字符串是否与特定值匹配。为什么这段代码不起作用?

	char *string;
	...
	if(string == "value") {
		/* string matches "value" */
		...
	}

8.3 如果我说...

	char a[] = "Hello, world!";
为什么我说不行
	char a[14];
	a = "Hello, world!";

8.4 我无法让...strcat工作。我试过

	char *s1 = "Hello, ";
	char *s2 = "world!";
	char *s3 = strcat(s1, s2);
但我得到了奇怪的结果。

8.5 这些初始化之间有什么区别?

char a[] = "string literal";
char *p  = "string literal";
如果我尝试为p[i].

8.6 如何获取与字符对应的数值(即 ASCII 或其他字符集代码),反之亦然?

8.7 C 是否有像其他语言中存在的“substr”(提取子字符串)例程?

8.8 我正在将用户输入的字符串读入数组,然后稍后打印它们。当用户输入像...这样的序列时\n,为什么它没有被正确处理?

8.9 我觉得我的编译器有问题:我刚注意到sizeof('a')是 2,而不是 1(即不是sizeof(char)).

8.10 我开始考虑多国字符集,并且我担心让...的影响sizeof(char)成为 2 以便表示 16 位字符集。


9. 布尔表达式和变量

9.1 C 中布尔值应该使用什么类型?是否有标准类型?我应该使用...#define或枚举类型来表示真和假值吗?

9.2 #define ...不是吗?TRUE定义为 1 是否危险,因为在 C 语言中任何非零值都被认为是“真”?如果内置的逻辑运算符或关系运算符“返回”的值不是 1 怎么办?

9.3 是...if(p)这样的表达式,其中p是指针,是否是有效且可移植的测试?

9.4 我应该使用符号名称,如...TRUEFALSE这样的符号名称来表示布尔常量,还是使用普通的 1 和 0?

9.5 我开始使用的第三方头文件定义了自己的...TRUEFALSE值与我已开发的的代码不兼容。我该怎么办?


10. C 预处理器

10.1 我正在尝试定义一些简单的类似函数的宏,例如

	#define square(x) x * x
但它们并不总是有效。

10.2 这里有一些有趣的预处理器宏

	#define begin	{
	#define end	}
有了它们,我就可以编写更像 Pascal 的 C 代码。你们觉得怎么样?

10.3 如何编写一个通用的宏来交换两个值?

10.4 编写多语句宏的最佳方法是什么?

10.5 使用 ... 和 ... 有什么区别?typedef#define定义用户自定义类型有什么区别?

10.5b ...和...有什么区别?

	const MAXSIZE = 100;
and
	#define MAXSIZE 100

10.6 我正在将程序拆分成多个源文件,这是我第一次这样做,我正在考虑把什么放在....c文件中放入什么,又该在.h文件中放入什么。(“.h” 到底是什么意思?)

10.7 一个头文件可以...#include另一个?

10.8a ...和...有什么区别?#include <>#include "" ?

10.8b 头文件搜索的完整规则是什么?

10.9 我在文件的第一个声明中出现了一些奇怪的语法错误,但它看起来是正确的。

10.10 我正在使用随附两个不同第三方库的头文件,它们“好心地”定义了公共宏,例如TRUE, FALSE, Min(),而Max(),但它们的定义相互冲突,也与我自己在头文件中已建立的定义冲突。我该怎么办?

10.10b 我正在 #include 我正在使用的库函数的正确头文件,但是链接器总是说它是未定义的。

10.11 我正在编译一个程序,似乎缺少它需要的一个头文件。有人能寄给我一份副本吗?

10.12 如何构造预处理器#if表达式来比较字符串?

10.13 ...是否?sizeof运算符在预处理器#if指令中是否有效?

10.14 能使用...#ifdef#define一行使用,像这样以两种不同的方式定义东西?

	#define a b \
	#ifdef whatever
		c d
	#else
		e f g
	#endif

10.15 有没有像...这样的东西?#ifdef对于typedef有什么区别?

10.16 如何使用预处理器...#if表达式来判断机器的字节顺序是大端还是小端?

10.17 我在...行内出现了一些奇怪的语法错误#ifdef过的行里遇到了奇怪的语法错误。

10.18 我继承了一些代码,其中包含太多的...#ifdef's。如何在不运行预处理器并展开所有#include's 和#define's 的情况下,将代码预处理以仅留下一个条件编译集?

10.19 如何列出所有预定义的标识符?

10.20 我有一些旧代码尝试用像...这样的宏来构造标识符

#define Paste(a, b) a/**/b
这样的宏来构造标识符,但它不再起作用了。

10.21 我有一个旧宏

#define CTRL(c) ('c' & 037)
,它似乎不再起作用了。

10.22 为什么宏...

	#define TRACE(n) printf("TRACE: %d\n", n)
会给我一个警告“字符串字面量中的宏替换”?它似乎正在扩展
	TRACE(count);
	printf("TRACE: %d\count", count);

10.23 如何在宏扩展中的字符串字面量中使用宏参数?

10.24 我正在尝试使用 ANSI 的“字符串化”预处理运算符`#' 来将符号常量的值插入到消息中,但它总是字符串化宏的名称而不是它的值。

10.25 我有一些棘手的预处理要做,而且我找不到方法来做。

10.26 如何编写一个接受可变数量参数的宏,或者使用预处理器来“关闭”一个带有可变数量参数的函数调用?

10.27 如何包含...的扩展?__FILE____LINE__宏的展开?


11. ANSI/ISO 标准 C

11.1 “ANSI C 标准”是什么?

11.2 如何获取标准副本?

11.2b 从哪里可以获得有关标准更新的信息?

11.3 我的 ANSI 编译器在看到...时抱怨不匹配

	extern int func(float);

	int func(x)
	float x;
	{ ...

11.4 可以混合旧式和新式函数语法吗?

11.5 为什么声明...

extern int f(struct x *p);
会在参数列表中给出关于“struct x 已声明”的晦涩警告消息?

11.6 我遇到了一个令人沮丧的问题,最终是由...行引起的

	printf("%d", n);
其中n实际上是一个long int。我认为 ANSI 函数原型应该可以防止此类参数类型不匹配。

11.7 我听说你必须...#include 在调用printf。这是为什么?

11.8 我不明白为什么我不能使用const值,例如

	const int n = 5;
	int a[n];

11.8b 如果你不能修改字符串字面量,为什么它们不被定义为...的数组?const数组?

11.9 ...和...有什么区别?const char *p, char const *p,而char * const p?

11.10 为什么我不能传递一个...char **给需要const char **?

11.11 我有声明

	typedef char *charp;
	const charp p;
为什么p变成const,而不是它指向的字符?

11.11b ...和...有什么区别?

	const MAXSIZE = 100;
and
	#define MAXSIZE 100

11.12a ...的正确声明是什么?main()?

11.12b 可以声明...mainvoid,以关闭那些恼人的“main函数无返回值”消息?

11.13 但...呢?main的第三个参数,envp?

11.14a 我认为声明...void main()不会失败,因为我调用了exit而不是返回,而且无论如何我的操作系统都会忽略程序的退出/返回状态。

11.14b 那么有什么可能出错?真的有系统会...void main()无效?

11.15 我一直在使用的书,《C Programing for the Compleat Idiot》,总是使用...void main().

11.16 是...exit(status)真正等同于从status返回main?

11.17 我正在尝试使用 ANSI 的“字符串化”预处理运算符`#' 来将符号常量的值插入到消息中,但它总是字符串化宏的名称而不是它的值。

11.18 “宏替换在字符串字面量中”的警告信息是什么意思?

11.19 我在...行内出现了一些奇怪的语法错误#ifdef过的行里遇到了奇怪的语法错误。

11.20 ...是什么?#pragma以及它们有什么用?

11.21 “...”是什么意思?#pragma once”是什么意思?我在一些头文件中找到了它。

11.22 是...char a[3] = "abc";合法的吗?它是什么意思?

11.23 由于数组引用会衰减为指针,如果arr是一个数组,那么arr&arr?

11.24 为什么我不能对...执行算术运算?void *指针执行算术运算?

11.25 ...和...有什么区别?memcpymemmove?

11.26 应该如何...应该做什么?返回一个空指针还是指向 0 字节的指针?

11.27 为什么 ANSI 标准对外部标识符的长度和大小写敏感性设置了限制?

11.28 ...是什么?noalias它去哪了?

11.29a 我的编译器拒绝了最简单的测试程序,出现了各种语法错误。它抱怨...的第一行

	main(int argc, char **argv)
	{
		return 0;
	}

11.29b “自动聚合初始化是 ANSI 功能”是什么意思?我的编译器抱怨有效的 ANSI 代码。

11.30 为什么一些 ANSI/ISO 标准库函数显示为未定义,尽管我有一个 ANSI 编译器?

11.31 有没有工具可以将旧式 C 程序转换为 ANSI C,反之亦然,或者自动生成原型?

11.32 为什么 Frobozz Magic C 编译器(声称符合 ANSI 标准)不接受这段代码?我知道这段代码是 ANSI 的,因为...gcc接受它。

11.33 人们似乎很重视区分实现定义的、未指定的和未定义的行为。这些是什么意思?

11.33b 一个程序“合法”、“有效”或“符合”是什么意思?

11.34 我很震惊 ANSI 标准将如此多的问题留为未定义。难道标准的工作不是标准化这些事情吗?

11.35 人们一直在说,...的行为i = i++的行为是未定义的,但我刚刚在一个符合 ANSI 标准的编译器上尝试了它,并得到了我预期的结果。


12. Stdio

12.1 这段代码有什么问题?

char c;
while((c = getchar()) != EOF) ...

12.1b 我有一个简单的程序,它读取字符直到 EOF,但我如何实际从键盘输入那个“EOF”值?我看到...EOF中定义为-1;我应该输入-1吗?

12.2 为什么简单的行复制循环...while(!feof(infp)) { fgets(buf, MAXLINE, infp); fputs(buf, outfp); }会复制最后一行两次?

12.3 我正在使用...fgets将文件中的行读取到指针数组中。为什么所有行最终都包含最后一行副本?

12.4 我的程序的提示和中间输出并不总是显示在屏幕上,尤其是在我通过另一个程序管道输出时。

12.5 如何一次读取一个字符,而不必等待 RETURN 键?

12.6 如何打印一个...'%'格式字符串中打印一个printf,但不起作用。\%

12.7 为什么不...

long int n = 123456;
printf("%d\n", n);
的函数调用是否会工作?

12.8 我以为 ANSI 函数原型应该可以防止参数类型不匹配。

12.9 有人告诉我使用...是错误的%lfwithprintf是不对的。如何printf使用%f用于类型double,如果scanf需要%lf?

12.9b 什么...printf这样的size_t使用什么格式化字符串,而我不知道它是long还是其他类型?

12.10 如何使用...实现可变字段宽度?printf也就是说,不是像%8d那样,而是希望宽度在运行时指定。

12.11 如何打印带逗号分隔千位的数字?
货币格式的数字呢?

12.12 为什么调用...scanf("%d", i)的函数调用是否会工作?

12.12b 为什么调用......

char s[30];
scanf("%s", s);
在传递给&scanfscanf.

12.13 为什么这段代码不...

double d;
scanf("%f", &d);
的函数调用是否会工作?

12.14 为什么这段代码不...

short int s;
scanf("%d", &s);
的函数调用是否会工作?

12.15 如何在...中指定可变宽度?scanf格式字符串?

12.16 如何从具有特定格式的数据文件中读取数据?
如何读取十个浮点数而不必使用一个费劲的scanf格式
字符串,例如"%f %f %f %f %f %f %f %f %f %f"?
如何将一行中任意数量的字段读取到数组中?

12.17 当我用...从键盘读取数字时scanf和 y"%d\n"格式,就像这样

	int n;
	scanf("%d\n", &n);
	printf("you typed %d\n", n);
它似乎会挂起,直到我输入额外的行。

12.18a 我正在读取一个数字...scanf%d读取一个数字,然后使用gets():

	int n;
	char str[80];

	printf("enter a number: ");
	scanf("%d", &n);
	printf("enter a string: ");
	gets(str);
	printf("you typed %d and \"%s\"\n", n, str);
读取一个字符串,但编译器似乎跳过了对gets()!

12.18b 我正在使用...scanf %c来读取Y/N的响应,但之后的输入被跳过了。

12.19 我想我可以用...scanf通过检查其返回值来确保用户输入了我期望的数字值,从而使其更安全

	int n;

	while(1) {
		printf("enter a number: ");
		if(scanf("%d", &n) == 1)
			break;
		printf("try again: ");
	}

	printf("you typed %d\n", n);
但有时它似乎会进入无限循环。为什么?[脚注]

12.20 为什么大家都说不要使用...scanf?我应该用什么来替代?

12.21 如何确定任意...的格式化字符串需要多少目标缓冲区空间?sprintf调用所需的缓冲区空间有多大?我如何避免目标缓冲区溢出?sprintf?

12.22 ...是怎么回事?sprintf的返回值有什么说法?它返回的是一个intchar *?

12.23 为什么大家都说不要使用...gets()?

12.24 我以为我会检查...errno在一长串printf调用之后,看看它们是否有失败的。

	errno = 0;
	printf("This\n");
	printf("is\n");
	printf("a\n");
	printf("test.\n");
	if(errno != 0)
		fprintf(stderr, "printf failed: %s\n", strerror(errno));
当我将输出重定向到文件时,为什么它会打印出像“printf failed: Not a typewriter”(printf 失败:不是打字机)这样的奇怪信息?

12.25 ...和...有什么区别?fgetpos/fsetposftell/fseek?
什么是fgetposfsetpos有什么好处?

12.26a 如何刷新挂起的输入,以便用户的输入不会在下一个提示时被读取?fflush(stdin)的函数调用是否会工作?

12.26b 如果...fflush不起作用,我能用什么来刷新输入?

12.27 我写了这个例程,它应该打开一个文件

	myfopen(char *filename, FILE *fp)
	{
		fp = fopen(filename, "r");
	}
但是当我像这样调用它时
		FILE *infp;
		myfopen("filename.dat", infp);
infp变量在调用者中未能正确设置。

12.28 我甚至无法获得一个简单的...fopen调用工作!这个调用有什么问题?

	FILE *fp = fopen(filename, 'r');

12.28b 如何打开像“...”这样的文件名?file1'', ``file2'', ``file3'' 等文件,其中数字部分由变量控制?基本上我想要 ``file%d'',就像printf.

12.29 fopen在某些路径名下失败。

12.30 我正在尝试原地更新文件,通过使用...fopenmode"r+"读取一个字符串,然后写回一个修改后的字符串,但它不起作用。

12.31 如何在文件的中间插入或删除一行(或记录)?

12.32 如何在给定打开的流的情况下恢复文件名?

12.33 如何重定向...stdinstdout到程序中的一个文件?

12.34 一旦我使用了...freopen,我该如何找回原来的stdout(或stdin)?

12.35 如何判断标准输入或输出是否被重定向(即“...”是否)?<'' 或 ``>”?

12.36 我正在尝试编写一个像“...”这样的程序more'' 的程序。如果stdin被重定向了,我该如何回到交互式键盘?

12.36b 如何安排将输出同时发送到两个地方,例如屏幕和文件?

12.37 我想以字节为单位在文件和内存之间读写数字,而不是像...那样格式化字符fprintffscanf那样作为格式化字符。我该怎么做?

12.38 如何正确读取二进制数据文件?我偶尔会看到...0x0a0x0d值被损坏,如果数据包含值0x1a.

12.39 我正在编写一个二进制文件的“过滤器”,但是...stdinstdout被预先打开为文本流。我该如何将它们的模式更改为二进制?

12.40 文本 I/O 和二进制 I/O 有什么区别?

12.41 如何从数据文件中读取/写入结构?

12.42 如何编写代码以符合这些旧的、二进制数据文件格式?

12.43 我正在将用户输入的字符串读入数组,然后稍后打印它们。当用户输入像...这样的序列时\n,为什么它没有被正确处理?


13. 库函数

13.1 如何将数字转换为字符串(与...相反)?atoi相反)?有没有itoa函数?

13.2 为什么...strncpy并不总是在目标字符串中放置一个'\0'终止符?

13.3 C 是否有像其他语言中存在的“substr”(提取子字符串)例程?

13.4 如何将字符串转换为全部大写或小写?

13.5 为什么有些版本的...toupper在给定大写字母时表现异常?
为什么有些代码会在调用islower之前先调用toupper?

13.6 如何将字符串分解成由空格分隔的字段?
我如何复制那个过程,通过这个过程main()被赋予argcargv?

13.7 我需要一些代码来执行正则表达式和通配符匹配。

13.8 我正在尝试使用...对字符串数组进行排序qsort来对一个字符串数组进行排序,并使用strcmp作为比较函数,但它不起作用。

13.9 现在我正在尝试使用...对结构数组进行排序qsort.我的比较函数接收结构指针,但编译器抱怨该函数对于qsort来说类型不正确。如何转换函数指针以关闭警告?

13.10 如何对链表进行排序?

13.11 如何对无法完全装入内存的数据进行排序?

13.12 如何在 C 程序中获取当前日期或一天的时间?

13.13 我知道库函数...localtime可以将time_t转换为分解的struct tm,并且ctime可以将time_t转换为可打印字符串。如何执行相反的操作,将struct tm或字符串转换为time_t?

13.14 如何给日期加上 N 天?如何找到两个日期之间的差值?

13.14b C 有什么年份 2000 年的问题吗?

13.15 我需要一个随机数生成器。

13.16 如何在特定范围内获取随机整数?

13.17 每次我运行我的程序时,我都会从...得到相同的数字序列?rand().

13.18 我需要一个随机的真/假值,所以我只是取...rand() % 2,但它总是交替出现 0, 1, 0, 1, 0...

13.19 如何返回一个不重复的随机数序列?

13.19b 如何生成浮点随机数?

13.20 如何生成具有正态或高斯分布的随机数?

13.21 我正在移植这个程序,它调用了一个例程...drand48,我的库里没有这个。这是什么?

13.22 是...exit(status)真正等同于从status返回main?

13.23 ...和...有什么区别?memcpymemmove?

13.24 我正在尝试移植这个旧程序。为什么我会收到一些库函数的“未定义外部”错误?

13.25 我一直收到未定义库函数的错误,但我在 #include 了所有正确的头文件。

13.26 我仍然收到未定义库函数的错误,尽管我显式地在链接时请求了正确的库。

13.27 为什么我的简单程序,几乎只在窗口中打印“Hello, world!”,编译成如此庞大的可执行文件(数百 KB)?我应该...#include更少的头文件吗?

13.28 当链接器说...是什么意思?_end未定义时,这是什么意思?

13.29 我的编译器抱怨说...printf未定义!怎么会这样?这是世界上最流行的 C 函数……


14. 浮点数

14.1 当我设置一个...float变量设置为,比如说,3.1 时,为什么printf会打印出 3.0999999?

14.2 我正在尝试计算一些平方根,并将代码简化为...

	main()
	{
		printf("%f\n", sqrt(144.));
	}
但我仍然得到奇怪的数字。

14.3 我正在尝试做一些简单的三角函数,并且我 #include 了...<math.h>,但是链接器一直在抱怨像sincos这样的函数是未定义的。

14.4a 我的浮点计算行为异常,并且在不同的机器上给出不同的答案。

14.4b 我很确定我已经正确声明了三角函数,但它们仍然给出错误的答案。

14.5 检查“足够接近”的浮点相等性的好方法是什么?

14.6 如何四舍五入数字?

14.7 为什么 C 没有指数运算符?

14.8 预定义的常数...M_PI似乎在我机器上的副本中丢失了<math.h>.

14.9 如何将变量设置为 IEEE NaN(“非数字”)和其他特殊值,或测试它们?

14.10 如何优雅地处理浮点异常?

14.11 在 C 中实现复数的好方法是什么?

14.12 我正在寻找一些代码来做...

快速傅里叶变换 (FFT)
矩阵运算(乘法、求逆等)
复数运算

14.13 我在使用 Turbo C 时遇到问题,它崩溃并显示类似“未链接浮点格式”的消息。


15. 可变参数列表

15.1 我听说你必须...#include 在调用printf。这是为什么?

15.2 ...可以吗?%f用于两者floatdouble参数在printf?它们不是不同的类型吗?

15.3 我遇到了一个令人沮丧的问题,最终是由...行引起的

	printf("%d", n);
其中n实际上是一个long int。我认为 ANSI 函数原型应该可以防止此类参数类型不匹配。

15.4 如何编写一个接受可变数量参数的函数?

15.5 如何编写一个接受格式字符串和可变数量参数的函数,像...printf,并将它们传递给printf来完成大部分工作?

15.6 如何编写一个类似于...的函数?scanf的函数,即它接受类似的参数,并调用scanf来完成大部分工作?

15.7 我有一个预 ANSI 编译器,没有...<stdarg.h>。我该怎么办?

15.8 如何发现一个函数实际被调用了多少个参数?

15.9 我的编译器不允许我声明一个函数...

	int f(...)
	{
	}
即接受可变数量的参数,但没有固定参数。

15.10 我有一个 varargs 函数,它接受一个...float参数。为什么

va_arg(argp, float)
不起作用?

15.11 我无法让...va_arg拉入一个函数指针类型的参数。

15.12 如何编写一个接受可变数量参数并将其传递给另一个函数(接受可变数量参数)的函数?

15.13 如何在运行时调用一个带有参数列表的函数?


16. 奇怪的问题

16.1 为什么这个循环总是执行一次?

	for(i = start; i < end; i++);
		{
		printf("%d\n", i);
		}

16.1b 我收到了一些令人费解的语法错误,这些错误毫无意义,而且似乎我程序的大部分都没有被编译。

16.1c 为什么我的过程调用不起作用?编译器似乎直接跳过了它。

16.2 我在文件的第一个声明中出现了一些奇怪的语法错误,但它看起来是正确的。

16.3 这个程序甚至在运行前就崩溃了!(使用调试器单步执行时,它在...的第一个语句之前就死了main.)

16.4 我有一个程序,似乎运行正常,但它在退出时崩溃,...的最后一个语句之后main()的最后一条语句之后。这可能是由什么原因引起的?

16.5 这个程序在一台机器上运行完美,但在另一台机器上我得到了奇怪的结果。更奇怪的是,添加或删除调试打印语句会改变症状...

16.6 为什么这段代码...

char *p = "hello, world!";
p[0] = 'H';
会崩溃?

16.7

我有一些代码试图解包外部结构,但它以“未对齐访问”的消息崩溃。这是什么意思?代码如下

struct mystruct {
	char c;
	long int i32;
	int i16;
} s;

char buf[7], *p;
fread(buf, 7, 1, fp);
p = buf;
s.c = *p++;
s.i32 = *(long int *)p;
p += 4;
s.i16 = *(int *)p;

16.8 “段错误”、“总线错误”和“通用保护故障”是什么意思?什么是“核心转储”?


17. 风格

17.1 C 中代码布局的最佳风格是什么?

17.2 函数应该如何分配到源文件中?

17.3 这是一个检查两个字符串是否相等的很棒的技巧

if(!strcmp(s1, s2))
这样好吗?

17.4 为什么有些人写...if(0 == x)来解决这个问题,而不是if(x == 0)?

17.4b 我见过像这样的函数声明

extern int func __((int, int));
那些额外的括号和下划线是做什么用的?

17.5 我看到了一些代码,其中包含...(void)之前加上一个强制类型转换printf。这是为什么?

17.6 如果...NULL0作为空指针常量是等效的,我应该使用哪一个?

17.7 我应该使用符号名称,如...TRUEFALSE这样的符号名称来表示布尔常量,还是使用普通的 1 和 0?

17.8 “匈牙利命名法”是什么?它值得吗?

17.9 在哪里可以获得“印度山风格指南”和其他编码标准?

17.10 有些人说...goto是邪恶的,我不应该使用它们。这会不会有点极端?

17.11 人们总是说良好的风格很重要,但是当他们不遗余力地使用清晰的技术并使程序可读时,他们似乎最终会得到效率较低的程序。由于效率如此重要,牺牲一些风格和可读性是否不是必要的?

17.12 哪个是正确的?

char *p
char* p
?


18. 工具和资源

18.1 我需要一些 C 开发工具。

18.2 如何追踪这些棘手的 malloc 问题?

18.3 有没有免费或便宜的 C 编译器可以使用?

18.4 我刚输入了这段程序,它行为奇怪。你能看出有什么问题吗?

18.5 如何关闭...给我的“警告:可能的指针对齐问题”消息?lint对...的每一次调用?malloc?

18.6 可以声明...mainvoid,以关闭那些恼人的“main函数无返回值”消息?

18.7 在哪里可以获得符合 ANSI 标准的...lint?

18.8 ANSI 函数原型不是使...变得多余吗?lint过时了?

18.9 有 C 教程或其他网络资源吗?

18.9b 在哪里可以找到一些好的代码示例来学习?

18.10 有什么好的 C 入门书?高级书籍和参考书呢?

18.11 在哪里可以找到 K&R 练习题的答案?

18.12 有人知道像《C 语言数值计算》、Plauger 的《标准 C 库》或 Kernighan 和 Pike 的《UNIX 编程环境》等书籍的源代码在哪里可以找到吗?

18.13 在哪里可以找到标准 C 库的源代码?

18.13b 有在线 C 参考手册吗?

18.13c 在哪里可以获得 ANSI/ISO C 标准的副本?

18.14 我需要能够解析和评估表达式的代码。

18.15 在哪里可以找到 C 的 BNF 或 YACC 语法?

18.15b 有 C 编译器测试套件可供使用吗?

18.15c 在哪里可以找到有用的代码片段和示例集合?

18.15d 我需要进行多精度算术的代码。

18.16 在哪里以及如何获得所有这些免费分发的程序副本?

18.17 在哪里可以获得此列表的额外副本?


19. 系统依赖

19.1 如何在不等待 RETURN 键的情况下从键盘读取单个字符?如何阻止字符回显到屏幕上?

19.2 如何知道是否有可读字符(如果有,有多少)?或者,如何执行一个在没有字符可用时不阻塞的读取操作?

19.3 如何显示一个自行更新的完成百分比指示器,或者显示一个“旋转的指示器”进度指示器?

19.4 如何清除屏幕?
如何以彩色显示文本?
如何将光标移动到特定的 x, y 位置?

19.4b 我正在 Windows 系统上编译一些测试程序,我的程序输出窗口在程序调用...之后很快关闭exit后很快关闭,以至于我无法看到输出。 如何让它在关闭前暂停?

19.5 如何读取箭头键?功能键呢?

19.6 如何读取鼠标?

19.7 如何进行串行(“通信”)端口 I/O?

19.8 如何将输出发送到打印机?

19.9 如何发送转义序列来控制终端或其他设备?

19.9b 如何直接访问 I/O 板?

19.10 如何进行图形处理?

19.10b 如何显示 GIF 和 JPEG 图像?

19.10c 如何加载新字体进行显示?

19.10d 如何从 C 程序发送邮件?

19.11 如何检查文件是否存在?我想在用户请求的输入文件丢失时警告用户。

19.12 在读取文件之前,如何知道文件的大小?

19.12b 如何获取文件的修改日期和时间?

19.13 如何在不完全清空或重写文件的情况下就地截断文件?

19.14 如何在文件的中间插入或删除一行(或记录)?

19.15 在给定打开的流或文件描述符的情况下,如何恢复文件名?

19.16 如何删除文件?

19.16b 如何复制文件?

19.17 为什么我无法通过显式路径打开文件?调用...

fopen("c:\newdir\file.dat", "r")
失败。

19.17b fopen不允许我打开类似"$HOME/.profile""~/.myrcfile".

19.17c 如何抑制可怕的 MS-DOS “Abort, Retry, Ignore?”消息?

19.18 我收到一个错误,“打开文件过多”。如何增加允许同时打开的文件数量?

19.19 如何知道磁盘上有多少可用空间?

19.20 如何在 C 程序中读取目录?

19.21 如何创建目录?
如何删除目录(及其内容)?

19.22 如何知道有多少可用内存?

19.23 如何分配大于 64K 的数组或结构?

19.24 “DGROUP 数据分配超过 64K”的错误消息是什么意思,我该怎么办?我认为使用大模型意味着我可以使用超过 64K 的数据!

19.25 如何访问位于特定地址的内存(内存映射设备或图形内存)?
如何在 C 中进行 PEEK 和 POKE?

19.25b 如何确定机器的字节顺序是大端还是小端?

19.26 如何访问位于机器地址 0 的中断向量?如果我将指针设置为0,编译器可能会将其转换为某个非零的内部空指针值。

19.27 如何在 C 程序中调用另一个程序(独立可执行文件或操作系统命令)?

19.28 如何调用...system当执行命令的参数(文件名等)在运行时才能确定?

19.29 如何从...获得准确的错误状态返回?system获得准确的错误状态返回值?

19.30 如何调用另一个程序或命令并捕获其输出?

19.31 我的程序如何发现它被调用的可执行文件的完整路径名?

19.32 如何在可执行文件所在的目录中自动查找程序的配置文件?

19.33 进程如何更改其调用者的环境变量?

19.34 如何打开命令行中提到的文件,并解析选项标志?

19.35 是...exit(status)真正等同于从status返回main?

19.36 如何读取一个目标文件并跳转到其中的位置?

19.37 如何实现延迟,或计时用户的响应,并具有亚秒级分辨率?

19.38 如何捕获或忽略键盘中断,如 Control-C?

19.39 如何优雅地处理浮点异常?

19.39b 如何确保整数算术不会溢出?

19.40 我该如何... 使用套接字?进行网络编程?编写客户端/服务器应用程序?

19.40a 可以组合 Microsoft C 和 Turbo C 的 .OBJ 和 .LIB 文件吗?

19.40b 我该如何... 使用 BIOS 调用?编写 ISR?创建 TSR?

19.40c 我正在编译这段代码,但是编译器抱怨“...union REGS”未定义,并且链接器抱怨int86未定义。

19.40d “近”指针和“远”指针是什么意思?

19.41 但我不能使用所有这些非标准、系统依赖的函数,因为我的程序必须符合 ANSI 标准!

19.42 为什么 C 中没有标准化所有这些?任何实际程序都必须做其中一些事情。


20. 杂项

20.1 如何从函数返回多个值?

20.2 存储文本行的好数据结构是什么?我开始使用固定大小的数组的数组,其中...char,但它们太受限制了。

20.3 如何打开命令行中提到的文件,并解析选项标志?

20.4 使用...的正确方法是什么?errno?

20.5 如何编写可以在具有不同字长、字节顺序或浮点格式的其他机器上读取的数据文件?

20.6 如果我有一个...char *变量指向一个函数名,我该如何调用该函数?代码如

	extern int func(int, int);
	char *funcname = "func";
	int r = (*funcname)(1, 2);
	r = (*(int (*)(int, int))funcname)(1, 2);
似乎行不通。

20.6b 如何确保整数算术不会溢出?

20.7 如何操作单个位?

20.8 如何实现位集或位数组?

20.9 如何确定机器的字节顺序是大端还是小端?

20.9b 如何交换字节?

20.10 如何将整数转换为二进制或十六进制?

20.11 可以使用基数为 2 的常量(例如...)吗?0b101010)?
是否有用于二进制的printf格式说明符?

20.12 计算整数中设置的位数最有效的方法是什么?

20.13 如何使我的程序高效?

20.14 指针真的比数组快吗?函数调用会减慢速度吗?...++ii = i + 1?

20.15 我一直在用移位运算符替换乘法和除法,因为移位更有效。

20.15b 人们声称优化编译器很好,我们不再需要为了速度而编写汇编代码,但我的编译器甚至无法替换...i/=2替换为移位。

20.15c 如何在不使用临时变量的情况下交换两个值?

20.16 ...和...哪个更有效?switch语句还是if/else链?

20.17 有办法...switch在字符串上?

20.18 有办法拥有非常量...case标签(例如范围或任意表达式)吗?

20.19 ...中的外层括号是...return语句真的可以省略吗?

20.20 为什么 C 注释不能嵌套?我该如何注释掉包含注释的代码?注释是否可以在引号字符串中?

20.20b 为什么没有编号的多级...break语句一次跳出多个循环?我应该用什么代替,goto?

20.21 似乎缺少一些运算符,例如...^^, &&=,而->=.

20.21a C 有循环移位运算符吗?

20.21b C 是一个很棒的语言,还是什么?你还能在哪里写出像...a+++++b ?

20.22 如果赋值运算符是...:=,那么意外写出类似if(a = b) ?

20.23 C 是否有等同于 Pascal 的...with语句吗?

20.24 为什么 C 没有嵌套函数?

20.24b ...是什么?assert()?我应该何时使用它?

20.25 如何从 C 调用 FORTRAN(C++、BASIC、Pascal、Ada、LISP)函数?(反之亦然?)

20.26 有人知道将 Pascal 或 FORTRAN(或 LISP、Ada、awk、“旧” C 等)转换为 C 的程序吗?

20.27 C++ 是 C 的超集吗?C 和 C++ 有什么区别?我可以使用 C++ 编译器编译 C 代码吗?

20.28 我需要一种“近似”strcmp 例程,用于比较两个字符串的接近程度,但不一定完全相等。

20.29 哈希是什么?

20.30 如何生成具有正态或高斯分布的随机数?

20.31 如何根据日期找到星期几?

20.32 是...(year % 4 == 0)是判断闰年的准确测试吗?(2000 年是闰年吗?)

20.33 为什么可以...tm_sectm结构体中范围从 0 到 61,暗示一分钟可能有 62 秒?

20.34 这是一个很好的谜题:如何编写一个生成自身源代码作为输出的程序?

20.35 “Duff's Device”是什么?

20.36 下一届国际混淆 C 代码竞赛 (IOCCC) 将何时举行?如何提交竞赛条目?今年的 IOCCC 冠军是谁?如何获取当前和以前的获胜条目的副本?

20.37 ...是什么?entry关键字是什么?

20.38 “C”这个名字是哪里来的?

20.39 如何发音“...char”?那个“#”字符的奇怪名字是什么?

20.39b “左值”和“右值”是什么意思?

20.40 在哪里可以获得此列表的额外副本?


术语表


参考文献


致谢


回到顶部