C 数组中元素的地址

C 数组中元素的地址,c,multidimensional-array,C,Multidimensional Array,有人能解释一下我是怎么得到这个的吗?下面是a、a+1和&a+1的情况: 答:由于a是一个数组,使用a会导致它衰减为指向该数组第一个元素的指针,该数组是一个由4个整数组成的数组,因此a的类型为int*[4]。这是您正在打印的地址:数组a的第一个元素的地址,也是第二级数组中第一个元素的地址 a+1:这与拾取a并将其移动到下一个对象(距离sizeofint*4字节)相同,因为a的每个元素都是4个整数的数组。因此,这将打印a中第二个元素的地址。 &a+1:这是不适用“数组到指针的衰减”规则的少数例外之一

有人能解释一下我是怎么得到这个的吗?

下面是a、a+1和&a+1的情况:

答:由于a是一个数组,使用a会导致它衰减为指向该数组第一个元素的指针,该数组是一个由4个整数组成的数组,因此a的类型为int*[4]。这是您正在打印的地址:数组a的第一个元素的地址,也是第二级数组中第一个元素的地址 a+1:这与拾取a并将其移动到下一个对象(距离sizeofint*4字节)相同,因为a的每个元素都是4个整数的数组。因此,这将打印a中第二个元素的地址。 &a+1:这是不适用“数组到指针的衰减”规则的少数例外之一。当数组是引用运算符&、sizeof的操作数或字符串文字初始值设定项时,它们不会衰减为指针。因此,&a不是指向由4个整数组成的数组的指针,而是数组的地址,按照惯例,数组的地址是a中第一个元素的地址。地址与a是相同,a和&a具有相同的地址,但区别在于&a具有指向int数组[3][4]的类型指针,即int*[3][4],这意味着&a+1的下一个对象距离sizeofint*3*4字节,这就是您得到的地址。 旁注:您应该使用%p打印指针值,而不是依赖指针与无符号int大小相同的事实。这是正确的:

 2293472,  2293488, 2293520
查看您得到的输出,我可以看到系统中的sizeofint是4。通过一点数学运算,你可以看到a+1实际上是a+16 2293472+4*4=2293488,&a+1距离是4*3*4字节;2293472+4*3*4=2293520

使用%u打印地址是未定义的行为,因此程序可以自由打印任何内容。在这种情况下,行为显然是由特定编译器实现的,它就是这样做的:

a是数组本身,因此它打印分配2D数组的地址。显然地址是2293472d。 a+1意味着由于a是算术表达式的一部分,它将衰减为指向其第一个元素的指针,而第一个元素又是由4个元素组成的数组。array+1意味着您需要获取该数组的地址+该数组的大小。以字节为单位,表示需要数组+4*sizeofint的地址。换句话说,2293472d+4*4=223488d。 &a+1意味着您获得一个指向整个数组的数组指针,然后将其增加一个整个数组的sizeof。2293472d+3*4*sizeofint=2293520。
理解这一点的关键是了解数组、指针和数组指针之间的区别,它们是3种不同但密切相关的类型。医生比我解释得更清楚。链接到这一章是所有C程序员的必读读物,初学者和退伍军人都一样。

好了,现在开始

您正在打印的只是一个指针,这是一个指针,显然会在输出屏幕上给出该指针的地址值

接下来,您将打印出a+1。int数据类型的大小为4字节。这里a[0][0]的地址是2293472。现在您需要a+1的地址值,其中a由4个整数组成。这将占用4*4=16字节的内存。所以a+1产生a的值加上16。那是2293488


接下来打印出&a+1。它给出的地址完全位于分配给变量的区域之后。这里是整数数组。数组由12个值组成,这意味着它需要48个字节的大小。因此,您得到的输出是2293472+48=2293520,这并不奇怪。你期待什么?你正在打印a的地址。另外,由于在执行getch之前返回,getch不会做任何事情。只是为了好玩,请使用%p作为格式说明符,如果愿意,请更新您的问题。结果的呈现可能会让你大吃一惊。与此无关,getch似乎有些毫无意义。请阅读我在回答中为char数组解释的第二个图表。一如既往:可靠打印数组或指针地址的唯一正确方法是使用%p占位符强制转换,并将相应的参数强制转换为void*,如const char*str=some string;printf%p\n,void*str;a的尾型是int[3][4],衰减为int*[4]@GrijeshChauhan,这就是我说的。
 2293472,  2293488, 2293520
printf("%p, %p, %p", (void *) a, (void *) (a+1), (void *) (&a+1));