2016-02-19 53 views
1
char xtime(char m) 
{ 
    //calculates the m value by checking m,if m is less than 0x80 hexadecimal 
    // then it is left shifted else it is left shifted and xor'ed with 0x1b. 
    if(m<0x80) 
    { 
     m<<=1; 
    } else { 
     m=(((m)<<1)^0x1b); 
    } 

    printf("%#01x ",m&0xff); 
    return m; 
} 

如果m = 0x80(这是0x1b),此代码不显示预期的输出,它以十六进制的形式给出输出0。具有相同逻辑的两段代码。一个给出预期的输出,另一个不给出

#define xtime(a) (((a)<0x80)?(a)<<1:(((a)<<1)^0x1b)) 

此代码的工作原理,并给出了预期的结果。

请问功能代码出了什么问题,以及第二个代码是如何解决的。

+4

'char'可能会根据环境进行签名,如果'char'是8位长并且被签名,则'0x80'可能不适合它。如果int类型的值被传递,第二个代码应该可以工作,因为int可以保存至少32767的整数。 – MikeCAT

+3

对于字符只使用'char'是个好主意。如果您需要一个小整数类型,请使用'signed char'或'unsigned char'。就你而言,后者似乎是你需要的。 –

+0

对于C++,您应该考虑'inline'而不是宏。 – crashmstr

回答

2

假设您的环境中

  • char签订
  • char是8位长
  • 二进制补码是用来表达负整数
  • 如果有符号整数转换为不能存储原始值,高位被简单扔掉

0x80太大而无法存储到char变量中,并且它将被解释为-128-128小于0x80,所以执行m <<= 1;。 该转变的结果是-256,其二进制表示是0xffffff00,而m将得到最后8位,即0。这就是你得到的。

如果0x80传递给a,因为计算将使用int完成宏将工作,int可容纳高达整数至少32767

+0

Plus有符号整型溢出是未定义的行为。 – YSC

+0

@YSC我认为'm'作为操作数将通过整数升级转换为'int',因为另一个操作数'1'是'int',并且转换为小型有符号整数是由实现定义的(N1256 6.3.1.3)。我错了吗? – MikeCAT

+0

这更糟糕:事实上'因为'm'是'signed char',所以'if(m <0x80)'总是为真。 – YSC

相关问题