关于类型提升问题

下面一个小程序,演示了c语言中类型提升带来的一个小问题。

 

//test.c

#include <stdio.h>

int array[]={23,34,45,56,67,78};
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))

int main()
{
    int d=-1,
        x=3;
    if(d<=TOTAL_ELEMENTS-2)
      x=array[d+1];
    printf("the value of x is %d/n",x);
    return 0;
}

 

编译运行,结果如下:

alei@alei-desktop:~$ gcc test.c -o test
alei@alei-desktop:~$ ./test
the value of x is 3

 

为什么结果是3而不是23呢?

 

先看ANSI C手册中的关于寻常算术转换的规定。

 

首先,如果一个操作书的类型是long double,那么另一个操作数也被转化为long double。其次,如果一个操作数的类型是double,那么另一个操作数也被转换为double。再次,如果其中一个操作数的类型是float,那么另一个操作数也被转换为float。否则,两个操作数进行整型提升,执行下面的规则:

如果其中一个操作数是unsigned long int,那么另一个操作数也被转换为unsigned long int。其次,如果其中一个操作数是long int, 而另一个操作数的类型是unsigned int ,如果long int 能够完整表示unsigned int 的所有值,那么unsigned int类型操作数被转换为long int,如果long int类型不能完整的表示unsigned int 的所有值,那么两个操作数都被转换为unsigned long int。再次,如果其中一个操作数的类型是long int,那么另一个操作数转换为long int。再再次,如果其中一个操作数的类型是unsigned int ,那么另一个操作数被转换为unsigned int。如果所有以上的情况都不属于,那么两个操作数都为int。

 

简言之,当进行算术运算时,操作数的类型如果不同,就会发生转换。数据类型一般朝着浮点精度更高,长度更长的防线转换,整型数如果转换为signed 不会丢失信息,就转换为signed,否则转换为unsigned。

 

再看上面的程序。

TOTAL_ELEMENTS是unsigned int类型的(因为sizeof()的返回类型是无符号整数)。if在signed int和unsigned int之间测试相等性,所以d被提升为unsigned int 类型的。只是表达式的值为假。要修正这个问题,可以进行强制类型转换:

if(d<=(int)TOTAL_ELEMENTS-2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值