指向整数的char指针可以测试字节顺序,对吗?

时间:2017-10-12 02:57:18

标签: c

我正在浏览2braces.com上的C test,并对第一个问题感到困惑。

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

答案说它的输出是-126。但IMO,它取决于:little-endian env中的输出应为-126,big endian env中的输出应为0。我是对的吗?

如果代码想要测试char溢出问题,可能会更加严格:

#include<stdio.h>
int main(){
    int a = 130;
    char c = a;
    printf("%d ",c);
    return 0;
}

BTW,我看到很多使用char和int联合来测试字节序的示例代码,将char *用于整数是不是更简单?

我想验证我的猜测,但我没有一个大端环境。

2 个答案:

答案 0 :(得分:2)

  

但IMO,它取决于:little-endian env中的输出应为-126,   大端环境中的0和0我是对的吗?

排序。

如果同时检查-126和130,vs 0,(char可以是有符号或无符号),现在大约有99%的设备,这将有效。但严格来说,这两种价值都无法保证。原因包括:

  • 可变尺寸。例如。 char可能与int具有相同的大小(和endianess和...),那么它的值将是130。
  • 不使用2补码的系统。 (然后130不是-126)
  • 奇怪的事情,如带有陷阱值的变量,未使用的位等等。
  • ...
  顺便说一句,我看到很多使用char和int结合的示例代码   测试字节顺序

虽然我需要查看它,但是不能保证char将位于int的第一个字节。如果是这样,这是另一个需要考虑的问题。

答案 1 :(得分:1)

这段代码:

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

没有未定义或未指定的行为,除了130以(隐式签名)char访问时会以某种方式恰好成为陷阱值的相当模糊的可能性,但有很多可能结果:

  1. 在小端平台上输出-126,其中char已签名且表示为2的补码
  2. 输出是架构上的其他内容,它使用符号和数字或负数的补码。
  3. 在小端平台上输出130,其中char是无符号的。
  4. 在big-endian平台上输出0,其中char已签名或未签名
  5. 输出可能是中端平台上的0。如果-126由一个,两个字节表示,则可以是130int或其他内容
  6. sizeof(int)为1的平台。可能所有可寻址的原始值都有sizeof 1 - 这些根本就没有任何字节序
  7. 其中一些是模糊的,但小端和大端计算机确实存在,并且在ARM处理器上char默认为unsigned

    为了不使事情复杂化,应使用unsigned类型完成endianess检测。

    如果您使用固定大小类型

    ,则union测试有效
    union {
        uint32_t the_int;
        uint8_t fragments[4];
    }
    

    您不会在运行时测试计算机的字节顺序!代码必须只为一个和一个字节序编译,所以你无论如何都可以在编译时完成它。需要在运行时完成的实际字节顺序检查仅涉及从文件或进程间通信中读取的数据结构。