C语言常见问题与解答:Steve Summit原著

需积分: 3 7 下载量 130 浏览量 更新于2024-08-02 收藏 1.42MB PDF 举报
"C语言常见问题集,由Steve Summit原著,朱群英和孙云翻译,包含关于声明和初始化、结构、联合和枚举等方面的常见问题解答,旨在帮助读者理解和解决C语言编程中的实际问题。" 在C语言编程中,理解和掌握声明与初始化是至关重要的。以下是针对提供的部分内容的详细解释: 1. **选择整数类型**:在C语言中,有多种整数类型如`int`, `short`, `long`, 和 `long long`等。选择哪种类型取决于你需要存储的数值范围和平台的字长。 2. **64位类型的表示**:在64位系统上,`long`通常是64位,但并非所有64位系统都如此。`long long`通常总是64位,但应使用`stdint.h`中的固定宽度类型如`int64_t`确保跨平台兼容性。 3. **全局变量与函数声明**:全局变量在程序的整个生命周期内有效,而函数声明用于告知编译器函数的存在,但不提供实现。最佳实践是在头文件中声明,在源文件中定义。 4. **extern的作用**:`extern`关键字用于告诉编译器变量或函数是在其他地方定义的,通常用于链接阶段。 5. **关键字auto**:在现代C++中,`auto`用于类型推断,但在C语言中,它的作用主要在旧的函数作用域规则中,现在已不再常用。 6. **自引用结构**:C语言允许结构包含指向自身的指针,这在创建递归数据结构如链表和树时很有用。 7. **复杂声明解析**:理解复杂的声明需要从右向左读取,同时考虑括号和指针的嵌套。例如,`int (*f[N])(char *)`是一个指针数组,每个元素都是返回`char *`的函数。 8. **非法重定义**:重复定义是编译错误,确保每个函数和变量在每个源文件中只定义一次,除非使用`extern`声明。 9. **main()的定义**:标准C中的`main()`函数应定义为`int main(void)`或`int main(int argc, char *argv[])`。`void main()`不是标准形式,可能导致不兼容问题。 10. **未初始化变量**:未初始化的全局变量默认值不确定,不应依赖其值。局部变量未初始化时,其值也是不确定的。 11. **字符串字面量与数组**:在`int f(){char a[]="Hello,world!";}`中,`a`是一个自动数组,字符串字面量不能赋值给非const指针。 12. **动态分配与初始化**:`char *p=malloc(10);`仅分配内存,未初始化。要初始化,需要使用`strcpy`或`memcpy`。 13. **字符数组与字符串字面量**:字符数组`char a[]="stringliteral";`可以直接初始化,而`char *p="stringliteral"`是字符串字面量,尝试修改会导致未定义行为。 14. **函数指针的声明与初始化**:声明函数指针如`typedef int (*func_ptr)(int)`,初始化可以是`func_ptr my_func = some_function;`。 接下来是结构、联合和枚举的相关问题: 1. **struct声明与typedef的区别**:`struct x1`定义了一个结构类型,而`typedef struct {} x2`创建了一个别名,两者都可以使用,但typedef使得类型名称更简洁。 2. **结构变量的声明**:`struct x`之后不能立即跟结构变量,需要分开写,如`struct x;`后跟`x the_struct;`。 3. **结构自引用**:是允许的,如`struct node { int data; struct node *next; };`创建链表节点。 4. **实现抽象数据类型**:C语言通过结构体和指针来实现抽象数据类型,隐藏内部实现细节。 5. **面向对象特性**:C不支持直接的面向对象特性,但可以通过结构体模拟类,通过函数指针模拟方法,以及通过组合结构体模拟继承。 2.6中的结构声明`struct name{int namelen;char namestr[1];};`是为了节省空间,`namestr[1]`可以用于存储任意长度的字符串,但需要小心使用,因为它没有自动添加字符串结束符。 以上只是部分知识点的概述,完整的问题集会涵盖更多细节,包括更多问题的解答,涉及C语言的各个核心概念和最佳实践。