C/C++ 关于类型的提升和转换 - 孙桨

时间:2024-03-18 07:20:42

C/C++ 关于类型的提升和转换

2015-06-05 18:37  孙桨  阅读(2478)  评论(0编辑  收藏  举报

 

C语言允许混合数据类型运算。不过其中各种数据类型将全部转换为其中字节最高的数据类型来进行运算。编译器都可以自动进行数据类型转换。所以表达式所得值的类型为其中字节最高的数据类型。自动数据类型转换可以进行所有类型之间的转换。

 

如果赋值表达式中赋值运算符两边的数据类型不同,编译器也会进行自动数据类型转换。右边表达式的值的数据类型为右边表达式中字节最高的数据类型(常量和函数调用返回值也有数据类型,运算时也可以被自动数据类型转),编译器将表达式所得值的数据类型自动数据类型转换为左边变量的类型(赋值运算时特殊的运算,编译器不会说那边数据类型高转换为哪种,而是不管怎样,无条件自动转换为左边变量的类型)。如果左边数据类型,这将不会丢失精度。右边数据类型的高于左边的,将丢失精度。

 

指派类型运算符(type)将某种数据类型变量、常量和函数调用返回值,强制转换为自己指派的数据类型。进行程序员现在要用的运算符。不是说系统的自动类型转换不能完成者两种类型的转换(可能能自动转换成这种类型,也可能转换成其他类型。这是就可以指派类型给它们,明确数据类型)。而是现在程序员现在需要某种数据类型,指派特定类型给它们,来完成自己的目标。

 

 

 

 

 

 

 

 

 

一、类型的提升

   把charunsigned charshortunsigned short转换成int类型称为类型提升(promotion)。

1. 如果short的字节长度小于int的字节长度

   char转换成 int

   unsigned char转换成 int

   short转换成 int

   unsigned short转换成 int

2. 如果short的字节长度等于int的字节长度

   char转换成 int

   unsigned char转换成 int

   short转换成 int

   unsigned short转换成 unsigned int

二、类型的转换

    long doubledoublefloatunsigned long longlong longunsigned longlongunsigned intint之间的转换称为类型转换

1. 如果int的字节长度小于long的字节长度

   类型等级由高到低依次为:long doubledoublefloat、 unsigned long longlong longunsigned longlongunsigned intint

2. 如果int的字节长度等于long的字节长度

   类型等级由高到低依次为:long doubledoublefloatunsigned long longlong longunsigned longunsigned intlongint

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

 

 

 

 

 

1 若参与运算量的类型不同,则先转换成同一类型,然后进行运算。

2 转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。

3 所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。

4 char型和short型参与运算时,必须先转换成int型。

5 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。


下图表示了类型自动转换的规则。


【例3.12
main(){
  float PI=3.14159;
  int s,r=5;
  s=r*r*PI;
  printf("s=%d\n",s);
}

本例程序中,PI为实型;sr为整型。在执行s=r*r*PI语句时,rPI都转换成double型计算,结果也为double型。但由于s为整型,故赋值结果仍为整型,舍去了小数部分。

强制类型转换
强制类型转换是通过类型转换运算来实现的。其一般形式为:
    (类型说明符)  (表达式)
其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。

例如:
    (float) a      a转换为实型
        (int)(x+y)     x+y的结果转换为整型

在使用强制转换时应注意以下问题:

6 类型说明符和表达式都必须加括号(单个变量可以不加括号),如把(int)(x+y)写成(int)x+y则成了把x转换成int型之后再与y相加了。

7 无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据说明时对该变量定义的类型。

【例3.13
main(){
  float f=5.75;
  printf("(int)f=%d,f=%f\n",(int)f,f);
}

    本例表明,f虽强制转为int型,但只在运算中起作用,是临时的,而f本身的类型并不改变。因此,(int)f的值为 5(删去了小数)f的值仍为5.75