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



边栏推荐
猜你喜欢
随机推荐
uwsgi配置文件启动
MySQL加锁案例分析
MySQL locking case analysis
How to Efficiently Develop Jmix Extension Components
显示为弹出窗口是什么意思(电脑总是弹出广告)
金仓数据库KingbaseES安全指南--6.5. LDAP身份验证
canvas粒子雨动画js特效
金仓数据库 OCCI迁移指南(2. 概述)
DevExpress的GridControl帮助类
03 gp cluster construction
MySQL's maximum recommended number of rows is 2000w, is it reliable?
直播app开发,是优化直播体验不得不关注的两大指标
阿里官方 Redis 开发规范
Go 单元测试
珠海市生物安全P3实验室主体结构封顶
使用Canvas实现网页鼠标签名效果
中国驻西班牙使馆再次提醒留学人员注意暑期安全
高薪程序员&面试题精讲系列131之Eureka如何实现高可用?自我保护机制是怎么回事?
ESP8266-Arduino programming example-GA1A12S202 logarithmic scale analog light sensor
C# LibUsbDotNet 在USB-CDC设备的上位机应用









