《C程序设计语言》(第2版·新版) P84~85
int a[];
int* pa;
下标和指针运算之间具有密切的对应关系。根据定义,数组类型的变量或表达式的值是该数组第0个元素的地址。执行赋值语句
pa = &a[0];
后,pa和a具有相同的值。因为数组名所代表的就是该数组最开始的一个元素的地址,所以,赋值语句pa = &a[0]也可以写成下列形式:
pa = a;
对数组元素a[i]的引用也可以写成*(a+i)这种形式。对此你可能觉得奇怪~?在计算数组元素a[i]的值时,C语言实际上先将其转换为*(a+i)的形式,然后再进行求值,因此在程序中这两种形式是等价的。如果对这两种等价的表示形式分别施加地址运算符&,便可以得出这样的结论:&a[i]和a+i的含义也是相同的。a+i是a之后第i个元素的地址。相应的,如果pa是一个指针,那么在表达式中也可以在它后面加下标。pa[i]与*(pa+i)是等价的。简而言之,一个通过数组和下标实现的表达式,可等价地通过指针和偏移量实现。
但是必须记住,数组名和指针之间有一个不同之处。指针是一个变量,因此,在C语言中,语句pa=a和pa++都是合法的。但数组名不是变量,因此类似于a = pa和a++形式的语句是非法的。
当把数组名传递给一个函数时,实际上传递的是该数组的第一个元素的地址。在被调用函数中,该参数是一个局部变量,因此,数组名参数必须是一个指针,也就是一个存储地址值的变量。
-----------------------------------------
在函数定义中,形式参数
char s[];
和
char *s
是等价的。通常习惯用后一种,因为它比前者更直观地表明了该参数是一个指针。如果将数组名传递给函数,函数可根据情况判定是“按照数组处理”还是“按照指针处理”,随后根据相应的方式操作该参数。为了直观且恰当地描述函数,在函数中甚至可以同时使用数组和指针这两种表示方式。
也可以将指向子数组起始位置的指针传递给函数,这样,就将数组的一部分传递给了函数。例如,如果a是一个数组,那么下面两个函数调用
f(&a[2])
与
f(a+2)
都将把起始于a[2]的子数组的地址传递给函数f。在函数f中,参数的声明形式可以为
f(int arr[]) {...}
或
f(int *arr) {...}
对于函数f来说,它并不关心所引用的是否只是一个更大数组的部分元素。
本文探讨了C语言中数组与指针的关系,详细解释了如何通过指针操作数组,包括指针与数组间的相互转换及应用。此外,还讨论了在函数间传递数组时的注意事项。
171万+

被折叠的 条评论
为什么被折叠?



