C语言数组与指针

举例,

int list[10] = {0};

那么,list[2]的类型为整型。

但是,list的类型是什么呢?是表示整个数组么?很遗憾,这种说法是错误的!

为什么这个说法是错误的呢?

举个例子,如果表示的是整个数组,那么,下面的例子,就表示复制整个数组:

1
2
3
int a[5] = {1, 2, 3, 4, 5};
int b[5];
b = a;

可是,b = a;,这个表达式明显是非法的(这里,之所以非法,原因在b身上,而非在a身上),所以,a表示的不是整个数组!

几乎所有(注意,是几乎所有,不是一个单独的所有或一个单独的全部)使用数组名的表达式中,数组名的值是一个只读指针(也就意味着,不能修改它的值,数组名不能作为可修改的左值。数组名的值,不是数组中某个元素的值)。

为什么上面说的是几乎所有呢?

当数组名作为sizeof操作符或单目操作符&的操作数时,数组名并不是指针常量。

sizeof(list),返回的是整个数组的长度,而不是指向数组的指针的长度。

&list,产生的是一个指向数组的指针,而不是一个指向指针常量值的指针。

注意上面的第二点,在多数早期版本的C语言实现中,并没有“数组的地址”这个概念,因此,&list,要么是非法的,要么就等同于list

除了优先级外,下标引用和间接访问是完全相同的!

array[subscript]等同于*(array + (subscript))

*(list + 3)等同于list[3]

(list + 3)等同于(3 + list),也等同于3[list]

下标引用可以作用于任意的指针,而不仅仅是数组名。

下标绝不会比指针更有效率,但,指针有时会比下标更有效率(前提是,它们被正确地使用)。

指针和数组并不是相等的!

举个例子,

1
2
int a[5];
int *b;

声明数组a时,编译器为a保留5int所需的连续的内存空间,然后再创建数组名a,让a指向这段内存空间的起始位置。

声明指针b时,编译器只为指针b保留内存空间,此时,指针并未指向任何内存空间。

当使用数组或指针作为函数参数时,哪个更准确呢?答案是指针,因为,实参实际上是指针,而不是数组。只传递给函数一个数组名,是无法在函数内部得知数组的长度的(得知的是指针的长度),这也就反证了,实参实际上是指针,而不是数组。

C语言中只存在一维数组,所谓的多维数组,只是多个一维数组嵌套而来的,也可以说成是仿真模拟


C语言数组与指针
https://daniate.github.io/2016/10/08/C语言数组与指针/
作者
Daniate
发布于
2016年10月8日
许可协议