【问题标题】:String #define returns a random integerString #define 返回一个随机整数
【发布时间】:2013-05-24 16:05:41
【问题描述】:

据我所知#define 只是一个字符串替换,它不是一个变量,所以它没有任何内存地址或其他东西。

假设这段代码:

#include <stdio.h>

#define ONE "a"

main() {
    printf("the number is: %d\n", ONE);
}

然后当我编译运行这个程序时,每次都会得到一个随机字符串:

号码是:8179551

号码是:21127007

号码是:57114463

...

如果#define 没有任何内存地址,那么这个值是多少,为什么每次都改变?

【问题讨论】:

  • 您正在打印字符串的地址。 (尝试使用“a”而不是 ONE 来执行相同的 printf——你会得到相同的结果。)
  • 答案的后半部分是你的系统使用en.wikipedia.org/wiki/Address_space_layout_randomization
  • 您的程序通过使用%d 格式传递指向printf 的指针来调用未定义的行为,因此您应该避免故意这样做。

标签: c c-preprocessor c-strings


【解决方案1】:

在您的代码中

printf("the number is: %d\n", ONE);

等价于

printf("the number is: %d\n", "a");

实际上,您将字符串"a" 的地址打印为十进制。

你在每次执行中都得到随机值,这是因为"a"的地址在每次执行中都是随机地址

字符串"a" 是一个文字字符串,它存储在只读存储器中。 printf 正在打印此内存的地址

【讨论】:

  • 那应该每次都改吧? printing the address of the string 是什么意思?
  • @AfshinMehrabani 字符串“a”是一个文字字符串,它存储在只读存储器中。 printf 正在打印此内存的地址
  • 奇怪。我不知道字符串也存储在内存中!对不起,我是新手。
  • @AfshinMehrabani 你想做什么?
  • @MOHAMED 没什么复杂的,我只是想知道#defineC 中的常量之间的区别,所以我写了这段代码来看看。谢谢你。
【解决方案2】:

MOHAMED 是对的,你打印了一个字符串的地址

你要做什么

#define ONE 'a'

两个' 之间的所有内容都是字符,只允许一个字符

【讨论】:

    【解决方案3】:

    此程序调用未定义行为,因为格式规范与参数类型不匹配(intchar *)。

    C99, 7.19.6.1 # 9 (fprintf)

    如果转换规范无效,则行为是 undefined.239) 如果任何参数不是正确的类型 相应的转换规范,行为未定义。

    打印地址的正确方法是使用%p(void *) 参数:

    printf("the address is: %p\n", (void *)ONE);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-29
      相关资源
      最近更新 更多