文章目录
- 函数如何使用指针来处理数组
- 将数组作为参数意味着什么
- 数组名和指针对应是好的吗?
- 参考资料
函数如何使用指针来处理数组
在大多数情况下,C++和 C 语言一样,也将数组名视为指针。
C++将数组名解释为其第一个元素的地址:
cookies == &cookies[0] // array name is address of first element
该规则有一些例外。
首先,数组声明使用数组名来标记存储位置;
其次,对数组名使用 sizeof 将得到整个数组的长度(以字节为单位):
第三,将地址运算符&用于数组名时,将返回整个数组的地址,例如&cookies 将返回一个32 字节内存块的地址(如果int长4字节)
执行下面的函数调用:
int sum = sum arr(cookies, ArSize);
其中,cookies 是数组名,而根据 C++规则,cookies 是其第一个元素的地址,因此函数传递的是地址由于数组的元素的类型为 int,因此 cookies 的类型必须是 int 指针,即 int*。这表明,正确的函数头应该是这样的:
int sum arr(int * arr, int n) // arr = array name, n = size
其中用 int*arr 替换了 int arr []。这证明这两个函数头都是正确的。
因为在 C++中,当(且仅当)用于函数头或函数原型中,int *arr 和 int arr []的含义才是相同的。它们都意味着 arr 是个int 指针。然而,数组表示法 (int arr[]) 提醒用户,arr 不仅指向 int,还指向 int 数组的第一个int。
当指针指向数组的第一个元素时,使用数组表示法:而当指针指向一个独立的值时,使用指针表示法。
别忘了,在其他的上下文中,int*arr 和 int arr []的含义并不相同。例如,不能在函数体中使用 int tip[ ]来声明指针。
鉴于变量 arr 实际上就是一个指针,函数的其余部分是合理的。同数组名或指针一样,也可以用方括号数组表示法来访问数组元素。无论 arr 是指针还是数组名,表达式 arr [3]都指的是数组的第 4个元素。就目前而言,记住下面两个恒等式,将不会有任何坏处:
arr[i] == *(ar + i)// values in two notations
&arr[i] == ar + i// addresses in two notations
记住,将指针(包括数组名)加 1,实际上是加上了一个与指针指向的类型的长度(以字节为单位)相等的值。对于遍历数组而言,使用指针加法和数组下标是等效的。
将数组作为参数意味着什么
函数调用 sum_arr(coolies,ArSize)将 cookies 数组第一个元素的地址和数组中的元素数目传递给 sum_arr()函数。
sum_arr()函数将 cookies 的地址赋给指针变量arr,将ArSize 赋给 int 变量 n。这意味着,程序实际上并没有将数组内容传递给函数,而是将数组的位置(地址)包含的元素种(类型)以及素数目(n 变量)提交给函数:
有了这些信息后函数便可以使用原来的数组。传递常规变量时,函数将使用该变量的拷贝;但传递数组时,函数将使用原来的数组。实际上,这种区别并不违反 C++按值传递的方法,sum_arr()函数仍传递了一个值,这个值被赋给一个新变量,但这个值是一个地址,而不是数组的内容。
数组名和指针对应是好的吗?
确实是一件好事。将数组地址作为参数可以节省复制整个数组所需的时间和内存。如果数组很大,则使用拷贝的系统开销将非常大;程序不仅需要更多的计算机内存,还需要花费时间来复制大块的数据。另一方面,使用原始数据增加了破坏数据的风险。
参考资料
《C++ PRIME PLUS》