【问题标题】:How to print a memory address?如何打印内存地址?
【发布时间】:2017-02-21 12:02:56
【问题描述】:

我在 youtube 教程上看到了关于人们 printf 变量的内存地址的指针。有问题的视频是在 Code:Blocks 中完成的,它与 %p 一起工作,但每当我在 Geany (VirtualBox) 中尝试完全相同的东西时,我都会遇到编译错误。我应该尝试另一种 %letter Linux 吗?

      int main(int argc, char *argv[]){
          int var;

          printf("%p\n", &var);

          return 0;
       }

我不需要它来做练习或其他事情,只是好奇(我猜是为了更好地理解指针的概念)。 提前致谢!

编辑:错误消息是 Linux 希望我在打印之前将 &var 转换为 (void*)。抱歉,我不是很清楚:我的问题基本上是,这是 Linux/Windows 的事情吗?为什么 Windows 会接受它,而 Linux 却希望我将其转换为 void-pointer?

error message:

【问题讨论】:

  • 确切的错误信息是什么?
  • 总是一个好的开始实际上是阅读错误消息(并添加你的问题!)。
  • 我认为你只需要将 &var 转换为 void*
  • printf("%p\n", (void*)&var);
  • 请提供确切的错误消息,而不是对其的解释。

标签: c linux pointers


【解决方案1】:

%p 说明符需要一个void*,而你给它一个int*。所以就投吧:

printf("%p\n", (void*)&var);

如果这是一个普通函数,从 int * 到 void * 的转换将是自动的,不会产生警告。但是由于 printf() 是一个可变参数函数,因此转换必须是显式的。可变参数函数的参数不需要进行类型检查。但是,一些编译器知道标准函数(包括 printf())是如何工作的,并且会在错误使用时发出警告。

【讨论】:

  • 所以在 Linux 中,%p 说明符需要一个 void 指针,但在 Windows 中不需要?
  • @jforberg 这是一个可变参数函数,除了标准促销之外,它们不进行自动转换。
  • 请注意:(通常)printf 无法知道格式字符串之外的参数类型。如果你说"%p"printf 会假设你给了它一个空指针。只有编译器/解释器才能注意到这种差异。 GCC 和 Clang 在这方面比微软的 C 编译器更好,但这取决于编译器标志。
  • %x 不适用于指针值。它可能会“工作”,但如果指针和 int 的大小不同,则不会。
  • @Marieke:如果printf 语句中的转换说明符和参数类型不匹配,则行为是未定义。编译器不需要为未定义的行为发出诊断。此外,未定义行为的一种可能表现是您的代码按预期工作。这里唯一的道理是,您需要 a) 尽可能提高警告级别,无论您使用什么编译器,b) 了解哪种类型与哪种格式说明符搭配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
相关资源
最近更新 更多