c中的bitshifting chars

rhl*_*lee 4 c types bitmask bit-shift

我试图通过所有小端系统以可移植的方式将int中的字节转换为一系列字符.

我有以下代码:

#include <stdio.h>

int
main()
{
  int i = 0xabcdef12;
  printf("i: %x\n", i);
  char a, b, c, d;
  a = (i >> 000) & 0xFF;
  b = (i >> 010) & 0xFF;
  c = (i >> 020) & 0xFF;
  d = (i >> 030) & 0xFF;
  printf("a b c d: %x %x %x %x\n", a , b, c, d);
  if(a == 0x12)
    printf("a is 0x12\n");
  if(b == 0xef)
    printf("b is 0xef\n");
  if(c == 0xcd)
    printf("c is 0xcd\n");
  if(d == 0xab)
    printf("d is 0xab\n");
  if(a == 0xffffff12)
    printf("a is 0x12\n");
  if(b == 0xffffffef)
    printf("b is 0xffffffef\n");
  if(c == 0xffffffcd)
    printf("c is 0xffffffcd\n");
  if(d == 0xffffffab)
    printf("d is 0xffffffab\n");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用-Wall时,这段代码编译时没有任何警告.

运行时,这给出:

i: abcdef12
a b c d: 12 ffffffef ffffffcd ffffffab
a is 0x12
b is 0xffffffef
c is 0xffffffcd
d is 0xffffffab
Run Code Online (Sandbox Code Playgroud)

这是一些gcc打印:

Breakpoint 1, main () at test.c:14
14    if(a == 0x12)
(gdb) p/x a
$1 = 0x12
(gdb) p/x b
$2 = 0xef
(gdb) p/x c
$3 = 0xcd
(gdb) p/x d
$4 = 0xab
Run Code Online (Sandbox Code Playgroud)

我很确定我做错了什么.如果您能回答以下几个问题,这将真正帮助我了解正在发生的事情:

  • char如何具有大于0xff的值?
  • 什么不是& 0xffbitmasks工作?
  • 为什么gdb会报告正确的值?

如果任何人有一个可靠的(系统独立的,但是endianess并不重要)从int到char []的方式,这将是伟大的.

Mys*_*ial 5

这是一个快速解决方案.

更改:

char a, b, c, d;
Run Code Online (Sandbox Code Playgroud)

unsigned char a, b, c, d;
Run Code Online (Sandbox Code Playgroud)

原因是char在您的系统上签名.当你通过了,a,b,c,dprintf(),他们得到晋升int.它们是符号扩展的.这就是你获得所有领先者ff的原因.

GDB正在报告正确的值,因为它正在chars直接读取.(因此没有整数提升)