表达式求值

简介: 目录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,但在不同编译器下数值不一样,编译器紊乱
//总结:我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的。


相关文章
|
6月前
三元表达式使用
三元表达式使用
57 0
|
6月前
|
编译器 C++
C++系列七:表达式
C++系列七:表达式
|
6月前
Q表达式
Q表达式。
48 5
|
6月前
|
SQL 数据库 Python
F表达式
F表达式。
39 4
|
6月前
|
安全 C++ 开发者
c++表达式详细介绍
前言 表达式是 C++ 语言的基石之一,它们在程序中执行计算、赋值、逻辑判断和更多操作。本文旨在提供对 C++ 表达式各个方面的全面了解,包括基础概念、类型、求值规则以及高级主题。
134 0
|
C语言
【学习笔记之我要C】求值表达式
【学习笔记之我要C】求值表达式
70 0
|
编译器
【C++Primer】第4章:表达式
【C++Primer】第4章:表达式
119 0
【C++Primer】第4章:表达式
|
算法 Java C++
【27. 表达式求值(中缀表达式)】
表达式求值(中缀) **前提准备** 需要开辟`俩个栈`,一个用于`存放数字`,另一个用于`存放运算符`。 需要用到`unordered_map`用来存放`运算符的优先级`。
199 0
【27. 表达式求值(中缀表达式)】
|
Serverless vr&ar 容器
F#表达式求值
重点介绍如何用F#求表达式 ( a + x ) * b 的值
905 0
F#表达式求值