不同数据类型混合运算及类型转换

1.类型装换

在这里插入图片描述
在这里插入图片描述

2.隐式转化

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

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

    1. 若两种类型的字节数不同,转换成字节数高的类型
    
    2. 若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型
    
  • 所有的浮点运算都是以双精度进行的,即使是两个float单精度量运算的表达式,也要先转换成double型,再作运算.

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

  • 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。

       如果右边量的数据类型长度比左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入
    
  • 函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。

  • 函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。

3. 例子

	unsigned int 	a = 30;
	int 			b = - 130;
	
	if ( a > b )
		printf("a > b\r\n");
	if ( a < b )
		printf("a < b\r\n");

结果如下:

wll@wll-linux:~/code/test$ ./cal
a > b
  • 根据前面提到的规则:不同的运算要先转换为同一类型才能运算,短字节要转为长字节类型,长度相同时,有有符号转为无符号,所以-130转为无符号,将是一个很大的数。
	unsigned short a = 0;
	unsigned int   b = 0x12345678;
	
	a = b;
	
	printf("b:0x%x, a:0x%x\r\n", b, a);
	

结果如下:

wll@wll-linux:~/code/test$ ./cal
b:0x12345678, a:0x5678
  • 赋值运算等号右边的类型会转换为左边的类型,如果左边的类型比右边的短,则数据被截断后赋值
unsigned char test(unsigned short x)
{
	printf("x: 0x%x\r\n", x);
	
	return x;
}

unsigned short a = 0;
unsigned int   b = 0x12345678;


printf("a:0x%x\r\n", a=test(b));

结果如下:

wll@wll-linux:~/code/test$ ./cal
x: 0x5678
a: 0x78
  • 从结果可以看出“返回表达式类型转换为返回值类型”,函数参数传递的时候实参转换为形参的类型后,赋值给形参

5.代码误区

由于不熟悉不同类型间运算规则,导致的代码bug,大部分人应该都遇到过,举例如下:

	unsigned int a = 1;
	unsigned int   b = 100;
	
	for ( b; b-a >= 0; b--)
	{
		printf("b-a:0x%x\r\n",b-a);
	}
	

以上代码并不会按照预期运行,而是出现了死循环:

无符号数想减,结果永远是无符号数,而无符号数,是不会<0的,所以for循环不会通知。

保持语义不变的情况下可以改为如下:

	
	for ( b; b >= a; b--)
	{
		printf("b:0x%x\r\n",b);
	}
	

另外,函数参数传递过程中的类型不一致导致的问题,也是层出不穷,待笔者日后遇到再进行补充

6.参考

https://www.cnblogs.com/weiyouqing/p/9090542.html

猜你喜欢

转载自blog.csdn.net/wll1228/article/details/106340567