c语言表达式求值--整型提升

什么是整型提升?

C的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。

什么叫缺省整数类型?缺省在计算机里面是默认的意思。

这句话大概意思就是,在c语言的整数运算中,如果有精度小于整型的非自定义类型数,就需要先转换为一个整数类型。

比如char和short int类型,它们的字节数分别为1、2,如果它们参与整数表达式的运算就会先转换成整数类型,再参与运算。

这里我们只谈论char和short int

代码举例:

int main()
{
	char a = 0x80;
	short b = 0x8000;
	int c = 0x86000000;
	if (a == 0x80)
		printf("a");
	if (b == 0x8000)
		printf("b");
	if (c == 0x86000000)
		printf("c");
	return 0;
}

看结果:

c语言表达式求值--整型提升_第1张图片只输出了一个c。

为什么会这样呢?a、b变量被赋予的值也没有超出它们的字节大小代表的最大值,为什么a==0x80和b==0x8000会为假呢?

这其中就发生了整型提升。

 

整型提升的规则

1、操作数为int的时候,高位补充符号位

2、操作数为unsigned int(无符号整数)的时候,高位补充0

 分析例子

1.变量a整型提升:

首先,a占一个字节,在转换前被赋值0x80(十六进制),二进制(补码)表示为1000 0000。

符号位是1.

整型提升变成四个字节,前面补充1,就转换成了:

1111 1111 1111 1111 1111 1111 1000 0000

所以这个时候的a就不等于原来的数了,很明显这都变成了一个负数。

2.变量b整型提升:

首先,b占两个字节,在转换前被赋值0x8000(十六进制),二进制(补码)表示为:

1000 0000 0000 0000

符号位是1.

整型提升变成四个字节,前面补充1,就转换成了:

1111 1111 1111 1111 1000 0000 0000 0000

所以这个时候的b就不等于原来的数了,很明显这都变成了一个负数。

而c是int,不需要转换。

代码1:


int main() {
	char a = 0x80;
	char b = 0x80;
	int c = a + b;
	printf("%d", c);

	return 0;
}

这里又会输出什么结果呢?

因为运算涉及到整数,所以字符a和b在参与计算的时候会先整数提升,而根据上面我们知道,a整型提升之后是一个负数,所以得到:

c语言表达式求值--整型提升_第2张图片

 

代码2:

int main()
{
 char c = 1;
 printf("%u\n", sizeof(c));
 printf("%u\n", sizeof(+c));
 printf("%u\n", sizeof(-c));
 return 0;
}

这里我们要注意,我前面已经强调过,只有在参与运算的时候才会考虑是否要整型提升,而sizeof(c)里的c并没有参与运算,所以不需要整型提升,得到的还是一个字节。

那么sizeof(+c)和sizeof(-c)呢?c语言会认为(+c)和(-c)都是参与了运算,所以需要整型提升,得到的也就是一个整型的字节大小。

c语言表达式求值--整型提升_第3张图片

 

整型提升的意义?

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 一般就是int的字节长度,同时也是CPU的通用寄存器的长度。 因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长 度。 通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转 换为int或unsigned int,然后才能送入CPU去执行运算。

总的来说,整型提升的目的是为了保持表达式中操作数的一致性。当不同大小的整数类型参与运算时,较小的类型会被提升为较大的类型,以避免精度丢失和数据溢出的问题

 

你可能感兴趣的:(c语言必备知识点,c语言,开发语言)