为什么在C / C ++中的多维数组中a [0]与a相同?

时间:2018-08-17 17:14:41

标签: c++ c pointers multidimensional-array

我有以下程序

#include<stdio.h>

int main() {
    int a[3][3]={{1,2,3},
                {4,5,6},
                {7,8,9}};

    printf("%p\n",a);
    printf("%p\n",a[0]);
    printf("%p\n",*(a+0));
}

它给了我以下输出:

6356716
6356716
6356716

我期望给定6356716这样的基址,然后*(6356716+0)将产生该位置内的值(即1)。

因此,如果像上面的表达式中那样,数组名称等于指向其第一个值的指针,则打印“ a”应将指向其第一个值的指针即a [0](其自身在位置处衰减为其第一个元素) 6356716)。在这种情况下,为什么取消引用在这里不起作用,并且*(a+0)计算为 *(6356716+0)

3 个答案:

答案 0 :(得分:1)

a是由3个int组成的3个数组。当用在除sizeof,一元&_Alignof的操作数以外的表达式中时,它将自动转换为指向其第一个参数的指针,该指针是3的数组{1}}。如果正确打印该指针,它将显示3 int的数组的地址。

inta[0]中的第一个元素,因此它是3 a的数组。在表达式中使用时,除上述相同外,它会自动转换为指向其第一个元素int的指针。如果正确打印此指针,它将显示该int的地址。

由于数组只是连续存储的对象序列,因此数组从其第一个元素所在的位置开始。因此,打印inta的结果显示相同的地址。

a[0]*(a+0)相同,因此打印它具有相同的结果。

您不应使用a[0]打印地址。使用%u打印指针具有未定义的行为。在某些情况下,它似乎可以在您的实现中起作用,但在其他情况下,它将破坏。要打印地址,请使用%u,并将指针转换为%pvoid *

const void *

答案 1 :(得分:0)

用于

maxBound

printf("%u\n", a); printf("%u\n", a[0]); 衰减到指向a的第一个元素的指针,而a衰减到指向a[0]的第一个元素的指针。同样,您可以使用:

a[0]

从对象类型的角度来看,printf("%u\n", &a[0]); printf("%u\n", &a[0][0]); &a&a[]是完全不同的指针类型。但是,如果查看2D数组的内存布局,您会意识到,从纯数值的观点来看&a[0][0] == &a == {{ 1}}。

此外,&a[]也不是打印指针的正确格式。您应该使用&a[0][0]

"%u"

答案 2 :(得分:0)

您需要了解的第一件事是将2D数组视为数组的数组,并且2D数组的所有元素都存储在连续的内存位置中,现在要了解的第二件事是数组名称实际上给出了地址因此,您的第一个printf语句<nav> <div class="center"> <a href="index.html">Home</a> <span class="holder"> <button class="dropbtn" onclick="myFunction()">Works <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content" id="myDropdown"> <a href="drawing.html">Drawing</a> <a href="animation.html">Animation</a> <a href="design.html">Design</a> </div> </span> <a href="about.html">About</a> <a href="contact.html">Contact</a> <a href="links.html">Links</a> </div> </nav>实际上为您提供了printf("%u\n",a);的地址,因为a[0]是此2D数组中的第一个元素。现在,您的第二个printf语句{{ 1}}的地址为a[0],因为printf("%u\n",a[0]);实际上是2D数组中第一个数组的名称。现在,最后一个printf语句为a[0][0]实际上是内部编译器的方式对待数组,它与第二个数组完全相同。从解释中可以明显看出,这三个语句是指相同的地址,但这并不意味着它们是同一对象,与第二和第三个,如上所述。尽管这三个语句为您提供了a[0]的地址,该地址是2D数组。