"C语言常见问题集——Steve Summit"
在学习和使用C语言的过程中,经常会遇到各种挑战和疑惑。Steve Summit的《C语言常见问题集》是解决这些问题的一个宝贵资源,尤其对初学者和求职者来说,它能帮助理解和掌握C语言的基础与精髓。这本书涵盖了从数据类型选择、变量声明到复杂数据结构的处理等多个方面的问题。
1. 关于整数类型的选取,C语言提供了多种整数类型(如int, short, long, long long),开发者应根据实际需求和平台特性选择合适的类型,确保数值范围符合预期。
2. 在64位系统上,64位类型通常由long或long long表示,但具体依赖于编译器的实现,因此在编写跨平台代码时需特别注意。
3. 全局变量和函数的声明与定义应保持一致,避免命名冲突和作用域混淆。一般情况下,全局变量在所有源文件中都可见,而函数只需在需要的地方声明,具体实现放在一个文件中。
4. extern用于声明在其他地方定义的变量或函数,表示它们不是在这个源文件中定义的,而是存在于其他地方。
5. auto是C语言中的一个存储类别关键字,主要用于函数内部自动分配的变量,但在现代C++中已经不再常用,而在C99标准之后,它的使用已经被局部变量默认的存储类别所取代。
6. 在C语言中,可以定义结构体包含指向自身的指针,这是创建递归数据结构如链表、树等的基础,但需要正确处理指针的分配和释放,以避免内存泄漏和悬挂指针。
7. 复杂声明的理解可以通过自右向左读取来辅助,例如,一个返回指向字符的指针的函数的指针数组,可以先理解为数组,然后是函数指针,最后是返回值类型。
8. 如果函数被多次声明,但只有一次定义,这可能导致编译错误。在C语言中,每个函数只能有一个定义,但可以有多个声明。
9. main函数的标准定义是int main(void),void main()不遵循C标准,可能在某些编译器上不被接受。
10. 未初始化的变量值是不确定的,不应假设其为零。全局变量的初始值不自动为零,除非明确初始化。空指针和浮点零也需要显式初始化。
11. 字符串字面量不能被修改,因此不能将"Hello, world!"赋值给可变字符数组。如果需要修改,应使用动态内存分配或固定大小的数组。
12. malloc返回的是未初始化的内存,必须使用字符串复制函数(如strcpy)将其初始化为字符串,否则尝试访问未初始化的内存会导致错误。
13. char a[]="stringliteral"是字符数组,可以修改;char *p="stringliteral"是字符串字面量的指针,不可修改。对p[i]赋值会导致写入只读内存,引发运行时错误。
14. 函数指针的声明需要指定返回类型和参数列表,初始化时则需要一个匹配的函数地址。例如,int (*func_ptr)(int)声明了一个返回整数并接受整数参数的函数指针,func_ptr = some_func;进行初始化。
15. 结构、联合和枚举是C语言中的重要概念。结构可以用来组织数据,通过typedef可以创建结构体别名,提高代码可读性。结构体可以包含指向自身的指针,以实现自引用和复杂数据结构。联合允许在一个内存区域存储不同类型的变量,而枚举提供了一种定义符号常量的机制。
16. 要在C语言中实现抽象数据类型,通常通过结构体和指针结合,以及私有化结构体成员实现。虽然C语言不是面向对象语言,但可以模拟面向对象的一些特性,比如通过函数指针实现多态性,以及使用结构体封装数据和操作。
2.6 中提到的结构声明struct name {int name_len; char name_str[1];}是动态大小字符串的一种实现方式,name_str[1]允许通过动态分配内存扩展字符串长度,但使用时需要注意内存管理。
这本书是C语言学习者的实用参考,涵盖了从基础到高级的许多问题,帮助开发者更好地理解和解决问题,提高编程技能。