无符号数运算问题——C语言隐式类型转换

要排序几个存了IP的文件,使用ntohl(inet_addr(ip));转成了无符号数,然后使用qsort函数来排序,但发现老是有部分数据没排正确。

经仔细检查,比较函数如下:

typedef struct
{
        unsigned long ipstart;
        unsigned long ipstop;
        unsigned short carrier; /*文件下标*/
}IP_RANGE;

static int cmp_iprange(const void *a,const void *b)
{
        IP_RANGE * A = (IP_RANGE*)a;
        IP_RANGE * B = (IP_RANGE*)b;

        return A->ipstart - B->ipstart;

}

这里面使用了无符号数的相减,这样相减的结果比较大时,转化为有符号数返回,会变为负数,这就是错误的根源,代码修改如下:

static int cmp_iprange(const void *a,const void *b)
{
        IP_RANGE * A = (IP_RANGE*)a;
        IP_RANGE * B = (IP_RANGE*)b;
        long long int difference = (long long int)((unsigned long long)(A->ipstart)) - (long long int)((unsigned long long)(B->ipstart));
        
        if(difference > 0)
            return 1;
        else if(0 == difference)
            return 0;
        else
            return -1;
}

1、隐式转换
    C在以下四种情况下会进行隐式转换:
       1、算术运算式中,低类型能够转换为高类型。
       2、赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他。
       3、函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。
       4、函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。

2、算数运算的隐式转换
    算数运算中,首先有如下类型转换规则:
       1、字符必须先转换为整数(C语言规定字符类型数据和整型数据之间可以通用) 。
       2、short型转换为int型(同属于整型) 。
       3、float型数据在运算时一律转换为双精度(double)型,以提高运算精度(同属于实型) 。
    其次,有下面的规则。
    当不同类型的数据进行操作时,应当首先将其转换成相同的数据类型,然后进行操作,转换规则是由低级向高级转换。转换规则如下图所示:


    上图的简化图如下所示:


3、算数运算示例
    执行:x = 100 + 'a' + 1.5 * u + f / 'b' - s * 3.1415926
    其中,uunsigned型,ffloat型,sshort型,xfloat型。式中右面表达式按如下步骤处理:
       1、首先将'a''b's换成int,将1.5f转换为double型。
       2、计算100+'a',因'a'已转换为int型,于是此运算结果为197
       3、计算1.5*u,由于1.5已转换为doubleuunsigned型,于是首先u转换为double,然后进行运算,运算结果为double
       4、计算197+1.5 * u,先将197转换为double(如197.0000),其结果为double
       5、计算f/ 'b'f已转换为double'b'已转换为int,于是先将'b'再转换为double,其结果为double
       6、计算(197+1.5 * u+f / 'b',者均为double,于是结果也为double
       7、计算s * 3.1415926,先将sint转换为double,然后进行运算,其结果为double
       8、最后与前面得的结果相减,结果为double
       9、最后将表达式的结果转换为float并赋给x

这样一个题,据说是微软面试题:

unsigned int i=3;
cout<<i * -1;
问结果是多少。
 
第一反应:-3。不过结果似乎不是这样的,写了个程序,运行了一下,发现是:4294967293。
用以上隐式类型转换解答之。

http://blog.csdn.net/miaouu/article/details/5213042


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值