判断一个变量是有符号数还是无符号数(转)

《C专家编程》最后一段讲面试,说是微软曾经有一道面试题:写一段代码,确定一个变量是有符号数还是无符号数?
首先,任何试图用函数来解决此问题的方法都不好使,因为函数有类型检查,所以只能用宏啦。
书中给出了一个宏:#define ISUNSIGNED(a) (a>=0 && ~a>=0)
它只能用在K&R C里,在ANSI C里就不行了。当这个宏被用在int/unsigned int时,没有任何问题。但是在判断unsigned char和unsigned short上就会出错。

此宏在int/unsigned int好使的原因是宏中的a的精度始终不会发生变化,而当a是char和short时,表达式~a>=0会先将a变为int然后再取反(因为常量0的类型为int),而int当然是有符号的,对它取反就有可能小于0。
要修正这个错误其实很简单,那就是要保证先进行取反操作再做精度提升,我们可以采用对a取反a=~a(这样就不会有类型提升),判断结束后再取一次反,恢复a的值。

好了,上测试代码:

#define IS_SIGNED_NUM(a)      (a < 0 ? true :( a =~a,a < 0 ? (a=~a,true):(a=~a,false)))
#define IS_UNSIGNED_NUM(a)  (a >=0 && (a=~a,a >=0 ? (a=~a,true):(a=~a,false)))

void testSignedNum()
{
    int a1 = 0xffff0001;
    int a2 = 0x0fff0001;
    int a =0;
    unsigned int b1 = 0xffff0001;
    unsigned int b2 = 0xffff0001;
    unsigned int b =0;
    assert(IS_SIGNED_NUM(a1) == true && IS_UNSIGNED_NUM(a1) == false);
    assert(IS_SIGNED_NUM(a2) == true && IS_UNSIGNED_NUM(a2) == false);
    assert(IS_SIGNED_NUM(a) == true && IS_UNSIGNED_NUM(a) == false);
    assert(IS_SIGNED_NUM(b1) == false && IS_UNSIGNED_NUM(b1) == true);
    assert(IS_SIGNED_NUM(b2) == false && IS_UNSIGNED_NUM(b2) == true);
    assert(IS_SIGNED_NUM(b) == false && IS_UNSIGNED_NUM(b) == true);
    
    char a3 = -1;
    char a4 = 0x0f;
    char a5 = 0;
    unsigned char b3 = 0xff;
    unsigned char b4 = 0x0f;
    unsigned char b5 = 0;
    assert(IS_SIGNED_NUM(a3) == true && IS_UNSIGNED_NUM(a3) == false);
    assert(IS_SIGNED_NUM(a4) == true && IS_UNSIGNED_NUM(a4) == false);
    assert(IS_SIGNED_NUM(a5) == true && IS_UNSIGNED_NUM(a5) == false);
    assert(IS_SIGNED_NUM(b3) == false && IS_UNSIGNED_NUM(b3) == true);
    assert(IS_SIGNED_NUM(b4) == false && IS_UNSIGNED_NUM(b4) == true);
    assert(IS_SIGNED_NUM(b5) == false && IS_UNSIGNED_NUM(b5) == true);
}


---------------------------------------------------------------
参考文献:《C专家编程》

原文地址:https://www.cnblogs.com/coversky/p/7351289.html