为什么这个程序输出64?

5
我在进行C编程的在线测试时发现了这个程序,我已经尝试过了,但是我无法弄清楚为什么该程序的输出结果是64。
有人能解释一下背后的概念吗?
#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int a = 320;
    char *ptr;
    ptr = (char *)&a;
    printf("%d",*ptr);
    return 0;
}

输出:

64

谢谢。


1
提示:char的大小是多少?它能适合吗? - nayana
1
320的十六进制表示为0x1400x40的十进制表示为64。还有其他问题吗? - Jabberwocky
3
@MichaelWalz..哦,这样他就学不到什么了:D - nayana
2
因为0x40是十进制的64.... ;) 顺便说一句,这完全取决于字节序... - LPs
2
@otopolsky 这可能会让他开始思考并自己找到答案。 - Jabberwocky
显示剩余2条评论
5个回答

11
一个char *只指向一个字节。假设你的系统上一个字节是8位,数字320占用了2个字节。其中较低的字节是64,较高的字节是1,因为320 = 256 * 1 + 64。这就是为什么在你的电脑上会得到64(它是一个小端的计算机)。
但是请注意,在其他平台上,即所谓的大端平台上,结果可能是最高16位/2个字节值的最重要字节1或者0(一个比16位/2个字节更大的值的最高有效字节)。
请注意,所有这些都假设该平台有8位字节。如果它有10位字节,你将会得到另一个不同的结果。幸运的是,现在大多数计算机都有8位字节。

5

如果你不了解以下知识,将无法理解本文:

  1. 十六进制/二进制表示法
  2. CPU 字节序

请将十进制数 320 转换为十六进制。将其拆分成字节。假设 int 占用 4 个字节,你应该能够确定哪些部分属于哪些字节。

之后,请考虑所给 CPU 的 字节序 并按照该顺序排列字节(最高位字节优先或最低位字节优先)。

代码访问整数的最低地址处分配的字节。其内容取决于 CPU 字节序。你可能会得到十六进制 0x40 或十六进制 0x00。


注意:不应使用 char 进行此类操作,因为其具有实现定义的符号。如果数据字节包含大于 0x7F 的值,则可能会出现非常奇怪的错误,这些错误在多个编译器中表现不一致。进行任何形式的位/字节操作时,请始终使用 uint8_t*

你可以通过将 320 替换为 384 来暴露此错误。在您的小端系统上,可能会打印出 -128 或 128,您将在不同的编译器上获得不同的结果。


代码不访问最高有效字节,而是访问存储在内存中地址最小的四个字节中的一个 - 这可以是最高有效字节或最低有效字节。 - Aconcagua
@Aconcagua 确实,已经修复。 - Lundin

0

Int 是四个字节的数据字节,而 char 是一个字节的数据字节,char 指针可以一次保留一个字节的地址。二进制值为 320 的十六进制表示为 00000000 00000000 00000001 01000000。因此,char pointer ptr 只指向第一个字节。 *ptr 即第一个字节的内容是 01000000,它的十进制值是 64


0

@Lundin所说的已经足够了。顺便说一下,一些基础知识可能会有帮助。320 = 0x0140。一个int等于4个char。因此,当打印第一个字节时,由于CPU的字节序,它输出0x40 = 64。


这在技术上是不正确的;在如今最常见的处理器上,int只有四个字节。但特别是微控制器和DSP可能不同,有的 int = 16位 = 2个字节,还有的 int = 16位 = 1个字节。 - Aconcagua
谢谢您的建议!我的错,我只是想写一些易于理解的东西。 - Z.Ding

0

ptr是a的char指针。因此*ptr将给出a的char值。char仅占用1个字节,因此在255之后它会重复其值。也就是说,256变为0,257变为1,依此类推。因此320变为64。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接