【问题标题】:Getting negative address in c在c中获取负地址
【发布时间】:2016-04-07 06:16:20
【问题描述】:
#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 的负值。我研究过地址不能为负数。那为什么我得到一个负值

【问题讨论】:

  • "地址不能为负数" - 当然可以。不过,您的代码具有未定义的行为,因此您不应从其输出中得出任何结论。
  • @Mat;有否定地址的例子吗?
  • @hacks:x86_64 上一半的地址空间(除非你想把它们都视为无符号,显然)
  • 您可以使用%u 打印无符号值。

标签: c arrays pointers printf


【解决方案1】:

对于指针,使用%pprintf()

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. %d 不是处理指针(地址)的正确格式说明符。您应该使用%p 并将相应的参数转换为void* 以打印地址。对特定格式说明符使用错误的参数类型会调用 undefined behavior

      引用C11 章节§7.21.6.1

      [...] 如果有任何参数 不是相应转换规范的正确类型,行为是 未定义。

    2. 无论如何,在这段代码中,*p 并不表示地址。

    3. 您不能仅在单个格式字符串中使用%ds 来打印数组。你需要有一个循环。在您的代码中,

      printf("%d\n%d\n%d\n%d\n%d\n", p, *p);
      

      格式字符串需要 5 个ints 作为参数,而您只提供一个指针和一个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);
    

    【讨论】:

      【解决方案3】:

      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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-25
        • 1970-01-01
        • 2013-07-25
        • 2013-02-27
        • 2012-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多