使用C中的char减去十六进制值

时间:2017-03-09 04:04:33

标签: c hex

我很难理解以下程序的输出。

int main(){
    char y = 0x02;
    y = y-0x03;
    printf("0x%x  %d",y,sizeof(y));
    return 0;
}

我得到的输出是

  

0xffffffff 1

我知道到目前为止,如果我添加两个十六进制值,则会添加其二进制值。使用借用概念进行减法也是如此(如果我错了,请纠正我)

  

实例
  111 - 001 = 110(二进制)   110 - 001 = 101(使用第一个操作数中第二个LSB的进位)

如果值为overflow char,则在添加两个十六进制值时,它们基本上是mod 256.即如果我将程序编写为

int main(){
   char y = 0x03;
   y = y+0xff;
   printf("0x%x",y);
   return 0;
}

我会得到

的输出
  

0X2

但是在减法的情况下,如果我运行第一个程序,预期的输出应该是

  

0xff的

所以我的问题是因为上面的减法应该是

  

00000010 - 00000011

二进制,借款来自哪里? 为什么我得到这个

  

0xffffffff的

奇怪的输出?

4 个答案:

答案 0 :(得分:4)

答案的两个部分:

  1. set iterationTimes=4 for /l %%i in (0,1,%iterationTimes%) do ( call matlab -nodesktop -nosplash -r "loop=%%i%%;"%stitchFile% call %IJPath% -macro %JythonPath% %%arg%% ) 的参数 - 或任何可变函数的printf()部分 - 都会进行默认促销。对于类型...,这意味着该值将转换为char

  2. 您已在计算机上签名int,因此该值已进行符号扩展。也就是说,char中存储的0xFF会转换为y,这就是您看到的内容。

  3. 如果您有一个支持足够现代的printf()规范的库,您可以使用:

    0xFFFFFFFF

    printf("%hhx %zu\n", y, sizeof(y)); 说'转换为hhx,然后打印'。 char长度修饰符z是打印%zu值的正确格式之一,例如size_t返回的值。如果做不到这一点,请使用sizeof()y & 0xFF代替普通(unsigned char)y作为y的参数。

答案 1 :(得分:1)

  

我知道到目前为止,如果我添加两个十六进制值,它们就是   转换为二进制,然后添加。这样做也是如此   使用借用概念减法(如果我是,请纠正我   错)

你错了。十六进制,十进制,八进制等是表示数字的形式。在其下方始终是一系列位。

由于%x格式规范,您获得了“奇怪”的输出。您的1字节char值将转换为unsigned int。

答案 2 :(得分:0)

今天大多数计算机系统使用two's complement来表示负数。在该系统中,负数表示为比它们absolute value小1的按位反转。以这种方式表示的负数是1 - 1 = 0的按位反转,其所有位都打开。

另外,请注意C中的带符号溢出为undefined behavior,因此除非您使用像gcc' s -fwrapv这样的编译器选项,否则上面的mod 256示例不会得到保证工作。

答案 3 :(得分:0)

这是因为一个名为整数促销的棘手概念。

基本上,您的单字节字符被转换为4字节整数来处理您的操作。所以:

  

0x02 - 0x03

变为:

  

0x00000002 - 0x00000003

碰巧是0xffffffff(因为那是-1如何将-1表示为整数)。