c++primer 第4章 表达式

news2024/12/26 22:47:32

文章目录

  • 第4章 表达式
    • 4.1 基础
      • 4.1.1 基础概念
      • 4.1.2 优先级与结合律
      • 4.1.3 求值顺序
    • 4.2 算术运算符
    • 4.3 逻辑和关系运算符
    • 4.4 赋值运算符
    • 4.5 递增和递减运算符
    • 4.6 成员访问运算符
    • 4.7 条件运算符
    • 4.8 位运算符
    • 4.9 sizeof运算符
    • 4.10 逗号运算符
    • 4.11 类型转换
      • 4.11.1 算术转换
      • 4.11.2 其他隐式类型转换
      • 4.11.3 显式转换
    • 4.12 运算符优先级表
    • 小结
    • 术语表

第4章 表达式

  • 表达式由运算对象组成 对表达式求值得到一个结果
  • 最简单的表达式:字面值和变量
  • 复杂表达式:将一个运算符和一个或多个运算对象组合

4.1 基础

4.1.1 基础概念

  • 一元/二元/三元运算符 某些符号元数由上下文决定
  • 组合运算符和运算对象
    • 优先级 结合律 求值顺序
  • 运算对象转换
    • 运算对象转换为同一种类型
    • 整数↔浮点数 ,但指针不能转换为浮点数
    • 小整数类型通常会被提升为较大的整数类型
  • 重载运算符
    • 当运算符作用在类类型的运算对象时,用户可以自行定义其含义。为已存在运算符赋予另外一层含义
    • 重载时 运算对象/返回值类型由运算符定义 但运算对象个数/运算符优先级/结合律无法改变
  • 左值和右值
    • C: 左值可以位于赋值语句左边,右值则不能
    • C++:右值:用的是对象的值(内容);左值:用的是对象的身份(在内存中的位置)
    • 右值可以由左值代替 反之不行
    • 需要用到左值的运算符
      • 赋值运算符 左侧运算对象
      • 取地址符作用于左值运算对象
      • 内置解引用/下标运算符 迭代器解引用 string/vector下标运算符 的求值结果均为左值
      • 内置类型/迭代器的递增递减运算符作用于左值运算对象 前置版本所得结果也是左值
    • 关键字decltype
      • 作用于求值结果是左值的表达式 得到的是引用类型
      • int *p; decltype(*p)->int&//解引用生成左值 得到类型为引用
      • int *p; decltype(&p)->int**//取地址符生成右值 结果为一个指向指针的指针

4.1.2 优先级与结合律

  • 复合表达式 含有两个或多个运算符的表达式
  • 优先级和结合律决定了运算对象组合的方式 括号(优先运算)无视上述规则
    • 高优先级运算符的运算对象要比低优先级的运算对象更为紧密地结合在一起
    • 如果优先级相同 组合规律由结合律确定
  • 括号无视优先级和结合律
  • 优先级和结合律 影响程序的正确性

4.1.3 求值顺序

  • 不会明确指定求值的顺序,如int i = f1() + f2();不能确定是先调用f1还是f2
  • 对于没有指定执行顺序的运算符来说,如果表达式指向并修改了同一个对象,将会引发错误并产生未定义的行为
  • 4种明确规定运算对象求值顺序的运算符
    • 逻辑与&& 先求左侧运算对象为真才继续求右侧运算对象(短路求值)
    • 逻辑或|| 先求左侧运算对象为假才继续求右侧运算对象(短路求值)
    • 条件运算符 ?:
    • 逗号运算符 ,
  • 求值顺序 优先级 结合律
    • 求值顺序与优先级和结合律无关
    • f()+g()*h()+j();
      • 优先级规定 g()的返回值和h()的返回值相乘
      • 结合律规定 f()的返回值先与g()和h()的乘积相加,所得结果再与j()的返回值相加
      • 对于这些函数的调用顺序没有明确规定 若fghj无关不会改变同一对象状态也不执行IO则函数调用顺序不受限制;若影响同一对象,则是一条错误的表达式,将产生未定义的行为
  • 处理复合表达式
    • 拿不准最好加括号来强制使表达式组合关系符合程序逻辑
    • 若改变了某个运算对象的值,在表达式的其他地方不要再使用该运算对象(例外*++iter,递增运算必须先求值 然后才轮到解引用)
  • c++未明确规定大多数二元运算符的求值顺序给编译器优化留下了余地,该策略实际上是在代码生成效率和程序潜在缺陷之间间进行权衡

