IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 第4章 表达式【C++】 -> 正文阅读

[C++知识库]第4章 表达式【C++】

第4章 表达式

什么是表达式?我可以简单地认为是需要运算的式子,官方的解释为表达式由一个或多个运算对象组成,对表达式求值将得到一个结果,字面值和变量是最简单的表达式,其结果就是字面值和变量的值。

基础

我们不必钻牛角尖,我们要通过实践向前看,通过实践一步步向前,当我们对整体有了解之后然后再回头来钻牛角尖、研究背后的道理。

基本概念

C++定义了一元运算符、二元运算符、三元运算符

//example1.cpp
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
    //运算符举例
    int i = 3;
    int *ip = &i;  //一元运算符&
    int j = i * 3; //二元运算符
    bool flag = false;
    i = flag ? 23 : 43; //因为falg为false则右边表达式计算结果为43
    cout << i << endl;  // 43
    /*
    state?return if state is true:return if state if false
    */
    return 0;
}

来其他运算,下面列举的有些我们已经在前面学过了,有些没有学习过

运算对象转换

也就是从一种类型转换到另一种类型,我们现在知道的有自动转换与强制转换,如果记得不太清楚可以翻到前面的章节进行回顾。

重载运算符

我们使用的cout<<中的<<就是对<<运算符的一种重载,但是我们现在不进行讨论,不然初学者或者小白肯定会懵逼的哦,后面我们会慢慢接触到的。

左值和右值

表达式可以分为左值和右值,左值可以位于赋值语句的左侧,右值不能。

优先级与结合律

复合表达式是指含有两个或者多个运算符的表达式,表达式通过运算方式连接在一起

//example2.cpp
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
    int i = 6 + 3 * 4 / 2 + 2;
    cout << i << endl; // 14
    //程序上是怎样处理的呢
    int j = (6 + ((3 * 4) / 2) + 2);
    //这是上面复合表达式中运算符中的运算优先级
    cout << j << endl; // 14

    //我们可以自己使用括号来达到我们特定的效果
    int k = 1 + 2 * 3;
    cout << k << endl; // 7
    k = (1 + 2) * 3;
    cout << k << endl; // 9

    //应用举例
    int arr[] = {9, 1, 2, 3, 4};
    cout << *(arr + 4) << endl; // 4
    cout << *arr + 4 << endl;   // 13
    //在*arr+4中 *先于arr结合使用然后得到结果在参与+的运算
    return 0;
}

求值顺序

运算符的优先级规定了运算对象的组合方式,但还有一点就是一个复合表达式中它们的计算顺序是怎样的

对于

f()+g()*h()+j()

对其规范地解释为,优先级规定g()与h()相乘,结合律规定,f()的返回值先与g()和h()的乘积相加,所得结果再与j()的返回值相加,对这些函数调用顺序没有明确规定。

C++没有明确指明大多数二元运算符左右表达式的运算顺序,但是在大多数编译器中都是从左到右的

举例代码

//example3.cpp
#include <iostream>
using namespace std;
int f1();
int f2();

int global_int = 1;

int main(int argc, char **argv)
{
    int i = f1() + f2(); // 3 + 6
    //在初始化i是右边的表达式f1()+f2()它们的执行顺序是怎样的呢
    cout << i << endl;
    // f1 excute gloal->2
    // f2 excute gloal->4
    // 9
    //可见是从左到右执行,当f1执行得到结果后才会向后计算

    cout << (f1() * 3 + (f2() * 3)) << endl;
    // f1 excute gloal->5
    // f2 excute gloal->7
    // 45
    //为什么?因为在此表达式中f1()*3的优先级与(f2()*3)相同
    //二者会按照谁在前谁先执行

    cout << f1() + f2() * 3 << endl;
    // f1 excute gloal->8
    // f2 excute gloal->10
    // 45
    //同理f1()与f2()*3同优先级,按照现后顺序执行
    cout << f2() * 3 + f1() << endl;
    // f2 excute gloal->12
    // f1 excute gloal->13
    // 56
    //但是C++没有明确指明大多数二元运算符左右表达式的运算顺序,但是在大多数编译器中都是从左到右的
    //也就是从C++的规定上,我们不知道f2()*3先执行还是f1()先执行
    return 0;
}
int f1()
{
    global_int += 1;
    cout << "f1 excute gloal->" << global_int << endl;
    return 1 + global_int;
}
int f2()
{
    global_int += 2;
    cout << "f2 excute gloal->" << global_int << endl;
    return 2 + global_int;
}

算数运算符

算术运算符有

+   一元正号     + expr
-   一元负号     - expr
*   乘法         expr * expr
/   除号         expr / expr
%   求余         expr % expr
+   加号         expr + expr
-   减法         expr - expr

关于它们的优先级,一元运算符优先级最高,其次是乘法和除法,优先级最低的为加减法,算术运算符满足结合律,当优先级相同时按照从左向右的顺序进行组合

