为什么在 C/C++ 中的多维数组中 a[0] 与 a 相同?
Why in multi-dimentional array in C/C++ a[0] is same as a?
我有以下程序
#include<stdio.h>
int main() {
int a[3][3]={{1,2,3},
{4,5,6},
{7,8,9}};
printf("%pn",a);
printf("%pn",a[0]);
printf("%pn",*(a+0));
}
它给了我以下输出:
6356716
6356716
6356716
我期望,给定一个基址,例如6356716
,那么*(6356716+0)
将产生该位置内的值(即1
(。
因此,如果数组名称等效于指向其第一个值的指针,如上面的表达式所示,打印"a"应将指针打印到其第一个值,即 a[0](它本身在位置 6356716 处衰减到其第一个元素(。在这种情况下,为什么取消引用在这里不起作用,*(a+0)
计算结果为*(6356716+0)
?
a
是一个由 3 个数组组成的数组,每个数组的数组为 3 个int
。当在表达式中用作sizeof
、一元&
或_Alignof
的操作数时,它会自动转换为指向其第一个参数的指针,这是一个 3int
的数组。如果正确打印此指针,它将显示该数组的地址 3int
。
a[0]
是a
中的第一个元素,所以它是一个3int
的数组。在表达式中使用时,除上述相同例外情况外,它会自动转换为指向其第一个元素的指针,即int
。如果正确打印此指针,它将显示该int
的地址。
由于数组只是连续存储的对象序列,因此数组从其第一个元素的同一位置开始。因此,打印的结果a
和a[0]
显示相同的地址。
*(a+0)
与a[0]
相同,因此打印它的结果相同。
不应使用%u
打印地址。打印带有%u
的指针具有未定义的行为。在某些情况下,它可能在您的实现中似乎有效,但在其他情况下会中断。要打印地址,请使用%p
,并将指针转换为void *
或const void *
:
printf("%pn", (const void *) a);
printf("%pn", (const void *) a[0]);
printf("%pn", (const void *) *(a+0));
首先你需要了解的是,一个二维数组被当作一个数组的数组,二维数组的所有元素都存储在连续的内存位置,现在第二个要了解的是数组名称实际上给出了其中第一个元素的地址。所以你的第一个printf语句实际上printf("%un",a);
给你a[0]
的地址,因为a[0]
是这个2D数组中的第一个元素。现在你的第二个printf语句printf("%un",a[0]);
给你a[0][0]
的地址,因为a[0]
实际上是2D数组中第一个数组的名称。现在你的最后一个printf语句printf("%un",*(a+0));
实际上是编译器内部处理数组的方式,它与第二个完全相同。从解释中可以清楚地看出,这三个语句指的是同一个地址,但这并不意味着它们是同一回事,与上面解释的第二个和第三个语句相比,第一个语句的含义不同。虽然这三个语句给你的地址是1
,这是2D数组的第一个元素。
在
printf("%un", a);
printf("%un", a[0]);
a
衰减到指向a
第一个元素的指针,a[0]
衰减到指向a[0]
的第一个元素的指针。等效地,您可以使用:
printf("%un", &a[0]);
printf("%un", &a[0][0]);
从对象类型的角度来看,&a
、&a[]
和&a[0][0]
是完全不同的指针类型。但是,如果您查看 2D 数组的内存布局,您会发现,从纯数字的角度来看,&a
==&a[]
==&a[0][0]
.
此外,"%u"
不是打印指针的正确格式。您应该使用"%p"
.
printf("%pn", a);
printf("%pn", a[0]);
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 通过交换元素使数组相同
- 为什么 2 个相同数组的元素彼此相等
- 为什么 &a 和 c++ 中的静态数组相同?
- 可以将两个相同类型的连续数组视为一个数组吗?
- 如何在构造函数中使用初始值设定项设置具有相同值的 2d 数组?
- 声明后,gcc 的动态大小数组是否与标准数组有效相同?
- 如何初始化所有值相同的 2D 数组?
- 数组上的相同逻辑会产生不同的结果
- 为什么存储在数组中的地址值与其自己的地址相同,它应该指向某个不同的地址(&arr[0])?
- 如何防止每次 Arduino 启动时颜色数组都是相同的随机数组
- 为什么在 C/C++ 中的多维数组中 a[0] 与 a 相同?
- C++函数返回两个 char 数组的相同索引元素
- 检查反向数组是否与原始数组相同
- 为什么gzwrite向量和数组值相同的gzwrite数组不同
- 如何每次在不同大小的循环中重新声明相同的数组
- 如何在 c++ 中计算相同数组元素的数量
- 计数在C 中相同数组值的发生
- 具有相同数组索引的C 分割故障
- c++排序:具有相同数组值的排序列表