4.2 算术运算符

在这里插入图片描述

  • 优先级由高到低:一元运算符 乘法和除法 加法和减法,优先级高的运算符比低的更紧密,上述都满足左结合律,当优先级相同时按照从左向右的顺序进行组合
  • 算术运算符都能作用于任意算术类型 以及任意能转换为算术类型的类型
  • 算数运算符的运算对象和求值结果都是右值
  • 表达式求值前小整数运算对象都被提升为较大的整数类型 所有运算对象最终都会转换成同一类型
  • 一元正号运算符 加法运算符 减法运算符都能作用于指针 (二元加法减法)
  • 一元正号运算符作用于一个指针或者算数值时 返回运算对象值一个(提升后的)副本
  • 布尔值不应该参与运算 对被提升为int型 对其求负true的仍然为true bool b=true; bool b2=-b;//b2为true 因b被提升为1,-b为-1不为零仍是true
  • 算术表达式有可能产生未定义的结果原因
    • 数学性质本身 如除数是0
    • 计算机特点 如溢出 计算的结果超出该类型所能表示的范围时就会产生溢出
  • + - * / 整数相除结果还是整数 若商含有小数部分则直接舍弃
  • %取余/取模运算符 参与取余运算的运算对象必须是整数类型
  • /除法运算 两运算对象符号相同则商为正 否则商为负
  • &取余运算 如m%n若值不为零则符号与m相同
  • (-m)/nm/(-n)都等价于-(m/n)m%(-n)等价于m%n(-m)%n等价于-(m%n)

4.3 逻辑和关系运算符

在这里插入图片描述

  • 关系运算符作用于 算术类型或指针类型 返回值为布尔类型
  • 逻辑运算符作用于 任意能转换为布尔值的类型 返回值为布尔类型
  • 以上两类运算符求值结果都是右值
  • 逻辑与和逻辑或运算符 都是先求左侧运算对象的值再求右侧
    • 逻辑与&& 全真为真 其余为假 左侧为真才求右侧
    • 逻辑或|| 全假为假 其余为真 左侧为假才求右侧
    • 短路求值:当且仅当左侧运算对象无法确定表达式的结果时才会计算右侧运算对象的值
  • 声明为引用类型可以避免对元素的拷贝,如不需写操作可声明为常量的引用
  • 逻辑非运算符
    • ! 将运算对象的值取反后返回
  • 关系运算符
    • 比较运算对象的大小并返回布尔值 满足左结合律
    • 不要连写关系运算符 如if(i<j<k)是拿i<j的布尔值结果与k比较;正确应该写为if(i<j&&j<k)
  • 相等性测试与布尔字面值
    • 测试一个算数对象或指针对象的真值 最直接方法是将其作为if语句的条件 如if(val){...}//任意非零值为真if(!val){...}//val为零值为真
    • 进行比较运算时除非比较的对象是布尔类型 否则不要使用字面值true和false作为运算对象如if(val==true)若val不是布尔类型会变为if(val==1)(false会转换为0),若要进行值比较应直接写1而不是true

4.4 赋值运算符

  • 赋值运算 左侧运算对象必须是一个可修改的左值 其的结果是它的左侧运算对象 是一个左值 类型就是左侧对象的类型,如果赋值运算的左右侧运算对象类型不同,则右侧运算对象将转换成左侧运算对象的类型
  • 右侧运算对象 允许使用花括号括起来的初始值列表;若左侧运算对象是内置类型,则初始化列表最多包含一个值 即使转换所占空间也不应该大于目标类型;无论左侧运算对象啊是什么类型,初始值列表都可以为空,编译器创建一个值初始化的临时量赋给左侧运算对象
  • 赋值运算符满足右结合律
    • 赋值返回的是其左侧运算对象
    • 多重赋值中每一对象 类型或者与右边对象的类型相同 或可由右边对象的类型转换得到
    • (不能将指针的值赋给int)
  • 赋值运算优先级比较低
    • 赋值部分加上括号
    • (低于关系运算符优先级) 所以加括号这样写while((i=get_value)!=42)
  • 切勿混淆相等运算符和赋值运算符 == =
  • 复合赋值运算符
    • 等价于 a=a op b;但复合运算符只求值一次,普通运算符求值两次

