"《你必须知道的495个C语言问题》是关于C语言常见问题的集合,由Steve Summit原著,朱群英和孙云翻译。这本书旨在帮助开发者,尤其是涉及安全相关系统(如工业控制系统)的开发者,解决C语言编程中遇到的各种问题。书中涵盖了声明与初始化、结构、联合和枚举等多个主题,提供了详细的解答和示例,有助于提高C语言编程技能。"
1. C语言中的整数类型选择应基于实际需求,考虑存储空间和性能。例如,`int`通常用于常规整数运算,`long`和`long long`用于更大范围的数值,而`short`则用于节省内存空间。
2. 在64位机器上,64位类型的表示取决于具体的编译器和平台,通常包括`long`和`long long`。不过,为了跨平台兼容性,建议使用`stdint.h`头文件中定义的固定宽度整型,如`int64_t`。
3. 全局变量和函数的声明和定义应清晰明确,避免命名冲突和作用域混淆。一般推荐在头文件中声明,在源文件中定义。
4. `extern`关键字用于在其他文件中引用已在一个文件中定义的变量或函数,表明它们是外部链接的。
5. `auto`关键字在C语言中用于局部变量的默认存储类别,但在C++中已不再常用,因为C++中的默认局部变量就是`auto`。
6. 结构体可以包含指向自身的指针,这在创建递归数据结构(如链表、树等)时非常有用。对于typedef的结构体指针,需要正确处理指针的类型。
7. 复杂声明的理解可以通过从右到左读取类型来辅助,例如,一个指针数组,数组元素是返回指针的函数。使用括号可以帮助分组和理解复杂声明。
8. 函数不能重复定义,一旦定义,后续出现的相同名称会被认为是重复定义,除非是声明(原型)。
9. `main()`函数的标准定义是`int main(void)`或`int main(int argc, char *argv[])`,`void main()`不被标准C所接受。
10. 未初始化的变量值是不确定的,不应依赖其初始值。全局变量通常不会自动初始化为零,局部静态变量则会。
11. 字符串字面量不能赋值给非数组的字符指针,因为字符串字面量是常量。
12. `malloc()`返回的是未初始化的内存,不能直接用作初始化,需要显式初始化。例如,`char *p = malloc(10); p[0] = 'a';`。
13. 字符串字面量和字符数组的区别在于,字符串字面量是不可修改的,而字符数组可以修改。尝试修改字符串字面量会导致未定义行为。
14. 函数指针的声明和初始化通常涉及函数的返回类型、参数列表和指针名称。例如,声明一个返回整型的函数指针类型`typedef int (*func_ptr)(int, int)`,然后初始化为某个函数,如`func_ptr fp = some_function;`。
2. 结构、联合和枚举:
- 结构声明`struct x1`和`typedef struct {} x2`主要区别在于类型名称的位置,前者需要使用`struct`关键字来访问,后者可以直接使用`x2`。
- `struct x{}; x theStruct;`会报错,因为结构体类型前缺少了`struct`关键字。
- 结构体可以包含指向自身的指针,这是实现递归数据结构的关键。
- 实现抽象数据类型(ADT)通常通过结构体和指针实现,隐藏内部实现细节,提供接口函数进行操作。
- C语言不支持直接的面向对象特性,但可以通过结构体模拟类,使用函数指针实现方法,以及通过结构体成员封装数据。
这些只是书中部分问题的解析,完整的书本提供了495个问题的详细解答,覆盖C语言的各个方面,对学习和提升C语言编程能力具有很高的参考价值。