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



边栏推荐
猜你喜欢

8年软件测试工程师感悟 —— 写给还在迷茫中的朋友

Using Canvas to achieve web page mouse signature effect

02 es cluster construction

软件测试谈薪技巧:同为测试人员,为什么有人5K,有人 20K?

华盛顿大学、Allen AI 等联合 | RealTime QA: What's the Answer Right Now?(实时 QA:现在的答案是什么?)

90后的焦虑,被菜市场治好了

时序数据库在船舶风险管理领域的应用

04 flink cluster construction

谁还敢买影视股?

OneFlow源码解析:Op、Kernel与解释器
随机推荐
助推科技强国高质量发展《科创超级训练营》系列活动正式拉开帷幕
金仓数据库 OCCI迁移指南(3. KingbaseES的OCCI特性支持)
谁还敢买影视股?
uwsgi配置文件启动
03 gp 集群搭建
金仓数据库 OCCI迁移指南(2. 概述)
untiy Resorces目录动态加载资源
沈腾拯救暑期档
全新升级!《云原生架构白皮书 2022 版》重磅发布
LeetCode第 303 场周赛
js邯郸市地图网页源码下载
我的新书销量1万册了!
金仓数据库 KDTS 迁移工具使用指南(3. 系统部署)
11 一发布就发布一系列系列
金仓数据库 MySQL 至 KingbaseES 迁移最佳实践(2. 概述)
蚂蚁首次披露核心基础软件技术开源版图
GridControl helper class for DevExpress
时序数据库在船舶风险管理领域的应用
Ant discloses the open source layout of core basic software technology for the first time
Slider/Carousel图片切换支持触摸屏