最新消息:把Logo换了一下,虽然丑了点,但至少完全是自己的设计

C语言中数值类型隐式转换规则

C 宇托 953浏览 暂无评论

C语言中,有数据类型隐式转换的处理,具体表现为以下三个方面。

  • 整形数值定义时的隐式转换
  • 未指定类型的函数调用时的隐式转换
  • 运算时的隐式转换

整形数值定义时的隐式转换

在整形定义时,如果未明确指定整形的后缀(参考:C语言的数值类型及其定义与输出 ),就会发生隐式转换。其规则如下:

  • 定义的数值常量在int的值范围(-2147483648 ~ 2147483647)内,默认为int。
  • 定义的数值常量在int的值范围外,但在unsigned int的值范围(2147483648 ~ 4294967295)内,隐式转换为unsigned int;
  • 定义的数值常量在上面两者以外,并在long long的范围内(-9223372036854775808 ~ 9223372036854775807),隐式转换为long long。
  • 定义的数值常量在long long的值范围外,但在unsigned long long的值范围(9223372036854775808 ~ 18446744073709551615)内,隐式转换为unsigned long long。
  • 上面四者以外隐式转换为long long。

上面的转换基本上在程序里不需要太关心,因为数值常量在赋值到变量时,也会自动转换。

未指定类型的函数调用时的隐式转换

在一些未指定参数类型(比如用...定义的参数)的函数调用时,做实参的变量会经过隐式转换再传给函数的参数变量。比如printf()

其隐式转换规则如下:

  • 对于char,short这两个整形类型来说(不管是signed还是unsigned),都转化为int.
  • 对于float这个浮点型来说,转化为double。

运算时的隐式转换

在C语言中,运算是不会改变类型的,类型的改变是的运算之前。比如说,int型和int型的运算(包括数学运算,位运算),其结果都是int型。
比如下面的代码uValue和iValue经过位运算,其结果的类型不变:

C
#include <stdio.h>

int main(int argc, char const *argv[]) {
    unsigned int uValue = 0x7FFFFFFF;
    int iValue = 0x7FFFFFFF;

    printf("sizeof(uValue << 1) = %d\n", sizeof(uValue << 1));
    printf("uValue << 1 = %lld\n", (long long)(uValue << 1));

    printf("sizeof(iValue << 1) = %d\n", sizeof(iValue << 1));
    printf("iValue << 1 = %lld\n", (long long)(iValue << 1));

    return 0;
}

在运算中,如果有强制转换,要先进行强制转换,然后再进行隐式转换。

对于运算前的隐式转换,按顺序有以下几个规则:

  • 如果运算的两个变量有一个是long double型的,把非long double型的变量值隐式转换为long double型,然后计算。
    比如:12 + 45.6l,因为45.6l是long double型,运算前会把12转化为long double型,再计算

  • 如果运算的两个变量有一个是double型的,把非double型的变量值隐式转换为double型,然后计算。
    比如:12l + 45.6,因为45.6是double型,运算前会把12转化为double型,再计算

  • 如果运算的两个变量有一个是float型的,把非double型的变量值隐式转换为float型,然后计算。
    比如:12ll + 45.6f,因为45.6f是float型,运算前会把12转化为float型,再计算

  • 如果两者都是整数型,则按以下顺序进行隐式转换

    • 对于char,short这两个整形类型来说(不管是signed还是unsigned),都转化为int.
    • 以int, unsigned int,long long,unsigned long long的优先度,把优先度低的转化为优先度高的。

这里要注意的是,一个表达式里可能的很多计算,隐式转换是在每一个计算之前做,而不是所有计算之前做。
比如1 / 3 * 3.0这个表达式的值是多少呢?根据计算优先级,先计算1 / 3,两个运算值都是整形,所以其结果为整形,结果为0。然后再计算0 * 3.0,3.0是double型,所以要把0转化为double型再计算,计算结果为0.0。呵呵,是不是和预想的不一样。要想得到结果1.0的话,表达式应该写成1 / 3.0 * 3.0或者1 / (double)3 * 3.0

测试代码:

C
#include <stdio.h>

int main(int argc, char const *argv[]) {

    printf("1 / 3 * 3.0 = %f\n", 1 / 3 * 3.0);
    printf("1 / 3.0 * 3.0 = %f\n", 1 / 3.0 * 3.0);
    printf("1 / (double)3 * 3.0 = %f\n", 1 / (double)3 * 3.0);

    return 0;
}

转载请注明:宇托的狗窝 » C语言中数值类型隐式转换规则

发表我的评论
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址