当前位置:网站首页>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,
所以右边根本不会计算,这就控制了求值顺序了



边栏推荐
- 夸克网盘资源站
- 火花:集群计算工作集
- Description of common operations and help projects about DevExpress in C#
- A full review of mainstream timed task solutions
- 金仓数据库KingbaseES安全指南--6.5. LDAP身份验证
- 使用Canvas 实现手机端签名
- 08 Spark cluster construction
- 搭建云计算平台(云计算管理平台搭建)
- Ant discloses the open source layout of core basic software technology for the first time
- 14年测试人最近的面试经历,值得借鉴√
猜你喜欢

MLX90640 红外热成像仪测温模块开发笔记(完整版)

月薪12K,蝶变向新勇往直前,我通过转行软件测试实现月薪翻倍...

22年镜头“卷”史,智能手机之战卷进死胡同

完全背包问题求组合数和排列数

网站备案后没有找到站点 您没有将此域名或IP绑定到对应站点! 配置文件未生效!

Ant discloses the open source layout of core basic software technology for the first time

uwsgi配置文件启动

08 Spark cluster construction

MUI 做手机返回操作栏

C# LibUsbDotNet 在USB-CDC设备的上位机应用
随机推荐
金仓数据库KingbaseES安全指南--6.5. LDAP身份验证
【Unity,C#】哨兵点位循迹模板代码
首席工程师究竟是怎样的存在?
聊下自己转型测试开发的历程
使用Canvas实现网页鼠标签名效果
年化收益高的理财产品
C # Excel helper classes
04 flink cluster construction
05 Doris cluster construction
月薪12K,蝶变向新勇往直前,我通过转行软件测试实现月薪翻倍...
Use Canvas to implement mobile phone signature
LeetCode Week 303
HashCode technology insider interview must ask
请问nacos 连接mysql失败后会重新连接吗?
5年测试,只会功能要求17K,功能测试都敢要求这么高薪资了?
UI helper class for Winform - some components will use DevExpress components
SQL函数 TIMESTAMPDIFF
Financial products with high annualized returns
27英寸横置大屏+实体按键,全新探险者才是安全而合理的做法
IronOS, an open source system for portable soldering irons, supports a variety of portable DC, QC, PD powered soldering irons, and supports all standard functions of smart soldering irons