你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

表达式求值

2021/11/22 0:37:49

目录

1:隐式类型转换

2:算术转换

3:操作符的属性


1:隐式类型转换

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

上代码:

#include<stdio.h>
int main()
{
	char a = 5;
	// 截断
	// 00000000000000000000000000000101    5的二进制 32个bit位
	// 00000101  截断后存在char类型中,只有8个bit位
	char b = 126;
	// 00000000000000000000000001111110
	// 01111110

	// 00000101  - a
	// 01111110  - b
	// 此时整型提升
	// 整形提升是按照变量的数据类型的符号位来提升的  第一位是0,补0.第一位是1,补1
	// 整型提升后:      00000000000000000000000000000101  - a
	//                   00000000000000000000000001111110  - b
	char c = a + b;
	// 此时相加          00000000000000000000000010000011  - c
	// 又因为是char类型,所以取8个bit位:        10000011  - c
	// 整型提升:        11111111111111111111111110000011  - c - 补码
	// 内存存的是补码,打印的是原码
	//                   11111111111111111111111110000010  - c - 反码
	//                   10000000000000000000000001111101  - c - 原码  -125
	
	printf("%d\n", c); // -125     整型提升
	return 0;
}

练习:

#include<stdio.h>
int main()
{
	char c = 1;
	printf("%u\n", sizeof(c));   //1
	printf("%u\n", sizeof(+c));  //4
	printf("%u\n", sizeof(-c));  //4
	return 0;
}

2:算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类 型,否则操作就无法进行。下面的层次体系称为寻常算术转换。

 // char short整型提升
 // int long longlong float double 算术转换
#include<stdio.h>
int main()
{
	int a = 3;
	float b = 5.5;
	float c = a + b;  //算术转换
	printf("%f\n", c);   // 8.500000
	return 0;
}
// sizeof内部的表达式是不参与计算的
#include<stdio.h>
int main()
{
	short s = 20;
	int a = 5;
	printf("%d\n", sizeof(s = a + 4));  //2
	printf("%d\n", s);  //20
	return 0;
}

3:操作符的属性

复杂表达式的求值有三个影响的因素。

1. 操作符的优先级

2. 操作符的结合性

3. 是否控制求值顺序。

两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。

// 10.3.1操作符的优先级
#include<stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int c = a + b * 10; //优先级
	int d = a + b + 10; //相邻操作符的优先级相同的情况下,结合性说了算
	return 0;
}

//一些问题表达式
//  1: a* b + c * d + e * f
//     注释:代码1在计算的时候,由于*比+的优先级高,只能保证,*的计算是比+早,但是优先级并不能决定第三个* 比第一个 + 早执行。
//  2: c + --c;
//     5 + 4 = 9
//     4 + 4 = 8
//  3:
#include<stdio.h>
int fun()
{
    static int count = 1;
    return ++count;
}
int main()
{
    int answer;
    answer = fun() - fun() * fun();
    printf("%d\n", answer);//输出多少?  //-10
    return 0;
}
//此编译器输出-10,但在不同编译器下数值不一样,编译器紊乱
//总结:我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的。