表达式求值

简介: 目录1:隐式类型转换2:算术转换3:操作符的属性

1:隐式类型转换

C的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。

image.png

上代码:

#include<stdio.h>
int main()
{
  char a = 5;
  // 截断
  // 00000000000000000000000000000101    5的二进制 32个bit位
  // 00000101  截断后存在char类型中,只有8个bit位
  char b = 126;
  // 00000000000000000000000001111110
  // 01111110
  // 00000101  - a
  // 01111110  - b
  // 此时整型提升
  // 整形提升是按照变量的数据类型的符号位来提升的  第一位是0,补0.第一位是1,补1
  // 整型提升后:      00000000000000000000000000000101  - a
  //                   00000000000000000000000001111110  - b
  char c = a + b;
  // 此时相加          00000000000000000000000010000011  - c
  // 又因为是char类型,所以取8个bit位:        10000011  - c
  // 整型提升:        11111111111111111111111110000011  - c - 补码
  // 内存存的是补码,打印的是原码
  //                   11111111111111111111111110000010  - c - 反码
  //                   10000000000000000000000001111101  - c - 原码  -125
  printf("%d\n", c); // -125     整型提升
  return 0;
}

练习:

#include<stdio.h>
int main()
{
  char c = 1;
  printf("%u\n", sizeof(c));   //1
  printf("%u\n", sizeof(+c));  //4
  printf("%u\n", sizeof(-c));  //4
  return 0;
}

2:算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类 型,否则操作就无法进行。下面的层次体系称为寻常算术转换。

image.png

 // char short整型提升
 // int long longlong float double 算术转换
#include<stdio.h>
int main()
{
  int a = 3;
  float b = 5.5;
  float c = a + b;  //算术转换
  printf("%f\n", c);   // 8.500000
  return 0;
}
// sizeof内部的表达式是不参与计算的
#include<stdio.h>
int main()
{
  short s = 20;
  int a = 5;
  printf("%d\n", sizeof(s = a + 4));  //2
  printf("%d\n", s);  //20
  return 0;
}

3:操作符的属性

复杂表达式的求值有三个影响的因素。

1. 操作符的优先级

2. 操作符的结合性

3. 是否控制求值顺序。

两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。

// 10.3.1操作符的优先级
#include<stdio.h>
int main()
{
  int a = 10;
  int b = 20;
  int c = a + b * 10; //优先级
  int d = a + b + 10; //相邻操作符的优先级相同的情况下,结合性说了算
  return 0;
}
//一些问题表达式
//  1: a* b + c * d + e * f
//     注释:代码1在计算的时候,由于*比+的优先级高,只能保证,*的计算是比+早,但是优先级并不能决定第三个* 比第一个 + 早执行。
//  2: c + --c;
//     5 + 4 = 9
//     4 + 4 = 8
//  3:
#include<stdio.h>
int fun()
{
    static int count = 1;
    return ++count;
}
int main()
{
    int answer;
    answer = fun() - fun() * fun();
    printf("%d\n", answer);//输出多少?  //-10
    return 0;
}
//此编译器输出-10,但在不同编译器下数值不一样,编译器紊乱
//总结:我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的。


相关文章
|
8月前
|
Java 数据处理
Java运算符与表达式详解
Java运算符与表达式详解
|
7月前
|
C++
C++一分钟之-理解C++的运算符与表达式
【6月更文挑战第18C++的运算符和表达式构成了编程的基础,涉及数学计算、逻辑判断、对象操作和内存管理。算术、关系、逻辑、位、赋值运算符各有用途,如`+`、`-`做加减,`==`、`!=`做比较。理解运算符优先级和结合律至关重要。常见错误包括优先级混淆、整数除法截断、逻辑运算符误用和位运算误解。解决策略包括明确优先级、确保浮点数除法、正确使用逻辑运算符和谨慎进行位运算。通过实例代码学习,如 `(a &gt; b) ? &quot;greater&quot; : &quot;not greater&quot;`,能够帮助更好地理解和应用这些概念。掌握这些基础知识是编写高效、清晰C++代码的关键。
51 3
运算符与表达式详解
运算符与表达式详解
|
8月前
|
SQL 数据库 Python
F表达式
F表达式。
48 4
|
编译器 C++
C++的运算符与表达式
在程序中,运算符是用来操作数据的,因此这些数据也被称为操作数,使用运算符将操作数连接而成的式子称为表达式
89 0
C#运算符和表达式的简单运用
C#运算符和表达式的简单运用
|
C# 索引
C#之表达式与运算符
C#之表达式与运算符
|
C语言
【学习笔记之我要C】求值表达式
【学习笔记之我要C】求值表达式
84 0
|
算法 Java C++
【27. 表达式求值(中缀表达式)】
表达式求值(中缀) **前提准备** 需要开辟`俩个栈`,一个用于`存放数字`,另一个用于`存放运算符`。 需要用到`unordered_map`用来存放`运算符的优先级`。
214 0
【27. 表达式求值(中缀表达式)】