"《你必须知道的495个C语言问题》是一本旨在帮助读者深入理解和解决C语言编程中常见及复杂问题的书籍。由Steve Summit原著,朱群英和孙云翻译,并在2005年6月23日修订到0.9.4版。这本书涵盖了C语言的各种关键概念,包括声明与初始化、结构、联合和枚举等,旨在提升读者的C编程技能,是程序员的实用参考书。
1. 在C语言中,选择整数类型时,应考虑所需的数值范围和效率。通常,`int`是标准的选择,但`short`适用于内存受限的环境,而`long`和`long long`用于处理大整数。
2. 在64位系统上,64位类型通常是`long`或`long long`。但需要注意,不同平台可能有所不同,需要查阅具体系统的头文件以获取准确信息。
3. 全局变量和函数应在程序的外部(全局作用域)声明,并使用`extern`关键字在其他源文件中引用它们。这有助于模块化编程和代码组织。
4. `extern`在函数声明中的作用是表明该函数是在其他地方定义的,告知编译器函数的存在但不包含其实现。
5. `auto`关键字在现代C语言中通常不被使用,它默认就是局部变量的存储类别,现在可以忽略它。
6. 链表的定义可以通过typedef创建更友好的指针类型,如示例中的NODEPTR。问题出在结构体定义中可能缺少分号,导致语法错误。正确的做法是:`typedef struct {char *item; struct Node *next;} Node;`。
7. 复杂声明的理解可以通过自右向左的规则,即先读取最内层的类型,然后向外扩展。例如,解析一个返回指向字符的指针的函数的指针数组,可以逐步理解每个元素的类型。
8. 重复的函数定义会导致编译错误,确保每个函数在所有源文件中只定义一次。如果需要在多个文件中使用,只需在其中一个文件中定义,其他文件使用`extern`声明。
9. `main()`的正规定义通常是`int main(void)`,`void main()`不符合C标准,可能导致兼容性问题。
10. 未初始化的变量的值是不确定的,不应依赖其初始值。全局变量的默认值不是零,但静态局部变量会被自动初始化为零。
11. 字符串字面量不能作为数组的初始值,因为它们是常量。应使用初始化数组的方式,如`char a[] = {"Hello, world!"}`。
12. `malloc`返回的指针需要显式转换为其对应的类型,例如`char *p = (char *)malloc(10)`。不加类型转换可能会导致编译警告,且不能直接初始化为字符串字面量。
13. 字符串字面量是常量,尝试修改`p[i]`会导致不可预知的行为,甚至程序崩溃。若需修改,应将字符串拷贝到动态分配的内存区域。
14. 函数指针的声明类似于普通指针,如`typedef return_type (*pointer_type)(parameter_types)`。初始化时,应确保函数的返回类型和参数列表与指针类型匹配。
2. 结构、联合和枚举部分涉及C语言的复杂数据结构:
- 结构声明如`struct x1`和`typedef struct {} x2`之间的差异在于是否创建了一个匿名结构。`struct x1`创建了一个带有标签的结构,而`typedef`创建了一个类型别名。
- 使用`struct x {}; x theStruct;`会引发错误,因为`x`在这里是结构标签,而不是类型名,应该使用`struct x theStruct;`。
- 结构可以包含指向自身的指针,这是自引用结构的基础,常用于实现链表、树等数据结构。
- 实现抽象数据类型(ADT)的最佳方法是结合结构和函数指针,通过封装实现数据的隐藏和操作的封装。
- C语言不支持直接的面向对象特性,但可以通过模拟,如结构中的函数指针(仿函数)来实现类似继承和多态的效果。
这本书详细解答了C语言编程中的各种疑惑,是C语言学习者和开发者的宝贵参考资料。通过阅读和实践书中的问题,读者可以深化对C语言的理解,提高编程技能,避免常见的编程陷阱。"