我有以下程序
#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)
?
答案 0 :(得分:1)
a
是由3个int
组成的3个数组。当用在除sizeof
,一元&
或_Alignof
的操作数以外的表达式中时,它将自动转换为指向其第一个参数的指针,该指针是3的数组{1}}。如果正确打印该指针,它将显示3 int
的数组的地址。
int
是a[0]
中的第一个元素,因此它是3 a
的数组。在表达式中使用时,除上述相同外,它会自动转换为指向其第一个元素int
的指针。如果正确打印此指针,它将显示该int
的地址。
由于数组只是连续存储的对象序列,因此数组从其第一个元素所在的位置开始。因此,打印int
和a
的结果显示相同的地址。
a[0]
与*(a+0)
相同,因此打印它具有相同的结果。
您不应使用a[0]
打印地址。使用%u
打印指针具有未定义的行为。在某些情况下,它似乎可以在您的实现中起作用,但在其他情况下,它将破坏。要打印地址,请使用%u
,并将指针转换为%p
或void *
:
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数组。