C语言学习过程总结(12)——操作符详解(2)

一、操作符的属性:优先级、结合性

这两个重要的属性决定了表达式求值的计算顺序

1.优先级

例:3 + 4 * 5

就是先计算4 * 5,然后计算3 + 20 结果是23而不是35

因为乘法的运算优先级高于加法

2.结合性

当运算符的优先级相同的时候,就要看结合性来决定先计算谁

分为右结合和左结合,大部分运算法都是左结合(从左往右计算),少数的右结合(从左往右计算),比如赋值运算符(=),将右边的值赋给左边

大家大概记住下面这些运算符的优先级就可以了

• 圆括号( () )

• ⾃增运算符( ++ ),⾃减运算符( -- )

• 单⽬运算符( + 和 - )• 乘法( * ),除法( / )

• 加法( + ),减法( - )

• 关系运算符( < 、 > 等)

• 赋值运算符( = )

(由上至下优先级递减)

由于圆括号的优先级最高,可以使用它改变其他运算符的优先级。

也可以参考下面的链接

https://zh.cppreference.com/w/c/language/operator_precedence

这些优先级和数学的运算逻辑比较相似,可以结合计算

二、表达式求值

1.整型提升

C语言中的整型算术运算总是至少按照默认整型类型的精度来计算的,也就是int

也就是说,在计算char、short类型的数据时也会被转换成int类型计算,计算完成之后再进行截断保留原本类型长度

那这不是脱裤子放屁吗,增长又截断,为什么要这么做?

简单来说:就是CPU中的计算元器件ALU中一般都是int字节长度,在CPU中难以处理的一些数据转换为int类型就可以处理

怎么进行整型提升

1. 有符号整数提升是按照变量的数据类型的符号位来提升的

2. 无符号整数提升,高位补0

//负数的整形提升

char  c1 = -1;

变量c1的⼆进制位(补码)中只有8个⽐特位:1111111

因为 char 为有符号的 char

所以整形提升的时候,⾼位补充符号位,即为1

提升之后的结果是:

11111111111111111111111111111111

//正数的整形提升11char  c2 = 1;

变量c2的⼆进制位(补码)中只有8个⽐特位:00000001

因为 char 为有符号的 char

所以整形提升的时候,⾼位补充符号位,即为0

提升之后的结果是:00000000000000000000000000000001

//⽆符号整形提升,⾼位补0 

2.算术转换

如果同一操作符的操作数是不同的类型,那么除非统一转化为其中一个类型,不然操作无法进行

long double

double

float

unsigned long int

long int

unsigned int

int

如果某个操作数的类型在上面这个列表中排名靠后,那么首先要转换为另外⼀个操作数的类型后执行运算。

3.问题表达式

1.   a*b + c*b + e*f

在计算机眼中,这就有两个运算路径

1.先全部算乘法,然后全部算加法

2.先算a*b和c*b 然后两者相加,再算e*f,在相加

2.   c + --c

同上,操作符的优先级只能决定⾃减 -- 的运算在 + 的运算的前⾯,但是我们并没有办法得知, + 操作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义的。
假设int c = 5

那么第一个c可能是5 也可能是4

3.如图
#include <sdtio.h>
int fun()
{
static int  count = 1;
return  ++count;
}
int main()
{
int  answer;
 answer = fun() - fun() * fun();
printf( "%d\n", answer);//输出多少?
return 0;
}

 我们虽然可以知道先算乘法再算加法,但是先调用那个函数我们是无法知道的

4.总结

即使有优先性和结合性,表达式依然可能具有不同的计算路径,造成歧义,所以我们不要写出不负责的表达式,也不要写很复杂的表达式,代码不是越简单越好,而是要让人看清,用一个表达式表示过多的信息,这个表达式除了计算机和本人就没有人能知道是什么了。而且时间一长可能本人都忘记是为什么写出来了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值