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


    《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专家编程》

  • 相关阅读:
    JDK1.8源码之HashMap(一)——实现原理、查找及遍历
    JDK1.8源码之ArrayList
    03、Swagger2和Springmvc整合详细记录(爬坑记录)
    02、Java的lambda表达式和JavaScript的箭头函数
    Java-IO流之输入输出流基础示例
    JDBC API 事务的实践
    JDBC API 可滚动可编辑的结果集
    Java虚拟机----垃圾回收与内存分配
    Java数据库连接与查询
    Java虚拟机-对象的创建和访问
  • 原文地址:https://www.cnblogs.com/coversky/p/7351289.html
Copyright © 2020-2023  润新知