操作符详解(下) (C语言)

操作符详解下

操作符的属性

C语言的操作符有2个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。

1.优先级

优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执行。各种运算符的优先级是不⼀样的。

比如 3 + 4 * 5,表达式 3 + 4 * 5 里面既有加法运算符( + ),又有乘法运算符( * )。由于乘法的优先级高于加法,所以会先计算 4 * 5 ,而不是先计算3+4。

2.结合级

如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符是左结合,还是右结合,决定执行顺序。大部分运算符是左结合 (从左到右执行),少数运算符是右结合(从右到左执行),比如赋值运算符( = )。

比如 5 * 6 / 2, * 和 / 的优先级相同,它们都是左结合运算符,所以从左到右执行,先计算 5 * 6 ,再计算 / 2 。

运算符的优先级顺序很多,下面是部分运算符的优先级顺序(按照优先级从高到低排列)详细的可以参考:https://zh.cppreference.com/w/c/language/operator_precedence

表达式求值

1.整型提升

C语言中整型算术运算总是至少以缺省(默认)整型类型的精度来进行的。

为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型 ,这种转换称为整型提升

下面展示一些 内联代码片

复制代码
javascript 复制代码
int main()
{
char a,b,c;
a=b+c;
}

就比如上面的代码,b和c的值被提升为普通整型,然后再执行加法运算。加法运算完成之后,结果将被截断,然后再存储于a中。

(表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。

通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行)

2.如何进行整形提升呢?

  1. 有符号整数提升是按照变量的数据类型的符号位来提升的
  2. 无符号整数提升,高位补0
    比如:

3.算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中⼀个操作数的转换为另⼀个操作数的类型 ,否则操作就无法进行。下面的层次体系称之为寻常算术转换 。如果某个操作数的类型在上面这个列表中排名靠后,那么首先要转换为另外⼀个操作数的类型后执行运算。

4.问题表达式解析

其实有时候我们会发现如果一个表达式太过复杂或者表达不清楚,虽然编译器会给出结果但是去不一定正确,并且有可能在不同的编译器上给出的结果是不一样的,所以这样的表达式是有问题的。

1.比如:c+ --c; 操作符的优先级只能决定减 -- 的运算在 + 的运算的前面,但是我们并没有办法得知, + 操作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义的。

2.

很显然,像这样有歧义的表达式在不同的编译器中会有不同的结果,再者说这样的表达式在一些运算当中都是错误的是不可取的。所以即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性确定唯⼀的计算路径,那这个表达式就是存在潜在风险的,建议不要写出特别复杂的表达式。

相关推荐
hello早上好11 分钟前
JDK 代理原理
java·spring boot·spring
PanZonghui16 分钟前
Centos项目部署之Java安装与配置
java·linux
破无差27 分钟前
python实现简单的地图绘制与标记20250705
python
向阳@向远方28 分钟前
第二章 简单程序设计
开发语言·c++·算法
JeffersonZU38 分钟前
Linux/Unix进程概念及基本操作(PID、内存布局、虚拟内存、环境变量、fork、exit、wait、exec、system)
linux·c语言·unix·gnu
沉着的码农1 小时前
【设计模式】基于责任链模式的参数校验
java·spring boot·分布式
喜欢吃豆1 小时前
目前最火的agent方向-A2A快速实战构建(二): AutoGen模型集成指南:从OpenAI到本地部署的全场景LLM解决方案
后端·python·深度学习·flask·大模型
Mr_Xuhhh1 小时前
信号与槽的总结
java·开发语言·数据库·c++·qt·系统架构
纳兰青华1 小时前
bean注入的过程中,Property of ‘java.util.ArrayList‘ type cannot be injected by ‘List‘
java·开发语言·spring·list
好开心啊没烦恼1 小时前
Python 数据分析:DataFrame,生成,用字典创建 DataFrame ,键值对数量不一样怎么办?
开发语言·python·数据挖掘·数据分析