- 现代C:概念剖析和编程实践
- (德)延斯·古斯泰特
- 1800字
- 2025-04-08 00:44:15
第1级 相识

这一级的吉祥物是渡鸦,它是一种非常善于交际的鸟类,以其解决问题的能力而闻名。渡鸦成群结队,有人观察到,即使成年后它们也在一起玩耍。
这一级将使你熟悉C编程语言:它将为你提供足够的知识来编写和使用好的C程序。“好”在这里指的是对语言的现代的理解,避免了C语言早期方言的大部分陷阱,并为你提供了一些以前不存在的结构,这些结构可以跨大多数现代计算机体系结构移植(从手机到大型机)。通过阅读这些章节,你应该能够编写满足日常需要的简短代码:不是非常复杂,但是很有用且可移植。
系好安全带
在很多方面,C语言是一种比较自由的语言。程序员有可能会犯错误,但C也不能阻止此类事件的发生。因此,就目前而言,我们将引入一些限制。我们将采取一定的措施来尽量避免在这一级发生问题。
C语言中最危险的结构是所谓的强制类型转换C,因此我们将在这一级略过它们。然而,还有许多其他的陷阱不太容易排除。我们将以一种你可能不熟悉的方式来处理其中的一些陷阱,特别是如果你在上个千禧年学习了C的基础知识,或者你是在一个多年没有升级到当前ISO C的平台上接触到C的。
- 有经验的C程序员:如果你已经有了一些C编程经验,下面的内容可能需要一些时间来适应,甚至会引起过敏反应。如果你在阅读这里的一些代码时碰巧出现了一些问题,请深呼吸并试着放松,但请不要跳过这些页。
- 没有经验的C程序员:如果你不是一个有经验的C程序员,下面的讨论可能有点超出你的理解。例如,我们可能使用你甚至还没有听说过的术语。如果是这样的话,这对你来说是题外话,你可以跳到第3章的开头,当你觉得舒服一点的时候再回来。但是一定要在这一级结束前完成。
我们在这一级上的一些“习惯”方法可能涉及我们所展示的材料中的重点和顺序:
- 我们将主要关注整数类型的无符号C版本。
- 我们将分步骤介绍指针:首先,将指针伪装成函数的参数(6.1.4节),然后讨论它们的状态(是否合法,6.2节),接下来在下一级(第11章)使用它们的全部潜能。
- 我们将尽可能地关注数组的使用。
你可能还会对下面将要讨论的一些样式方面的考虑感到惊讶。在下一级,我们将用一整章(第9章)来专门回答这些问题,所以请耐心等待,并先暂时接受它们。
1. 将类型修饰符和限定符绑定到左边。我们希望从视觉上将标识符与它们的类型分开。我们通常会写成

其中char*
是类型,name
是标识符。我们还将左绑定规则应用于限定符,写成

这里,第一个const
将char
限定至其左边,*
使其成为一个指针,第二个const
再次将所指内容限定至其左边。
2. 不使用连续声明。它们混淆了类型声明符的绑定。例如:

这里,b
的类型是unsigned const
。也就是说,第一个const
指向类型,第二个const
只指向a
的声明。这样的规则非常混乱,你还有更重要的东西要学习。
3. 使用数组符号来表示指针参数。只要这些假设指针不能为空,我们就可以这样做。例如:

第一个声明强调strlen
必须接收一个合法的(非空)指针,并且至少要访问string
的一个元素。第二个声明总结了main
接收一个指向char
的指针数组的事实,数组包含程序名、argc-1
个程序参数和一个终止数组的空指针。
注意,前面的代码是合法的。第二组声明只是为编译器已知的特性添加了额外的等价声明。
4. 使用函数符号来表示函数指针参数。同样,只要我们知道函数指针不能为空,就可以这样做:

这里,atexit
的第一个声明强调,从语义上讲,它接收一个名为handler
的函数作为参数,并且不允许使用空函数指针。从技术上讲,函数参数处理程序handler
被“重写”为函数指针,就像数组参数被重写为对象指针一样,但是对于功能的描述来说,这并不重要。
再次注意,前面的代码是合法的,第二个声明只是为atexit
添加了一个等价的声明。
5. 对变量的定义要尽可能靠近首次使用它们的位置。缺少变量初始化,特别是指针的初始化,是新手C程序员遇到的主要陷阱之一。这就是为什么我们应该尽可能地将变量的声明与变量的第一次赋值结合起来,C为此提供的工具是定义,即声明和初始化。它给一个值命名,并在第一次使用该值的地方引入该名称。
这对于for
循环特别方便。一个循环的循环变量与另一个循环中的循环变量在语义上是不同的对象,因此我们在for
中声明该变量,以确保它保持在循环的范围内。
6. 对代码块使用前缀表示法。为了能够读取一个代码块,很重要的一点是要容易地捕获它的两个方面:用途和范围。因此:
- 所有
{
都作为前缀与引入它们的语句或声明位于同一行。 - 里面的代码缩进一级。
- 终止
}
在与引入块的语句的同一级上启用一个新行。 - 如果
}
之后有延续的块语句,则它们在同一行上延续。
例如:
