【问题标题】:Why does C++ always display a Hexadecimal memory address and not just an integer?为什么 C++ 总是显示十六进制内存地址而不仅仅是整数?
【发布时间】:2020-10-16 20:06:08
【问题描述】:

我想知道为什么在 c 中打印变量的地址会得到类似于 823759733 的输出 同时,在 C++ 中做同样的事情显示 0x7ff6474009c?? 这是'cout'的工作,将地址格式化为十六进制吗?还是隐藏变量内存地址以显示一些任意地址来封装它? 我知道 C++ 中的虚拟内存中的一切都在发生,这对 C 来说是一样的吗?

例子-

int a=10;
int* ptr=&a;
printf("%d", ptr);

它应该打印一个整数。

用 c++ 编写的相同代码 和

cout<<ptr

它显示一个十六进制(我想知道为什么?)

【问题讨论】:

  • 如何在 C 中打印地址?看起来你在 C 代码中做错了什么。您是否启用了编译器警告?你的编译器应该告诉你你做错了什么。
  • 请人分析你的代码时,请出示你的代码
  • 引用(地址)在十进制形式中是毫无意义的。很难找到十进制地址的用途
  • 在 C 中,printf("%d", ptr);未定义的行为,因为打印说明符与参数不匹配。使用printf("%p", (void*) ptr);

标签: c++ c memory encapsulation addressing


【解决方案1】:

我猜你正在用 C 打印这样的东西:

void* p;
...
printf("%d", p);

%d 说明符打印为整数,输出为 base-10。

我猜在 C++ 中你正在做类似的事情:

void* p;
...
std::cout << p;

这里,由于 C++ 强类型,cout 知道 p 是指针,而不是整数。指针默认以 16 进制输出。

【讨论】:

  • "指针默认以 16 进制输出。" --> 我怀疑十六进制输出很常见,不是默认的。
【解决方案2】:

C 中 printf 的格式说明符的作用由 C++ 中 operator&lt;&lt; 的不同重载承担。在 C 代码中,您没有显示明确要求打印十进制表示,当您调用 std::cout::operator&lt;&lt; 时,选择了适当的重载。将内存地址打印为十六进制是常见的约定。如果您愿意,可以在 C 和 C++ 中将它们打印为小数。

【讨论】:

    【解决方案3】:

    这就是问题

    printf("%d", ptr);
    

    结果可能完全错误。在我的系统上,int 有 4 个字节,指针有 8 个字节。当我尝试将指针打印为十进制 (%d) 时,它会导致未定义的行为。在我的示例中,我将未定义的行为视为溢出。您应该使用%p 来打印指针

    printf("%p", ptr);
    

    您的编译器应该向您显示警告,例如

    warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' [-Wformat=]
    

    一个例子

    #include <stdio.h>
    
    int main() {
        int a;
        int* ptr = &a;
        printf("%d", ptr);
    }
    

    编译输出:

    prog.c: In function 'main':
    prog.c:5:14: warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *' [-Wformat=]
        5 |     printf("%d", ptr);
          |             ~^   ~~~
          |              |   |
          |              int int *
          |             %ls
    

    运行时输出:

    -204940372
    

    【讨论】:

    • 感谢您的回答,完全理解格式说明符,但是当您说,您的系统有 4 个字节用于 int,8 个字节用于指针,这可能会导致一些溢出问题。但是,如果我将指针类型设置为 int 指针,则指针现在应该包含 4 个字节而不是 8 个字节,对吗?它不应该引起任何问题吗?抱歉说的有点深入,我一直很好奇学习
    • @NishadSanilya 不,所有指针的大小都相同。指针在 32 位系统上具有 4 个字节,在 64 位系统上具有 8 个字节。 int 指针的大小与 double 指针或 void 指针相同。
    • "所有指针的大小相同" --> 不完全。然而这里的重点是int 的大小和int * 的大小可以不同。 “指针在 32 位系统上有 4 个字节,在 64 位系统上有 8 个字节”——> 也不完全是。尽管您说的很普遍,但系统的 N 位通常指的是本机整数大小,而不是指针大小。指针大小和本机整数大小可以不同。本机整数可能与 int 不同。
    • @chux-ReinstateMonica 我了解到 N 位描述了内存地址。 32 位系统的地址为 32 位,因此最多可使用 4 GB 内存。 64 位系统使用 64 位地址,可以使用更多内存。
    • 请注意,即使参数的大小匹配,使用错误的格式说明符在技术上也是 UB。
    猜你喜欢
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    相关资源
    最近更新 更多