数组变量与指针又不完全相同

虽然可以将数组变量用作指针,但两者还是有一些区别,为了区分它们,考虑下面这段代码:

  1. char s[] = "How big is it?";
  2. char *t = s;
  • sizeof(数组)是……数组的大小

sizeof(指针)返回了4或8,因为4和8分别是32位和64位操作系统上指针的大小。但如果对数组变量使用sizeof,C语言就开窍了,它知道你想得到数组在存储器中的长度。

数组变量与指针又不完全相同 - 图1

  • 数组的地址……是数组的地址。

指针变量是一个用来保存存储器地址的变量,那数组变量呢?如果对数组变量使用&运算符,结果是数组变量本身。

数组变量与指针又不完全相同 - 图2

当程序员写下&s时,表示“数组s的地址是?”,数组s的地址就是……s;但如果他写的是&t,则表示“变量t的地址是?”。

  • 数组变量不能指向其他地方。

当创建指针变量时,计算机会为它分配4或8字节的存储空间。但如果创建的是数组呢?计算机会为数组分配存储空间,但不会为数组变量分配任何空间,编译器仅在出现它的地方把它替换成数组的起始地址。

但是由于计算机没有为数组变量分配空间,也就不能把它指向其他地方。

数组变量与指针又不完全相同 - 图3

指针退化

数组变量和指针变量有一点小小的区别,所以把数组赋给指针时千万要小心。假如把数组赋给指针变量,指针变量只会包含数组的地址信息,而对数组的长度一无所知,相当于指针丢失了一些信息。我们把这种信息的丢失称为退化。

只要把数组传递给函数,数组免不了退化为指针,但需要记清楚代码中有哪些地方发生过数组退化,因为它们会引发一些不易察觉的错误。

数组变量与指针又不完全相同 - 图4

致命处方案件

这栋宅邸拥有他梦寐以求的一切:优美的风景,华丽的吊灯,独立盥洗室。豪宅的主人王百万因心脏病突发死在了花园中,享年94岁。自然死因?医生认为是服用心脏病药物过量。凉亭传来阵阵恶臭,但除了尸体的腐臭好像还有其他的味道。警察走出了大厅,走向王百万的27岁的遗孀,汤茱蒂。

“我想不通,他平时吃药时都很小心,这次怎么会……这张是服药的剂量单。”她将自动服药器的代码拿给他看。

  1. int doses[] = {1, 3, 2, 1000};

“警察说我改编了服药程序,但我对技术一窍不通。他们说是我写了这段代码,但我认为它不能编译,你说呢?”

她把修过指甲的手伸进钱包,递给了他一份程序。这段代码是警察在百万富翁的床旁边发现的,看起来的确无法编译……

  1. printf("服用 %i 毫克的药", 3[doses]);

表达式3[doses]是什么意思?3又不是数组。汤茱蒂擤了擤鼻子,说道:“真的不是我写的,况且3毫克的剂量也不算太坏,你说呢?”

3毫克的剂量杀不死那个老男人,但是真相其实近在眼前……