2.4算术表达式中的自动类型转换 2.5强制类型转化运算符

在一个算术表达式中,如果是相同类型的操作数,进行运算,那么,它的运算类型的结果究竟是什么呢?
C语言规定,相同类型的数据进行运算的结果类型与操作数的类型是相同的
例如整数除法,就是这样的一个非常典型的例子
被除数和除数都是整型,那么它们相除的结构,也是整型的
实际上它的小数部分是被舍弃掉了,


如果是不同类型的操作数进行运算,那么它的结果类型是什么呢?
C语言规定,不同类型的操作数,进行运算,它的结果类型就是操作数中取值范围较大的,那么种类型
例如浮点数除法
如果一个浮点数和一个整形术进行除法运算,C编译器会将所有类型的数,全部转化成取值较大的那个操作数的类型,这里都转化为浮点类型
然后在执行这个除法运算,这样就可以得到它的小数部分了
那么不同类型的操作数进行除法运算的时候,C编译器将所有的操作数,都转化为取值范围较大的那种操作数的类型,这个过程就称为类型提升
2.4算术表达式中的自动类型转换 2.5强制类型转化运算符2.4算术表达式中的自动类型转换 2.5强制类型转化运算符2.4算术表达式中的自动类型转换 2.5强制类型转化运算符将字符型和短整型转化为基本整型,然后在进行计算
这个过程称为整数提升。
C99增强了整数提升规则
当不同类型的数据类型,进行混合运算的时候,需要根据参与运算操作数的类型,由低级别到高级别进行自动转换,这个时候由编译器来自动完成的。
如何理解横向箭头和纵向箭头呢?
纵向箭头,表示必然的转换,而横向箭头表示的是不同类型的操作数进行混合运算时,由低到高的类型转换的方向。
但是它不代表这个转化所必需的的中间过程,
例如一个整型和单精度浮点类型
int+float→ float +float
计算时,计算机会先将整型转化为单精度浮点类型,然后在去运算,但是由整型转换为浮点类型,是直接转换的。
也就是说Int类型转换为浮点类型,是不需要经过unsigned long这个中间过程的,可直接进行转换。
long+unsigned int → 我们知道Long类型表达的上限值 214
而unsigned上限值是429.
429>214
如果Unsigned 超出了四字节的long类型,能够表达数据的上限值的话,那么long无法表达unsigned,否则会产生溢出,为了避免产生溢出
编译器会将上述两种类型都转换为unsigned long。然后再去进行计算。

2.4算术表达式中的自动类型转换 2.5强制类型转化运算符
2.4算术表达式中的自动类型转换 2.5强制类型转化运算符2.4算术表达式中的自动类型转换 2.5强制类型转化运算符

类型级别较高的数据类型,比类型级别较低的数据类型,所占的内存字节空间数,要多,因此它有利于保持原有的数据存储的精度,避免数据,在算术运算的过程中因发生自动类型转换,而产生数据信息的丢失。

2.5强制类型转化运算符

例子;定义了两个整形变量和一个浮点型变量
那么编译器就会根据变量定义语句中,变量的类型为这三个变量分配相应大小的存储单元,假设经过后边的代码计算呢。
我们得到了toal值15,number值2,
此时当程序进行到这条语句aver = total /numer的时候,也就是要执行这个除法运算,而这个除法运算,这个被除数total,是一个整型,除数number也是一个整型的,也就是说,它实际上是执行的一个整数除法运算,想同类型的计算结果仍然是这种类型,因此,两个整数进行整数除法运算的结果,仍然是整数,因此15/2的结果不会是7.5,而是7。
将7的值赋值给浮点类型的变量aver,aver得到的值也会是7,尽管aver也是一个浮点类型的变量,但是它仍然得不到这个除法运算的小数部分。
2.4算术表达式中的自动类型转换 2.5强制类型转化运算符2.4算术表达式中的自动类型转换 2.5强制类型转化运算符我们将total整型改为浮点型,在执行tatal/number就不在执行整数除法运算了。因为total被定义为了浮点类型,而Number是整数型的
在不同类型的数据之间进行运算的的时候,它的运算结果的类型应该是取值范围较大的那个数据类型,因此,这个运算的结果,应该是一个浮点类型的结果。
也就是说,编译器在执行这个运算的时候,回自动将除数的数据类型,转化为浮点类型, 然后在去计算这个结果,因此就是相当于执行了一个浮点数的除法运算,因此它的结果是7.5,也就是说浮点数除法,运算的结果仍然是一个浮点数。那么将7.5赋值给aver后,那么aver就得到了除法运算的小数部分。
在这里由于参与运算的两个操作数的数据类型是不同的,那么在不同的数据类型的数据之间进行运算的时候,编译器是要进行一个类型提升,也就是将操作数的类型都转化为取值范围较大的那个数据类型,然后在去进行运算。但是因为这种自动类型转换,它是隐士表达的,有些时候,我们需要这种自动类型转换,但是有些时候,这种自动类型的转换,并非我们程序员的本意。由于它是隐士表达,我们无法知道程序员的本意究竟是什么,因此这种隐士的自动类型转换,它会给程序带来一些迭代的错误隐患,而这种错误隐患又是非常隐蔽的,很难被发现,那么如何来避免这种隐士的自动类型转换呢?来显示的表明程序员的意图呢?
我们可以通过、
aver = (float)total / number
将一个表达式的类型强制转换为我们用户指定的数据类型
在这里这个括弧数据类型就代表了强制类型转换运算符 -类型强转(CASTING)
一般类型为:(表达式)类型 ————-一元运算符
由于它只需要一个操作数,因此它只是一个一元运算符。
这个一元运算符,与其他的一元运算符,都具有相同的优先级。通过这种显示的表达数据类型,可以明确的表明程序员的意图是什么,也就是说显示的来表明程序打算执行哪一种类型转换,有助于消除自动类型转换,给成宿带来的错误隐患
2.4算术表达式中的自动类型转换 2.5强制类型转化运算符2.4算术表达式中的自动类型转换 2.5强制类型转化运算符请看强制转换运算符是如何来执行的
首先将tatal的值15先转换为15.000000这样的浮点数,然后在与进行除法运算,由于被除数被转换为了一个浮点数,而被除数和除数中,只要有一个为浮点数,那么它执行的就是一个浮点数除法运算,因此它的除法运算的结果,仍然是时一个浮点数,就是7.5 将7.5的值赋值给aver,那么aver得到了除法部分的小数部分。这里尤其需要对total强制类型转换float,它并不改变total,变量本身的类型。以及total变量本身的值。
total这个本身的类型,仍然是整型,而total的值,也仍然是15,这个整数,它只是将表达式的值暂时转换为浮点数,用于后续运算而已。
2.4算术表达式中的自动类型转换 2.5强制类型转化运算符刚才的程序是对total执行了一个强制类型转换。
如果我们将这条语句修改为
(float)(total/number)结果是什么?
它表达,将total/number这个表达式作为强制类型转换的操作数,也就是将这个表达式的值,强制转换为浮点类型,并不是将total,转换为float类型,因此它是先求出total/number的值就是15/2的值7,强制转换为浮点类型,在讲其赋值给aver。
因此依然得不到除法的小数部分的。
因此在使用强制类型转换运算符的时候,一定要明确。它是对哪一个表达式进行强制类型转换2.4算术表达式中的自动类型转换 2.5强制类型转化运算符2.4算术表达式中的自动类型转换 2.5强制类型转化运算符