当前位置:网站首页>C语言:表达式求值详解
C语言:表达式求值详解
2022-08-01 16:34:00 【高邮吴少】
前言
该篇文章是笔者之前一篇文章C语言操作符详解的后续补充:
表达式求值的顺序一部分是由操作符的优先级和结合性决定。
同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。
本文将介绍隐式类型转换、算术转换、和操作符的相关属性。预祝读者学业有成,天天进步!
提示:以下是本篇文章正文内容,下面案例可供参考
一、隐式类型转换
C的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,
这种转换称为整型提升。
举个例子:
int main()
{
char a = 3;
char b = 127;
char c = a + b;
return 0;
}
b和c的值被提升为普通整型,然后再执行加法运算。
加法运算完成之后,结果将被截断,然后再存储于a中。
如何进行整形提升?
整形提升是按照变量的数据类型的符号位来提升的
//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//无符号整形提升,高位补0
整形提升的例子:
示例1:
int main()
{
char a = 3;
//整形3的补码:00000000 00000000 00000000 00000011
//但是我们这里的a只有1byte,也就是8bit
//所以a:00000011
char b = 127;
//整形127的补码:00000000 00000000 00000000 01111111
//同理b:01111111
char c = a + b;
//a和b都是char类型,自身大小都是1byte,所以这里计算的时候要整形提升
//因为都是正数,所以整形提升前面补0
//a: 00000000 00000000 00000000 00000011
//b: 00000000 00000000 00000000 01111111
//a+b:00000000 00000000 00000000 10000010
//计算完后发生截断(char一共8字节,取后面8位)
//c: 10000010
printf("%d\n", c);
//以%d的形式打印,也就是以整形形式打印,这里c又发生了整形提升
//但是这里因为c是10000010,就认为它的最高位是1,也就是负数了
//负数整形提升是前面补1
//c补:11111111 11111111 11111111 10000010(内存里存的是补码)
//c反:11111111 11111111 11111111 10000001(负数反码=补码-1)
//c原:10000000 00000000 00000000 01111110(负数原码=反码符号位不变其他全变)
//我们打印的是原码,也就是-126
return 0;
}
ps:整形提升也就是发生在short和char这两个类型上,因为其他类型都比int型大
示例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没有参加运算也不会有整形提升,所以大小还是1
但是sizeof(+c)和sizeof(-c)进行了运算,所以会有整形提升,也就是变成4字节了
二、算术转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类
型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
long double
double
float
unsigned long int
long int
unsigned int
int
//从下往上进行转换,eg:int->long double
如果某个操作数的类型在上面这个列表中排名较低,
那么首先要转换为另外一个操作数的类型后执行运算。
举个例子:
int main()
{
int a = 4;
float b = 4.1f;
float c = a + b;//会把int类型的a算术转换成float类型,再与b进行计算
return 0;
}
三、操作符的属性
复杂表达式的求值有三个影响的因素。
- 操作符的优先级
- 操作符的结合性
- 是否控制求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。
如果两者的优先级相同,取决于他们的结合性。
下图中操作符优先级从上到下,是从高到底的
结合性L-R表示从左向右,比如a+b+c是先算a+b,再算+c
是否控制求值顺序,比如0&&(a+b*c/d),因为你&&左边是0,
所以右边根本不会计算,这就控制了求值顺序了
边栏推荐
猜你喜欢
随机推荐
珠海市生物安全P3实验室主体结构封顶
mysql源码分析——聚簇索引
04 flink 集群搭建
使用Canvas 实现手机端签名
C#的CSV格式文件帮助类
js邯郸市地图网页源码下载
等变图神经网络在药物研发中大放异彩
C#中关于DevExpress的常用操作和帮助类项目工程内容说明
Winform的UI帮助类——部分组件会使用到DevExpress组件
C#Excel帮助类
助推科技强国高质量发展《科创超级训练营》系列活动正式拉开帷幕
Winform message prompt box helper class
TiFlash 存储层概览
Isometric graph neural networks shine in drug discovery
Ranking of itineraries (summer vacation daily question 12)
11 一发布就发布一系列系列
金仓数据库 KingbaseES V8.3 至 V8.6 迁移最佳实践(4. V8.3 到 V8.6 数据库移植实战)
C# LibUsbDotNet 在USB-CDC设备的上位机应用
时序数据库在船舶风险管理领域的应用
14年测试人最近的面试经历,值得借鉴√