2.1 What to Expect from C

C 是一种低级语言。

但它曾经不是。早期,人们用花岗岩制作打孔卡片,而 C 是一种让人摆脱像汇编语言这样的低级语言繁琐工作的极佳方式。

但在现代,现今的编程语言提供了许多 1972 年 C 诞生时不存在的功能。这意味着 C 是一门功能相对基础、特性不多的语言。它几乎能做任何事情,但你得为此付出努力。

那么,为什么我们今天还要使用它呢?

如果你熟悉其他编程语言,很多关于 C 的东西都会很容易理解。C 影响了许多其他语言,你会在 Go、Rust、Swift、Python、JavaScript、Java 等各种语言中看到它的影子。这些部分对你来说会很熟悉。

C 中让人最头疼的一点是指针。几乎其他所有东西你都很熟悉,但指针却很怪异。指针背后的概念你可能已经懂了,但 C 要求你明确地使用一些你可能从未见过的运算符来操作它们。

这点尤其狡猾,因为一旦你真正理解(grok)了指针,它们突然就变得很简单了。但在那之前,它们就像滑溜的鳗鱼。

C 中的其他所有内容不过是记住另一种方式(有时甚至是相同的方式)去做你已经做过的事情。指针是怪异的部分。可以说,即便是指针,也是在你大概已经熟悉的主题上的一种变体。

所以,准备好展开一场紧贴计算机核心、尽可能不依赖汇编语言的精彩冒险吧——探索这门有史以来最具影响力的编程语言。坚持下去!

2.2 Hello, World!

这是一个经典的 C 程序示例。每个人都会用到它。(注意左侧的行号仅供读者参考,不是源码的一部分。)

/* Hello world program */

#include <stdio.h>

int main(void)
{
    printf("Hello, World!\\n");  // Actually do the work here
}

我们将穿上长袖厚重的橡胶手套,拿起手术刀,深入探究这段程序的运作原理。准备好,因为我们要开始了。小心翼翼地切入……

先从简单的开始:介于 /**/ 之间的内容是注释,编译器会完全忽略。同样,行内以 // 开头的内容也是注释。这样你就可以给自己或他人留下一些信息,方便将来回来看这段代码时,知道当初写这段代码的目的是什么。相信我,你一定会忘记,没关系,这很正常。

那么,什么是 #include?恶心吗?其实,它告诉 C 预处理器去拉取另一个文件的内容,并把它插入到代码的那个地方

等等——什么是 C 预处理器?好问题。编译过程分为两个阶段²⁶:预处理和编译。任何以井号符号(“octothorpe”,#)开头的东西,都是预处理器在编译器开始工作之前处理的。常见的预处理指令包括 #include#define,稍后会详细讲述。

在继续之前,为什么我要特别指出井号符号叫做 octothorpe 呢?答案很简单:我觉得这个词太好玩了,每次有机会都要无偿地传播它这个名字。Octothorpe,Octothorpe,octothorpe,octothorpe。