C语言自动转换规则

今天遇到一个无符号数跟有符号数相加的问题,居然搞错了,虽然是很低级的东东,但是长时间没用到还是会忘记的...

平时遇到的都是什么float自动转换成double,int自动转换成float,int8自动转换成int32之类的....

好吧,重新记下来吧,运算符左右类型不匹配时,会对其中一个做自动类型转换:

int     ---> long

int8,char,short   ----> int

int     ----> uint  (今天在这里马失前蹄)

float  ----> double


下面是从这个博客摘录的,相对其他人写的更科学和准确一些:(好吧,我承认第五点“函数原型”那里我不是很清楚他神马意思,先这样吧)


    1. 在表达式中,char 和 short 类型的值,无论有符号还是无符号,都会自动转换成 int 或者 unsignedint(如果 short 的大小和 int 一样,unsigned short 的表示范围就大于 int,在这种情况下,unsignedshort 被转换成 unsigned int)。因为它们被转换成表示范围更大的类型,故而把这种转换称为“升级(promotion)”。


    2. 按照从高到低的顺序给各种数据类型分等级,依次为:long double, double, float, unsignedlong long, long long, unsigned long, long, unsigned int 和int。这里有一个小小的例外,如果 long 和 int 大小相同,则 unsigned int 的等级应位于 long 之上。char 和short 并没有出现于这个等级列表,是因为它们应该已经被升级成了 int 或者 unsigned int。


    3. 在任何涉及两种数据类型的操作中,它们之间等级较低的类型会被转换成等级较高的类型。


    4. 在赋值语句中,= 右边的值在赋予 =左边的变量之前,首先要将右边的值的数据类型转换成左边变量的类型。也就是说,左边变量是什么数据类型,右边的值就要转换成什么数据类型的值。这个过程可能导致右边的值的类型升级,也可能导致其类型降级(demotion)。所谓“降级”,是指等级较高的类型被转换成等级较低的类型。


    5. 作为参数传递给函数时,char 和 short 会被转换成 int,float 会被转换成 double。使用函数原型可以避免这种自动升级。


2014.6.19 坑死人不偿命. 谨记上述第一条规则.

[dongsong@localhost c++-study]$ cat conv.c 
#include<stdio.h>
#include<stdint.h>

int main(int argc, char** argv)
{
    int16_t a = 4;
    uint16_t b = 0xEFFF;
    printf("%d-%d=%d\n", a, b, a-b);
    printf("%d-%d=%u\n", a, b, a-b);
    printf("%d-%d=%hu\n", a, b, a-b);
    printf("%hd-%hd=%hd\n", a, b, a-b);
}

[dongsong@localhost c++-study]$ gcc -o conv conv.c ; ./conv
4-61439=-61435
4-61439=4294905861
4-61439=4101
4--4097=4101

32bit->16bit,数据被截断
不做强制转换(自动转换)的情况下,int16 - uint16 -> uint32,这里在意料之中;把uint32赋值给int16数据被截断,结果可能为正也可能为负,这里导致我今天遇到的BUG
    printf("%d, %hd %hu\n", 0x80008001, 0x80008001, 0x80008001);                    -2147450879, -32767 32769
    printf("%d, %hd %hu\n", 0x80000001, 0x80000001, 0x80000001);                    -2147483647, 1 1
    printf("%8x %hd %hu\n", (int32_t)-1, (int32_t)-1, (int32_t)-1);                    ffffffff -1 65535

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值