Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在C/C+中使用多维数组+;a[0]与a相同吗?_C++_C_Pointers_Multidimensional Array - Fatal编程技术网

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

C++ 为什么在C/C+中使用多维数组+;a[0]与a相同吗?,c++,c,pointers,multidimensional-array,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+0)将在该位置内产生值(即1) 因此

我有以下程序

#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+0)
将在该位置内产生值(即
1

因此,如果数组名等效于指向其第一个值的指针(如上述表达式中所示),则打印“a”应打印指向其第一个值的指针,即a[0](其本身衰减到位置6356716处的第一个元素)。在这种情况下,为什么取消引用在这里不起作用,而
*(a+0)
的计算结果是
*(6356716+0)

在中使用时

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[]
&a[0][0]
是完全不同的指针类型。但是,如果您查看2D阵列的内存布局,您将意识到,从纯数值的角度来看,
&a
=
&a[]
=
=
&a[0][0]

另外,
“%u”
不是打印指针的正确格式。您应该使用
“%p”


a
是一个由3个数组组成的数组,其中3个
int
。当在表达式中使用而不是作为
sizeof
、一元
&
\u Alignof
的操作数时,它会自动转换为指向其第一个参数的指针,这是一个3
int
的数组。如果正确打印此指针,它将显示3
int
数组的地址

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

由于数组只是连续存储的对象序列,因此数组的起始位置与其第一个元素的起始位置相同。因此,打印
a
a[0]
的结果显示相同的地址

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

您不应使用
%u
打印地址。使用
%u
打印指针具有未定义的行为。在某些情况下,它可能在您的实现中起作用,但在其他情况下它会中断。要打印地址,请使用
%p
并将指针转换为
void*
const void*

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

您需要了解的第一件事是2D数组被视为数组的数组,2D数组的所有元素都存储在连续的内存位置,现在需要了解的第二件事是数组名实际上给出了其中第一个元素的地址
实际上为您提供了
a[0]
的地址,因为
a[0]
是这个2D数组中的第一个元素。现在,您的第二个printf语句
printf(“%u\n”,a[0])
为您提供
a[0][0]
的地址,因为
a[0]
实际上是2D数组中第一个数组的名称。现在,您的最后一个printf语句是
printf(“%u\n”,*(a+0))
实际上是编译器内部处理数组的方式,它与第二个完全相同。从解释中可以清楚地看出,这三个语句引用的是相同的地址,但这并不意味着它们是相同的东西,第一个语句与上面解释的第二个和第三个语句相比具有不同的含义。尽管这三个语句为您提供了
1
的地址,这是2D数组的第一个元素。

C/C++==UB
请选择一种语言。此代码中的任何内容实际上都是指该值(即1)。第二张和第三张照片是相等的。可能的副本是不一样的,所以你的问题是没有意义的。@pmg很好的类比。只是
*(a+0)
a[0]
完全相同。UB:printf指针格式错误。发送地址相同,但引用的对象不同(类型不同)。@P_uj_u,你说得对。我只是在回答核心问题,但我已经更新了一点答案。
printf("%p\n", a);
printf("%p\n", a[0]);
printf("%p\n", (const void *) a);
printf("%p\n", (const void *) a[0]);
printf("%p\n", (const void *) *(a+0));