#include <stdio.h>
int main(void) {
int a[5] = {0, 1, 2, 3, 4}, *p;
p = a;
printf("%d\n%d\n%d\n%d\n%d\n", p, *p);
return 0;
}
当我执行此代码时,我得到p的负值。我研究过地址不能否定。那我为什么得到一个负值
答案 0 :(得分:5)
%d
不是处理指针(地址)的正确格式说明符。您应该使用%p
并将相应的参数强制转换为void*
以打印地址。对特定格式说明符使用错误的参数类型会调用undefined behavior。
引用C11
章节§7.21.6.1
[...]如果有任何论据 不是相应转换规范的正确类型,行为是 未定义。
在此代码中,*p
无论如何都不表示地址。
您只能在单个格式字符串中使用%d
来打印数组。你需要一个循环。在您的代码中,
printf("%d\n%d\n%d\n%d\n%d\n", p, *p);
格式字符串需要5 int
s作为参数,而您只提供指针和int
。 FWIW,为提供的转换说明符提供的参数不足也会调用undefined behavior。引用相同的标准,
[...]如果格式的参数不足,则行为为 未定义。 [...]
详细说明,替换
printf("%d\n%d\n%d\n%d\n%d\n", p, *p);
通过
for (i= 0; i < 5; i++, p++)
printf("%d %p\n", *p, (void *)p);
答案 1 :(得分:3)
对于指针,请将%p
与printf()
:
int a[5] = {0, 1, 2, 3, 4}, *p;
p = a;
printf("%p\n%d", (void *)p, *p);
还要确保您的漫威警告处于最高级别。您应该收到使用%d
指针的警告:
warning <code>: 'printf' : '%d' in format string conflicts with argument 1 of type 'int *'
答案 2 :(得分:1)
错误匹配的printf()
说明符和参数
printf("%d\n%d\n%d\n%d\n%d\n", p, *p);
预计5 int
。代码正在提供int *
和int
。结果:未定义的行为。
相反:
printf("Pointer %p\nValue: %d\n", (void *) p, *p);