4.5 递增和递减运算符

  • 前置版本j = ++i,求值结果为改变后的对象
  • 后置版本j = i++,求值结果为运算对象改变之前的那个值的副本
  • 两者均须作用于左值运算对象
  • 除非必须 否则不使用递增递减运算符的后置版本(比前置多一步存储原始值)
  • 在一条语句中混用解引用和递增运算符
    • 既想变量加一减一又能使用它原来的值 则可以使用后置版本
    • auto pbeg=v.begin(); while(pbeg!=v.end() && *pbeg>=0){cout<<*pbeg++<<endl;} 后置递增运算符优先级高于解引用 故*pbeg++等价于*(pbeg++)
  • 运算对象可按任意顺序求值
    • 复合表达式多个地方改变同一个对象的值时求值顺序很关键,因为递增递减会改变运算对象的值,所以要提防在复合表达式中错用这两个运算符

4.6 成员访问运算符

  • 点运算符 获取类对象的一个成员 成员对象是左值结果为左值 成员对象是右值结果为右值
  • 箭头运算符 作用于指针类型运算对象 结果为左值 ptr->mem等价于(*ptr).mem
  • 解引用*运算符优先级低于点运算符.,须加括号

4.7 条件运算符

  • 条件运算符(?:if-else逻辑嵌入到单个表达式中去 cond? expr1: expr2
  • 先求cond的值 条件为真返回expr1 条件为假返回expr2 只对expr1和expr2中的一个求值
  • 当条件运算符的两个表达式都是左值或者能转换为同一种左值类型时 运算结果是左值 否则运算结果是右值
  • 嵌套条件运算符
    • 右结合律 按照从右向左的顺序组合 靠右边的条件运算构成靠左边的条件运算的:分支
    • 嵌套多了可读性下降 最好别超过两到三层
  • 在输出表达式中使用条件运算符
    • 条件运算符优先级非常低 记得加括号

4.8 位运算符

在这里插入图片描述

  • 作用于整数类型运算对象 将对象看成二进制位的集合 提供检查和设置二进制位的功能
  • 小整型自动提升为较大的整型 运算对象有/无符号的都可;若带符号负数 左移操作可能会改变符号位的值
  • 符号位的处理无明确规定 建议仅将位运算用于处理无符号类型
  • 移位运算符
    • 二进制位向左移(<<)(在右侧插入值为0的二进制位)或者向右移(>>)(无符号 在左侧插入值为0的二进制位;有符号 在左侧插入符号位的副本或者值为0的二进制位 视具体情况),左侧运算对象内容按照右侧运算对象的要求移动指定位数,移出边界外的位就被舍弃掉
  • 位求反运算符
    • (~) 将运算对象逐位求反后生成一个新址 1->0 0->1
    • char提升为int 提升时运算对象原来的位保持不变 往高位添加0即可
  • 位与 位或 位异或 运算符
    • &| 异或^ 两运算对象上逐位执行相应的逻辑操作
    • & 全1为1 其余为0
    • | 全0为0 其余为1
    • 异或^ 相异(对应位置有且仅有一个为1)为1 相同为0
    • 不要将位运算符和逻辑运算符搞混 如位与& 位或| 位求反~和逻辑与&& 逻辑或|| 逻辑非!
  • 使用位运算符
    • 测试是否通过 位或某一位设为0其余位设为1 只改变其中一位 其他位不变
  • 移位运算符(又叫IO运算符)满足左结合律
    • 重载优先级和结合律与内置版本一样
    • 优先级不高不低 比算术运算符优先级低 比关系运算符、赋值运算符、条件运算符优先级高,一次使用多个运算符有必要适当加括号

4.9 sizeof运算符

  • sizeof运算符返回一条表达式或一个类型名字所占的字节数 满足左结合律
      1. sizeof (type) 类型名
      1. sizeof expr 表达式
  • 所得值的类型是 size_t类型的常量表达式, sizeof返回表达式类型结果,并不实际计算其运算对象的值(sizeof *P等价于sizeof (*P),因为不实际计算其运算对象的值,即使P是一个无效(未初始化)的指针也安全,指针并未被真正使用,不需真的解引用也能知道它所指对象的类型)
  • 允许使用作用域运算符来获取类成员的大小,无需提供具体对象因为想知道类成员大小无须真的获取该成员
  • 结果部分依赖于作用的类型
    • char类型/表达式 结果为1
    • 引用类型 被引用对象所占空间大小
    • 指针 指针本身所占空间大小
    • 解引用指针 指针所指对象所占空间大小 指针不需有效
    • 数组 整个数组所占内存空间大小 等价与每个元素sizeof值之和 sizeof不会将数组转换为指针来处理
      • 可以用数组大小除以单个元素的大小得到数组元素个数
      • 因为sizeof返回值是常量表达式 可用于声明数组维度
// sizeof(ia)/sizeof(*ia)  返回整个数组所占空间的大小/返回数组的大小
constexpr size_t sz = sizeof(ia)/sizeof(*ia);
int arr2[sz];//返回值是常量表达式 可用于声明数组维度
  • string vector 返回类型固定部分大小 不会计算对象元素占用空间

4.10 逗号运算符

  • (,)含有两个运算对象,从左向右依次求值
  • 规定运算对象顺序 先求左侧,将左侧求值结果丢弃,逗号运算符真正结果是右侧表达式的值。如果右侧运算符是左值,那么最终的求值结果也是左值。

4.11 类型转换

  • 如果两种类型可以相互转换 那么它们就是关联的
  • 隐式类型转换:
    • c++根据类型转换规则将运算对象的类型统一(自动执行)后再求值
    • 尽可能避免损失精度 如同时有整型和浮点型运算,整型会转换为浮点型
  • 何时发生隐式类型转换
    • 大多数表达式 比 int类型小的整数值先提升为较大的整数类型
    • 条件 非布尔转换成布尔
    • 初始化 初始值转换成变量的类型;赋值 右侧转换为左侧类型
    • 算术运算或者关系运算的运算对象有多种类型 要转换成同一种类型
    • 函数调用时也发生类型转换

4.11.1 算术转换

  • 把一种算术类型转换为另外一种算术类型
    • 运算符的运算对象将转换为最宽的类型
    • 表达式中既有浮点型也有整型时 整型将转换为相应的浮点类型
  • 整型提升
    • 将较小的整数类型转换为较大的整数类型 bool/char/signed char/unsigned char/short/unsigned short等可能存在int里提升为int
    • 较大的char类型(wchar_t/char16_t/char32_t)提升为int/unsigned int/long/unsigned long/long long/unsigned long long中的一种,前提:转换后的类型要能容纳原类型所有可能的值
  • 无符号类型的运算对象
    • 转换结果依赖于机器中各个整数类型的相对大小
    • 先整型提升 若结果类型匹配则无需进一步的转换
    • 若都是带符号/无符号 则小类型运算对象转换为大类型运算对象
    • 若一个带符号 一个不带符号
      • 无符号不小于带符号 则带符号转换为无符号
      • 带符号大于无符号 转换结果依赖于机器
        • 若无符号所有值都能存在该带符号类型中,则无符号类型运算对象转换为带符号
        • 若不能 则带符号运算对象转换为无符号类型
  • 理解算术转换
    • 研究大量的例子
      在这里插入图片描述

4.11.2 其他隐式类型转换

  • 数组转换为指针(指向数组首元素的指针)
    • 当数组被用作decltype关键字 或作为取地址符(&)、sizeof及typeid等运算对象时上述转换不会发生
    • 如果用一个引用来初始化数组时上述转换也不会发生
    • 在表达式中使用函数类型时会发生类似指针转换
  • 指针的转换
    • 常量整数值0/字面值nullptr 能转换为任意指针类型
    • 指向任意非常量的指针能转换为void*
    • 指向任意常量的指针能转换为const void*
  • 转换为布尔值
    • 算术类型/指针类型->布尔类型
    • 0->false;否则->true
  • 转换为常量
    • 能将指向类型T的指针或者引用分别转换成指向const T的指针或引用
    • 不允许const转换为非常量 因为它试图删除底层const
  • 类类型定义的转换
    • 能定义由编译器自动执行的转换 每次只能执行一种类类型转换
//字面值转string
string s,t="a value";
//cin转 布尔值
while(cin>>s);
//最后一次读入成功 转换的布尔值是true
//不成功 布尔值是false

4.11.3 显式转换

  • 显示的将对象强制转换为另外一种类型
  • 命名的强制类型转换
    • cast-name<type>(expression);
    • static_cast、const_cast、dynamic_cast、reinterpret_cast
    • dynamic_cast:
      • 支持运行时类型识别
    • static_cast:
      • 任何具有明确定义的类型转换,只要不包含底层const,都可以使用
      • 利用static_cast找回存在于void*指针中的值,应确保指针的值保持不变,强制转换结果与原地址值相等,须确保转换后所得类型就是指针所指的类型,类型一旦不符,将产生未定义的后果
    • const_cast:(常用于有函数重载的上下文中)
      • 只能改变运算对象的底层const,将常量对象转换为非常量对象的行为一般称为去const性质
      • 如果运算结果对象本身不是一个常量 使用强制类型转换获取写权限是合法行为
      • 如果运算结果对象本身是一个常量 再使用const_cast强制类型写操作就会产生未定义的行为
      • const_cast只能改变表达式的常量属性,使用其他类型的命名强制类型转换改变表达式的常量属性都将引发编译器错误;同样,也不能用const_cast改变表达式的类型
    • reinterpret_cast:
      • 通常为运算对象的位模式提供低层次上的重新解释
      • 使用reinterpret_cast非常危险,本质上依赖机器,想安全使用reinterpret_cast必须对涉及的类型和编译器实现转换的过程都非常了解
      • 例子
    int *ip;
    char *pc=reinterpret_cast<char*>(ip);
    //牢记pc指向的真实对象是一个int而非字符,不能将其当普通字符指针使用
    
    • 建议:避免强制类型转换
      • 干扰正常类型检查
      • 每次书写一条强制类型转换都应反复斟酌能否以其他方式实现相同的目标
      • 实在无法避免 也应尽量限制类型转换值的作用域 记录对相关类型的所有假设可以减少错误发生的机会
  • 旧式强制类型转换
    • 早期c++显示进行强制类型转换
    • type (expr);//函数类型强制类型转换
    • (type) expr;//c语言风格强制类型转换
    • 若旧式强制类型转换转换为static_cast、const_cast也合法,则其行为与对应的命名转换一致;若替换后不合法则执行与reinterpret_cast类似的功能
    • 与命名的强制类型转换先比旧式强制类型转换不那么清晰明了容易被看漏

4.12 运算符优先级表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

小结

  • 运算符作用于内置类型运算对象所执行的操作,支持运算符重载,允许我们自己定义运算符作用于类类型时的含义
  • 对含超一个运算符的表达式 要理解优先级、结合律、求值顺序
    • 每一个运算符都有对应的优先级和结合律
      • 优先级规定复合表达式中运算符组合的方式
      • 结合律说明当运算符的优先级一样时应该如何组合
    • 大多数运算符不规定运算对象的求值顺序
      • 若两运算对象指向同一个对象并且其中一个改变了对象的值,会导致程序出现缺陷
  • 运算对象经常从原始类型自动转换为某种关联类型,还可显示进行强制类型转换

术语表

  • 左值:求值对象结果为对象或函数的表达式。一个表示对象的非常量左值可以作为赋值运算符的左侧运算对象
  • 右值:一种表达式,其结果是值而非值所在的位置
  • 求值顺序:运算对象一定要在运算符之前得到求值结果。但只有&&、||、条件、逗号4中运算符规定了求值顺序
  • 优先级:高优先级的运算符结合得更紧密
  • 短路求值:描述&&、||运算符的执行过程。如果根据运算符的第一个运算对象就能确定整个表达式的结果,求值终止,此时第二个运算对象将不会被求值
  • size_of:返回储存对象(类型可能为某个给定类型名字也可能由表达式的返回结果确定)所需字节数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/126093.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ES6-ES11笔记(1)

关于这个视频的笔记 (https://www.bilibili.com/video/BV1uK411H7on?p29&vd_source3cf72bb393b8cc11b96c6d4bfbcbd890) 1.ES6 1.1let的一些注意点 let a; let b,c,d; let e 100; let f"你好",g101;// 变量名不能重复声明 // let testDepulicate 123456 // …

无信息变量消除法研究及实现(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 波长变量筛选的方法主要有相关系数法&#xff0c;逐步回归法&#xff0c;无信息变量消除法(UVE)&#xff0c;遗传算法(genetic …

python圣诞树词云

一、前言 圣诞节虽然是西方节日&#xff0c;但是个人还是比较喜欢的&#xff08;没有崇洋媚外的意思&#xff0c;中国的春节也超级棒&#xff09;&#xff0c;一个是圣诞节的氛围&#xff0c;圣诞节的圣诞老人等象征、雪花麋鹿等元素&#xff0c;都充满了浪漫的氛围。我想这也是…

Linux的文件系统编程(1)

What makes the desert beautiful is that somewhere it hides a well. 沙漠之所以美丽,是因为在它的某个角落隐藏着一口井. Linux的文件系统编程&#xff08;1&#xff09;运行过程框架标准IO和文件IO标准IO文件IO(主要学)open函数两个参数三个参数close函数read函数write函数…

Python基础语法(二)

Python基础语法&#xff08;二&#xff09; 函数 编程中的函数和数学中的函数有一定的相似之处. 数学上的函数, 比如 y sin x , x 取不同的值, y 就会得到不同的结果. 编程中的函数, 是一段 可以被重复使用的代码片段 . 代码示例: 求数列的和, 不使用函数 # 1. 求 1 - 100 …

树Tree【代码笔记】

树【Tree】 树是n&#xff08;n>0&#xff09;个结点的有限集。当n 0时&#xff0c;称为空树。在任意一棵非空树中应满足&#xff1a; 有且仅有一个特定的称为根的结点。当n>1时&#xff0c;其余节点可分为m&#xff08;m>0&#xff09;个互不相交的有限集T1,T2,……

OpenHarmony#深入浅出学习eTs#(六)编写eTs第一个控件

本项目Gitee仓地址&#xff1a;深入浅出eTs学习: 带大家深入浅出学习eTs (gitee.com) 一、控件基本属性 在使用第一个控件前&#xff0c;我们需要了解一些控件都有哪些基础属性&#xff0c;比如说我们在Super Visual中使用过的长宽和字体大小等等&#xff0c;通用属性有以下这…

Retrofit的使用

文章目录Retrofit的使用最好用的网络库: RetrofitRetrofit的基本用法处理复杂接口的地址类型Retrofit构建器的最佳写法Retrofit的使用 最好用的网络库: Retrofit Retrofit是一款由Square公司开发的网络库,但是它和OkHttp定位完全不同,OkHttp的侧重点是底层通信的实现,而Retro…

Java集合类——LinkedList(单链表及双链表)

一&#xff0c;ArrayList的缺陷 1.空间浪费 在之前的博客中&#xff0c;我利用源码详细的讲解了ArrayList这个集合类&#xff08;尤其是扩容机制&#xff09;&#xff0c;可以知道ArrayList的底层主要是一个动态的可变数组&#xff0c;容量满的时候需要进行1.5倍扩容。但是我…

第二十讲:神州路由器静态路由的配置

实验拓扑图如下所示 设备 端口 IP 子网掩码 网关 Router-A G0/0 120.83.200.55 255.255.255.0 无 G0/3 192.168.0.1 255.255.255.0 无 Router-B G0/0 120.83.200.56 255.255.255.0 无 G0/3 192.168.1.1 255.255.255.0 无 PC1 192.168.0.2 255.255.255…

jQuery 的基本使用

1、jQuery 介绍 1.1、JavaScript 库 JavaScript库&#xff1a;即 library&#xff0c;是一个封装好的特定的集合&#xff08;方法和函数&#xff09;。从封装一大堆函数的角度理解库&#xff0c;就是在这个库中&#xff0c;封装了很多预先定义好的函数在里面&#xff0c;比如动…

【C++】const关键字

【C】const关键字 0x1 常量 C定义常量有两种方式 #define 宏常量&#xff1a;#define 常量名 常量值 通常在文件上方定义&#xff0c;表示一个常量宏常量不可以修改 // 宏常量 #define MAX 999int main() {return 0; }const修饰的变量&#xff1a; const 数据类型 常量名 …

docker 安装Es

1、下载镜像文件 docker pull elasticsearch:7.4.2 存储和检索数据 docker pull kibana:7.4.2 可视化检索数据 2、创建实例 1、ElasticSearch mkdir -p /mydata/elasticsearch/config mkdir -p /mydata/elasticsearch/data echo "http.host: 0.0.0.0" >…

第三十六章 数论——容斥原理

第三十六章 数论——容斥原理一、容斥原理1、定理内容二、代码模板1、问题&#xff08;1&#xff09;如何求出能够被整除的个数&#xff1f;&#xff08;2&#xff09;如何枚举出2n−12^n-12n−1种情况&#xff1f;2、代码实现&#xff1a;一、容斥原理 1、定理内容 我们在高…

开启微信小程序的学习窗口(第一课)

第一个问题 什么是微信小程序 微信小程序&#xff0c;小程序的一种&#xff0c;英文名Wechat Mini Program&#xff0c;是一种不需要下载安装即可使用的应用&#xff0c;它实现了应用“触手可及”的梦想&#xff0c;用户扫一扫或搜一下即可打开应用。 全面开放申请后&#xff0…

Educational Codeforces Round 93 (Rated for Div. 2) K. Lonely Numbers

Problem - C - Codeforces 翻译&#xff1a; 给定一个数组&#x1d44e;1&#xff0c;&#x1d44e;2&#xff0c;…&#xff0c;&#x1d44e;&#x1d45b;&#xff0c;由0到9的整数组成。一子数组&#x1d44e;&#x1d459;,&#x1d44e;&#x1d459; 1,&#x1d44e;&…

R实战 | 置换多元方差分析(以PCoA的PERMANOVA分析为例)

adonis-cover置换多元方差分析&#xff08;Permutational multivariate analysis of variance&#xff0c;PERMANOVA&#xff09;&#xff0c;又称非参数多因素方差分析&#xff08;nonparametric multivariate analysis of variance&#xff09;、或者ADONIS分析。它利用距离矩…

第003课 - 分布式基础概念

文章目录 集群、分布式、节点远程调用负载均衡服务注册/发现和注册中心服务熔断和降级API网关我们以前将所有的代码、页面、sql语句,写到一个应用,如果有一个地方有问题,整个就不可用了。 我们可以基于业务边界进行服务微化和拆分。 如果有一个出现了问题,不影响其他服务…

迅为LS2K0500开发板龙芯全国产处理器LoongArch架构核心主板

全国产开发板&#xff1a; 迅为iTOP-LS2K0500开发采用龙芯LS2K0500处理器&#xff0c;基于龙芯自主指令系统&#xff08;LoongArch&#xff09;架构&#xff0c;片内集成64位LA264处理器核、32位DDR3控制器、2DGPU、DVO显示接口、两路PCle2.0、两路SATA2.0、四路USB2.0、一路US…

梯度下降算法、随机梯度下降算法、动量随机梯度下降算法、AdaGrad算法、RMSProp算法、Adam算法详细介绍及其原理详解

相关文章 梯度下降算法、随机梯度下降算法、动量随机梯度下降算法、AdaGrad算法、RMSProp算法、Adam算法详细介绍及其原理详解反向传播算法和计算图详细介绍及其原理详解 文章目录相关文章前言一、回归拟合问题二、损失函数三、梯度下降算法四、随机梯度下降算法五、动量随机梯…