“去卡内基音乐厅怎么走?”

“多练习!”

——20世纪来源不详的笑话

指针是 C 语言中最令人害怕的东西之一。实际上,正是它让这门语言变得极其具有挑战性。但这是为什么呢?

因为,坦率说,它们确实可能导致“电击”从键盘传来,把你的手臂永久焊接在原地,让你一辈子只能守着这个70年代的键盘写代码!

真的吗?其实不然。我只是想帮你做好心理准备,迎接成功。

根据你之前使用的语言,你可能已经理解了“引用”(references)的概念,即变量引用某种类型的对象。

这和指针非常相似,只是用 C 语言时,我们必须更加明确地说明引用的是引用本身还是它所指向的对象。

5.1 Memory and Variables

计算机内存可以保存各种类型的数据,对吧?它可以存储 floatint,或者你所拥有的任何数据。为了方便管理内存,每个内存字节都有一个整数标识。随着你在内存中往上移动,这些整数会依次递增。你可以把它想象成一堆编号的盒子,每个盒子存储一个字节的数据。或者如果你来自有数组概念的语言,可以把它看作一个大数组,每个元素存储一个字节。表示每个盒子的数字被称为它的地址

不过,并非所有数据类型都只用一个字节。例如,一个 int 通常占用四个字节,float 也是如此,但具体取决于系统。你可以使用 sizeof 操作符来确定某种数据类型占用多少字节内存。

// %zu 是类型 size_t 的格式说明符
printf("an int uses %zu bytes of memory\\n", sizeof(int));
// 对我来说输出是 4,但不同系统可能不一样。

内存趣闻:

当你有一个使用多个字节的类型(例如典型的 int),组成该数据的字节在内存中通常是相邻的。有时它们的顺序和你预期的一样,有时却不一定。虽然 C 语言不保证具体的内存字节顺序(这依赖于平台),但通常仍可以用一种与平台无关的方式编写代码,从而无需关心这些令人头疼的字节顺序。

所以无论如何,如果我们正式定义指针时,先给它伴奏一段隆隆的鼓声和预示着紧张气氛的音乐——指针就是一种保存地址的变量

想象一下电影《2001太空漫游》的经典配乐响起,Ba bum ba bum ba bum BAAAAH!

所以,无论如何,如果我们要继续讲指针的定义,就让我们伴随着鼓声和紧张的音乐来介绍它——指针是一个保存地址的变量。想象一下电影《2001太空漫游》的经典配乐此刻响起,Ba bum ba bum ba bum BAAAAH!

好吧,也许我有点夸张了,是吧?指针其实没什么神秘的。它们就是数据的地址。就像一个 int 变量可以保存数值 12,指针变量可以保存数据的地址。

这意味着这些说法都是一个意思,也就是说,指针就是表示内存中某个位置的数字: