C 有人能解释一下为什么这个程序会这样吗?

C 有人能解释一下为什么这个程序会这样吗?,c,C,我有以下C语言程序: void main() { int x[3]; int* p = &x; printf("%d %d \n", p, x); } p和x的那些值似乎是相同的,但我不明白为什么p是指针x的地址,不应该有类似*p=x的东西来代替p=x?最大的问题是p和&x是不同的类型 &x给出的指针是指向整个数组x,而不是单个元素的指针,其类型是int(*)[3],而不是int* 如果要获取指向x的第一个元素的指针,请使用&x[0],或普通x(因为这会衰减为&

我有以下C语言程序:

void main() {
    int x[3];
    int* p = &x;
    printf("%d %d \n", p, x);
}

p
x
的那些值似乎是相同的,但我不明白为什么p是指针x的地址,不应该有类似
*p=x
的东西来代替
p=x

最大的问题是
p
&x
是不同的类型

&x
给出的指针是指向整个数组
x
,而不是单个元素的指针,其类型是
int(*)[3]
,而不是
int*

如果要获取指向
x
的第一个元素的指针,请使用
&x[0]
,或普通
x
(因为这会衰减为
&x[0]

即使
&x
&x[0]
的类型不同,它们都指向相同的位置(正如(无效)打印输出所示)。如果尝试在内存中可视化数组
x
,则可以看到这一点:

+------+------+------+ | x[0] | x[1] | x[2] | +------+------+------+ ^ | &x | &x[0]
您的代码在编译时会产生一些警告:

warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=] 
warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘int *’ [-Wformat=] 
编译后的代码会导致未定义的行为,而相同的结果是由于未定义的行为

提示
您的代码在概念上是错误的,请阅读更多关于C语言中指针、数组e类型的内容。

程序中有几个问题导致未定义的行为


首先,数组
x
未初始化,稍后访问它会导致UB


第二,当用作指针时,
x
已经是数组
x
的第一个元素的地址(相当于
&x[0]
);因此,
&x
将是指向该指针的指针。 第三,
%d
需要一个整数值,而不是指向整数值的指针;因此,您需要取消对
p
x
的引用

以下程序的行为应符合您的预期:

int main() {
    int x[3] = { 1,2,3 };
    int* p = x;
    printf("%d %d \n", *p, x[0]);
}

对于初学者来说,
int*p=&x不应编译。如果它能为您编译,您可能应该切换到更严格的编译器设置。在这种情况下,
x
&x
具有相同的值,但类型不同。@一些程序员使用
-pedantic错误拒绝它。¯\_(ツ)_/“
&x
的类型是
int(*)[3]
,而不是
int*
。此外,您不使用
%d
printf(“%d%d\n”,p,x);
printf(%p%p\n),(void*)p,(void*)x);
从技术上讲,
int*p=&x;
使代码格式错误,而不是导致UB(不应编译)。如果忽略这一点,
printf(“%d%d\n”,p,x);
确实会导致UB。@HolyBlackCat
int*p=&x;
属于“指向对象类型的指针可能会转换为指向其他对象类型的指针。如果生成的指针与引用的类型没有正确对齐,则行为未定义”。因此,可能的UB。“以后访问它会导致UB。”-->OP的代码不访问
x
的内容,只访问它的地址,因此没有UB。因此
&x
将是指向该指针的指针。”-->
&x
是指向数组的指针。数组不是指针,指针不是数组。
&x
是类型
int(*)[3]
int main() {
    int x[3] = { 1,2,3 };
    int* p = x;
    printf("%d %d \n", *p, x[0]);
}