为什么在为数组中的第一个元素赋值时必须指定索引号? 假设我们有这个数组:
int childer[] = {10, 30, 50};
那么childer
和childer[0]
都将访问数组的第一个元素,那么为什么你不能childer = 15;
呢?
数组类似于指针。例如,当传递给函数时,数组会衰减到指针,甚至当运算符[]
并且一元*
应用于它们时(感谢 StoryTeller)。所以
childer[0]
相当于
*childer
你可以做到
*childer = 15;
将第一个元素设置为 15。
childer
另一方面与
&childer[0]
childer[0]
和childer
有两种不同的含义。childer[0]
是数组的第一个元素,而childer
是指向第一个元素的指针。为了使用指针获取第一个元素,您必须使用*childer
。
所以
*childer = 15;
可用于分配。
你可以取消引用数组的名称,但只是尝试这样做
childer = -999;
完全错了...
请参阅以下示例:
int main() {
int childer[] = { 10, 30, 50 };
cout << childer[0] << endl;
cout << *childer << endl;
//now write
childer[0] = 200;
cout << childer[0] << endl;
cout << *childer << endl;
//now write again
*childer = -999;
cout << childer[0] << endl;
cout << *childer << endl;
return 0;
}
首先
int childer[] = { 10, 20, 30 };
...
childer = ....; <--- THIS WILL NOT COMPILE, as childer is not an lvalue.
你不能说childer = 20;
,你可以说childer[0] = 20;
或*childer = 20;
,甚至更*(childer + 1) = 20;
(访问第一个元素以外的其他元素),但你不能在赋值中使用childer
作为整个数组。 简单地说,C和C++都不允许这样做。
数组和指针是非常不同的东西。让您感到困惑的是,C和C++都没有办法引用整个数组,数组标识符本身意味着第一个元素的地址(不是指针而是引用)。 我所说的引用是指,我刚才没有使用指针这个词,指针通常是指指针类型的变量,并且作为变量可以修改(主要是因为数组位置不能在运行时更改)。 你不能写像array = something_else;
这样的东西,当array
是一个数组时。 数组名称本身不能用作左值,只能用作右值。 这可以通过指针来完成,例如
int childer[] = { 10, 20, 30, };
int *pointer = childer;
然后
pointer = some_other_place_to_point_to;
因为pointer
是指针,而childer
不是。
两种语言都归因于数组名称的含义只是一个指向第一个元素地址的指针 rvalue(并键入为单元格类型,请继续阅读以获取有关此内容的解释)。 这与数组的地址(两者都是不同的东西,如下所示)不同(数组名称是指向单元格类型的指针,而数组地址&childer
是指向整个数组类型的指针)不同。 这可以用下一个程序来说明,该程序试图向您展示数组元素、整个数组、数组指针和单元格指针的大小差异:
#include <stdio.h>
#include <sys/types.h>
#define D(x) __FILE__":%d:%s: " x, __LINE__, __func__
#define P(fmt, exp) do {
printf(D(#exp " == " fmt "n"), (exp));
} while(0)
#define TR(sent)
sent;
printf(D(#sent ";n"))
int main()
{
int i = 1;
TR(double a[10]);
P("%p", a);
P("%p", &a);
P("%d", sizeof a);
P("%d", sizeof &a);
P("%d", sizeof *a);
P("%d", sizeof *&a);
return 0;
}
它执行到 (我选择double
作为单元格的类型,以在尝试更加独立于架构的同时明显差异):
$ pru
pru.c:16:main: double a[10]; <-- array of ten double's (a double is 8 bytes in many architectures)
pru.c:18:main: a == 0xbfbfe798 <-- address values are
pru.c:19:main: &a == 0xbfbfe798 <-- equal for both.
pru.c:20:main: sizeof a == 80 <-- size of whole array.
pru.c:21:main: sizeof &a == 4 <-- size of array address (that's a pointer to array)
pru.c:22:main: sizeof *a == 8 <-- size of pointed cell (first array element)
pru.c:23:main: sizeof *&a == 80 <-- size of pointed array.
但是你说你不能使用表达式来访问其他元素是错误的,因为你可以使用array + 1
来表示第二个元素的地址,array + n
来访问n + 1
元素的地址。 显然array + 0
与array
相同(0
数字在指针加法中也是中性的),因此您可以轻松上手。 有些人也喜欢把它写成0+array
(滥用+
运算符的交换性)并更进一步,写类似0[array]
的东西,引用数组的第一个元素(这次访问是对该元素的访问,而不是它的地址)我不知道这是否在新标准中继续有效, 但恐怕它可能会继续,也许,允许遗留代码可编译(增加了关于应该保存什么和什么可以在标准修订版中消除的争议)