第8章 再论数组
所有作为函数参数的数组名总是可以通过编译器转换为指针。在其它情况下,两者不能混淆。但在使用数组(在语句或表达式中引用)时,数组总是可以写成指针的形式,两者可以互换。
对编译器而言,一个数组名就是一个地址,一个指针就是一个地址的地址。
在表达式中,指针和数组是可以互换的,因为它们在编译器里的最终形式都是指针,并且都可以进行取下标操作。
编译器需要知道对指针进行解除引用操作时应该取几个字节,以及每个下标的步长应取几个字节,因此指针总是有类型限制,每个指针只能指向一种类型。
在处理一维数组时,指针并不见得比数组更快。C语言把数组下标改写成指针偏移量的根本原因是指针和偏移量是底层硬件所使用的基本模型。
在函数形参定义这个特殊情况下,编译器必须把数组形式改写成指向数组第一个元素的指针形式。编译器只向函数传递数组的地址,而不是整个数组的拷贝。
把作为形参的数组和指针等同起来是出于效率原因的考虑。在C语言中,所有非数组形式的数据实参均以传值形式(对实参作为一份拷贝并传递给调用函数,函数不能修改作为实参的实际变量的值,而只能修改传递给它的那份拷贝)调用。然而,如果要拷贝整个数组,无论在时间上还是在内存空间上的开销都可能是非常大的。而且在绝大部分情况下,其实并不需要整个数组的拷贝,只想告诉函数在那一时刻对哪个特定的数组感兴趣。
函数的返回值绝不能是一个数组或函数,而只能是指向数组或函数的指针。
有一样操作只能在指针里进行而无法在数组名中进行,那就是修改它的值。数组名是不可修改的左值,它的值是不能改变的。
可以让指针指向数组中任何一个元素,这样传递给函数的就是从该元素之后的数组片段。
数组和指针可交换性的总结:
1、用a[]这样的形式对数组进行访问总是被编译器“改写”或解释为像*(a+1)这样的指针访问。
2、指针始终就是指针,决不可能改写成数组。
3、在特定的上下文中,也就是它作为函数的参数,一个数组的声明可以看作是一个指针。作为函数参数的数组始终会被编译器修改成为指向数组第一个元素的指针。
4、当把一个数组定义为函数的参数时,可以选择把它定义为数组,也可以定义为指针。不论选择何种方法,在函数内部事实上获得的都是一个指针。
5、在其它所用情况中,定义和声明必须匹配。
C语言里面只有一种别的语言成为数组的数组的形式。当提到C语言中的数组时,就把它看作是一种向量,也就是某种对象的一维数组,数组的元素可以是另一个数组。
不能把一个数组赋值给另一个数组,因为数组作为一个整体不能成为赋值的对象。可以把数组名赋值给一个指针,因为在表达式中数组名被编译器当作一个指针。
在C语言的多维数组中,最右边的下标是最先变化的,这个约定被称为行主序。C语言中多维数组最大的用途是存储多个字符串。
只有字符串常量才可以初始化指针数组,指针数组不能由非字符串的类型直接初始化。
文章评论(0条评论)
登录后参与讨论