//example4.cpp
#include <iostream>
#include <climits>
using namespace std;
int main(int argc, char **argv)
{
    int num1 = -199;
    bool num2 = NULL; // NULL等价于0,false等价于0
    int num3 = -num2;
    cout << num1 << " " << num2 << " " << num3 << endl; //-199 0 0

    //我们要注意在算数运算时要注意防止数据溢出的情况
    int num4 = INT_MAX;
    cout << num4 << endl; // 2147483647
    num4 = num4 + 1;
    cout << num4 << endl; //-2147483648
    return 0;
}

limits头文件

可见我们上面有用到一个新的头文件,climits在C语言中为limits.h,其内有宏定义各个基本类型的标识范围,不要恐惧,这些玩意根本不是让人记忆的,我们要知道有这么回事,在由于语法提示的编辑器内写代码,一敲不就出来了吗,但是我们要知道它们是做什么的,随着我们对知识的掌握,我们在回过头研究它们的表示范围为什么是这样,这就是计算机编码的范畴了同样也属于计算机组成原理内的重要知识

//example5.cpp
#include <iostream>
#include <climits>
using namespace std;
int main(int argc, char **argv)
{
    // char
    cout << CHAR_MIN << endl; // -128
    cout << CHAR_MAX << endl; // 127

    // signed char
    cout << SCHAR_MIN << endl; // -128
    cout << SCHAR_MAX << endl; // 127

    // unsigned char
    cout << UCHAR_MAX << endl; // 255

    // short
    cout << SHRT_MIN << endl; // -32768
    cout << SHRT_MAX << endl; // 32767

    // unsigned short
    cout << USHRT_MAX << endl; // 65535

    // int
    cout << INT_MAX << endl; // 2147483647
    cout << INT_MIN << endl; //-2147483648

    // unsigned int
    cout << UINT_MAX << endl;

    // long
    cout << LONG_MAX << endl; // 2147483647
    cout << LONG_MIN << endl; //-2147483648

    // unsigned long
    cout << ULONG_MAX << endl; // 4294967295

    // unsigned long long
    cout << ULONG_LONG_MAX << endl; // 18446744073709551615

    // longlong
    cout << LONG_LONG_MAX << endl; // 9223372036854775807
    cout << LONG_LONG_MIN << endl; //-9223372036854775808

    // float
    cout << __FLT_MANT_DIG__ << endl;   // 24 尾数
    cout << __FLT_DIG__ << endl;        // 6 最少有效数字位数
    cout << __FLT_MIN_10_EXP__ << endl; //-37 带有全部有效数的float类型的负指数的最小值(以10为底)
    cout << __FLT_MAX_10_EXP__ << endl; // 38 float类型的正指数的最大值(以10为底)
    cout << __FLT_MIN__ << endl;        // 1.17549e-038 保留全部精度的float类型正数最小值
    cout << __FLT_MAX__ << endl;        // 3.40282e+038 float类型正数最大值
    return 0;
}

除法与求余

下面我们在看一看我们不太熟悉的算术运算符
在注意的一点是求余运算不支持左右表达式为浮点型,也就是只支持整数求余算数运算

//example6.cpp
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
    //对于加减法在此不再举例,我们在上面小结已经有了了解
    //我们来看两个比较特殊的算数 除法与求余
    int num1 = 21 % 5;
    int num2 = 3 % 2;
    int num3 = 9 % 3;
    cout << num1 << " " << num2 << " " << num3 << endl; // 1 1 0
    //明白怎么回事了吧,就是我们计算整数除法,那个余数啊,不会怕这都不知道这是小学的只是啊
    //没关系我们把它学会的就好了

    //还有特殊的地方为整数的除法
    float num4 = 4 / 3;
    cout << num4 << endl;         // 1
    cout << (float)4 / 3 << endl; // 1.33333
    cout << 4.f / 3 << endl;      // 1.33333
    //可见在整数除法中,除到不可除就不再计算了,也就是得到了整数部分 剩下的余数进行了舍弃
    //解决办法就是将expr / expr 上下的数值至少一个为浮点型,然后用浮点型变量存储起来
    return 0;
}

负数求余

被除数与除数有负数时进行求余运算时,结果是怎样的呢?

  • m%(-n) 等于 m%n
  • (-m)%n 等于 -(m%n)
  • (-m)%(-n)=-(m%n)

简单可以记住,求余的结果的正负号有%符号左边的正负号决定

代码举例

//example7.cpp
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
    cout << -4 % 3 << endl;  //-1
    cout << 4 % -3 << endl;  // 1
    cout << -4 % -3 << endl; //-1
    //这都是怎么回事
    //计算规则是这样的
    // m%(-n) 等于 m%n
    //(-m)%n 等于 -(m%n)
    //对于(-m)%(-n)怎么解释呢
    //(-m)%(-n) 等于 -(m%(-n))
    //又(m%(-n))等于m%n
    //则(-m)%(-n)=-(m%n)
    return 0;
}

逻辑和关系运算符

填坑中

赋值运算符

填坑中

递增和递减运算符

填坑中

成员访问运算符

填坑中

条件运算符

填坑中

位运算符

填坑中

sizeof运算符

填坑中

逗号运算符

填坑中

类型转换

填坑中

运算符优先级表

填坑中

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-30 08:30:43  更:2022-04-30 08:30:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:42:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码