当前位置:首页 » 《关注互联网》 » 正文

C语言操作符终极揭秘:表达式求值秘籍

1 人参与  2024年12月09日 10:01  分类 : 《关注互联网》  评论

点击全文阅读


C语言中操作符详解(终结篇)

放在最前面的表达式求值定义(1) 操作数的求值(2) 操作符的应用(3)类型转换(3.1)隐式类型转换(Type Promotion)举例分析:(上代码)输出结果: (3.2)算术转换(Arithmetic Conversion)举例分析:(上代码)输出结果: (4)优先级和结合性举例分析:(上代码)输出结果: 综合举例分析:(上代码)代码详细分析:输出结果: 总结 END

放在最前面的

? ? 我的CSDN主页:OTWOL的主页,欢迎!!!????
??我的C语言初阶合集:C语言初阶合集,希望能帮到你!!!?
? ????创作不易,欢迎大家留言、点赞加收藏!!! ???

表达式求值

定义

C语言中的表达式求值是一个复杂但有序的过程,
它涉及多个步骤和原则,
包括操作数的求值、操作符的应用、类型转换、以及优先级和结合性的考虑。
下面我将详细解释这些方面,并通过例子进行分析。

(1) 操作数的求值

在C语言中,表达式的求值通常 从左到右 进行(除非受到操作符优先级和结合性的影响)。
首先,表达式中的所有操作数都会被求值。
如果操作数是变量或复杂表达式,那么这些变量或表达式的值会被计算出来。

(2) 操作符的应用

一旦操作数被求值,接下来就会根据操作符的类型(如算术操作符、关系操作符、逻辑操作符等)对它们进行相应的运算。
在这个过程中,类型转换(特别是隐式类型转换)可能会发生。

(3)类型转换

类型转换 是 C语言表达式求值中 的一个重要方面。
当两个不同类型的操作数参与运算时,编译器会根据一定的规则将它们转换为一种公共类型。
这些规则通常包括 整数提升、浮点提升 以及 算术转换。

(3.1)隐式类型转换(Type Promotion)

隐式类型转换发生在两个不同类型的操作数参与运算时,
编译器会自动将它们转换为一种公共类型,然后进行运算。
这种转换通常遵循一定的规则,
如 整数提升(Integer Promotion)和 浮点提升(Floating Promotion)。

整数提升:小的整数类型(如charshort)会被提升为 int 类型(如果 int 能表示其所有值),如果不能,则提升为 unsigned int

浮点提升:float 类型通常会被提升为 double 类型进行运算。

举例分析:(上代码)
#include<stdio.h>int main(){char a = 10;int b = 20;float ret = a + b; // 这里a会被提升为 int,然后与 b相加,结果再转换为 float//输出printf("ret = %f\n", ret);return 0;}
输出结果:

(3.2)算术转换(Arithmetic Conversion)

算术转换 是隐式类型转换的一种特殊情况,发生在涉及算术运算符(如+, -, *, /)的表达式中
它的规则比一般的隐式类型转换更为具体:

1. 如果操作数中有long double类型,则另一个操作数被转换为long double

2. 否则,如果操作数中有double类型,则另一个操作数被转换为double

3. 否则,如果操作数中有float类型,则另一个操作数(如果为整型)被转换为float(整型提升为int后)。

4. 否则,所有操作数都被转换为int类型(如果它们原本是charshort类型,则先进行整数提升)。

举例分析:(上代码)
int main(){float x = 3.14f;int y = 2;double ret = x * y; // y会被提升为 float,然后与 x相乘,结果再转换为 double//输出printf("ret = %lf\n", ret);return 0;}
输出结果:

(4)优先级和结合性

操作符的 优先级 决定了在表达式中哪个操作首先被执行。具有更高优先级的操作符会先被计算。
如果两个操作符具有相同的优先级,则它们的 结合性 决定了操作是从左到右还是从右到左进行。

优先级:

例如,乘法( * )和除法( / )的优先级高于加法( + )和减法( - )。
括号( () )可以用来改变默认的优先级顺序。

结合性:

大多数操作符(如加法、乘法、赋值等)是从左到右结合的。
这意味着当操作符 具有相同的优先级时,操作会从左到右 依次进行。
但是, 也有一些操作符(如单目操作符 和 赋值操作符等)是从右到左结合的。

举例分析:(上代码)
#include<stdio.h>int main(){int a = 5, b = 10, c = 20;int ret = a + b * c; // 因为乘法优先级高于加法,所以先计算 b*c,然后加上a//输出printf("ret = %d\n", ret);return 0;}
输出结果:


综合举例分析:(上代码)

#include <stdio.h>int main() {    char a = 'A'; // ASCII值为 65    int b = 10;    double c = 3.5;    double ret = 0.0;    // 表达式求值    ret = (double)(a + b) / c;    // 打印结果    printf("ret = %lf\n", ret);    return 0;}
代码详细分析:

(1)操作数求值:

a 的值是65(char类型ASCII值为65)。
b 的值是10(int类型
c 的值是3.5(double类型)。

(2)类型转换

(a + b) 中,a被提升为 int类型(实际上它已经是int类型了,因为char类型在这里被提升),
然后与 b相加得到 75(int类型)。
然后,(double)(a + b)将 75(int类型)转换为75.0(double类型)。

(3) 操作符的应用

最后,75.0 / c 执行浮点除法运算,
结果是 20.833333(double类型)。

(4)优先级和结合性
在这个表达式中,括号()的优先级最高,
所以首先计算 (a + b)
然后是类型转换(double类型)(…)。
最后是除法运算 /
由于除法和类型转换都是从左到右结合的,所以它们的顺序是确定的。
结果:
ret 的值为 20.833333(具体值可能因编译器和平台而异,但大致接近这个值)。
输出结果:

总结

即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性确定唯一 的 计算路径,
那这个表达式就是 存在潜在风险的,建议 不要写出特别复杂的的表达式。

END

每天都在学习的路上!
On The Way Of Learning


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/198468.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1