是一个二维数组的名称,它在C++中的第一个元素的地址

Is the name of a two dimensional array address of the address of its first element in C++?

本文关键字:它在 C++ 地址 元素 第一个 二维数组 一个      更新时间:2023-10-16

实现这样的二维数组时:int a[3][3];它们保持:A=&A[0],同时保持A[0]=&A[0][0]。所以,A=&(&A[0][0]),基本上说A是数组第一个元素的地址,这不完全正确。我在这里犯了什么错?A真的衰减为指向指针的指针吗?

您的错误是对数组和指针之间的关系理解不正确。数组不是指针。它是一个数组。但是,数组可以隐式转换为指向其第一个元素的指针。所以,虽然这个表达式的计算结果是真的:

A == &A[0]

A&A[0]是不对的。并非所有表达式都发生转换。例如:

&A

这不采用A的第一个元素的地址的地址(这甚至没有意义)。它采用A的实际地址,其类型为int[3][3]。所以&A的类型是int(*)[3][3],读作"指向3个int数组的数组的指针"。

&A&A[0]之间的主要区别在于,如果将1添加到&A,则会得到一个距离3 * 3 * sizeof(int)字节的地址,而如果将1加到&A[0],则会获得一个距离仅3 * sizeof(int)字节的指针。

考虑到所有这些,你应该能够看到你的错误在哪里。A[0]而不是&A[0][0],但它可以隐式转换为它。然而,与所有转换一样,这会导致一个临时的,你不能取它的地址。因此,表达式&(&A[0][0])甚至没有意义。

由于对我之前回答的反应,我做了一些研究,以了解更多关于我解释中错误的地方。在这里找到了一个相当详细的主题解释:

http://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c

我将尝试总结一下:

如果您有以下内容:

char array_place[100] = "don't panic";
char* ptr_place = "don't panic";

这在内存中的表现方式完全不同。ptrplace是一个真正的指针,array_place只是一个标签。

char a = array_place[7];
char b = ptr_place[7];

C中数组的语义规定数组名称是数组第一个元素的地址,这与说它是指针不同因此,在对a的赋值中,数组的第8个字符是通过将array_place的值偏移7,并将结果地址指向的内容移动到al寄存器中,然后再移动到a中来获得的。

指针的语义大不相同。指针只是一个正则变量,恰好在其中包含另一个变量的地址。因此,为了实际计算字符串第8个字符的偏移量,CPU将首先将指针的值复制到寄存器中,然后再递增。这需要另一条指令[1]。

这一点经常被那些并没有真正破解编译器的程序员所忽视。C中的变量只是存储位置的一个方便的字母数字假名。如果我们编写汇编代码,我们只需要在某个内存位置创建一个标签,然后访问这个标签,而不是总是对内存值进行硬编码——这就是编译器所做的。

实际上,由于加载和重新定位的问题,地址并没有以绝对的方式进行硬编码,但为了进行讨论,我们不必讨论这些细节。

标签是编译器在编译时指定的东西从这里可以看出数组和指针之间的巨大区别这也解释了为什么sizeof(array_place)给出数组的完整大小,其中指针的大小将给出指针的大小

我必须说,我自己并没有意识到这些细微的差异,而且我已经用C和C++以及数组编码了很长一段时间。

然而,如果数组元素的名称是数组的第一个元素的地址。你可以创建一个指针并初始化它的值

char* p = array_place

p将指向字符所在的内存位置。

得出结论:

数组名称和指针之间有一个区别,必须牢记。指针是一个变量,所以p=array_place和p++是合法的。但是数组名称不是一个变量;像array_place=p和array_place++这样的构造是非法的。我确实知道;-)

相关文章: