C 有人能解释一下为什么这个程序会这样吗?
我有以下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(因为这会衰减为&
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。@HolyBlackCatint*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]);
}