4.表达式

本文详细介绍了C++中的表达式概念,包括左值与右值的区别,以及它们在赋值运算、取地址符、解引用运算符等场景中的应用。同时,文章阐述了类型转换的重要性,分为隐式转换和强制类型转换,举例说明了何时会发生隐式类型转换,如在算术运算、函数调用、初始化和赋值过程中。强调了隐式类型转换的常见情况,如整型提升、非布尔值转布尔、数组转指针等,并提醒了强制类型转换的风险。
摘要由CSDN通过智能技术生成

表达式

表达式一个或多个运算对象组成,对表达式求值将得到一个结果字面值变量是最简单的表达式,其结果就是字面值变量的值,把一个运算符和一个或多个运算对象组合起来可以生成较复杂的表达式。表达式求值结果要么是左值,要么是右值

1.左值和右值

C++的表达式要然是右值,要不然是左值比较容易忽略的一点是,变量是左值,字面常量是临时量属于右值。左值是持久的,右值是短暂的。

一个左值表达式的求值结果是一个对象或者一个函数。 以常量对象为代表的某些左值不能作为赋值语句的左侧运算对象。某些表达式求值结果是对象,但它们是右值而不是左值。但一个表达式的求值结果是一个对象,此时这个对象可能是左值也可能是右值,判断这个对象到底是左值还是有值可以得出一个简单的归纳:当这个对象被用作右值的时候,用的是对象的值;当这个对象被用作左值的时候,用的是这个对象的身份。

int a,b;
a=5;     //a是左值
b=a;     //a是右值

不同的运算符对运算对象的要求不同,有的需要左值,有的需要右值;运算符的返回值也有差异,有的得到左值结果,有的得到右值结果。在需要右值的地方可以用左值来替代,但在用到左值的地方不能用右值来替代。

几个熟悉的用到左值的运算符:

  • 变量:变量可以看作只有一个运算都没有的表达式,变量其实是一个左值

  • 赋值运算符需要一个左值(左值结果是个对象)作为其左侧运算对象返回的结果仍然是一个左值

如:a=b=1;等价于(a=b)=1;a=b返回的结果是a的一个引用。

  • 取地址符作用于一个左值运算对象返回一个指向该对象的指针,这个指针是一个右值。

如:&a,其中a是一个变量是一个左值,得到的结果是a的地址,是一个指针是一个右值

  • 内置运算符解引用运算符、下标运算符、迭代器的解引用运算符、string和vector的下标运算符的求值结果都是一个左值

如:int *p=a[10]; *p的结果是a[0]是一个数组元素的对象,是一个左值。

  • 内置类型和迭代器递增递减运算符前置版本,作用于左值对象,所得的结果也是个左值

如:++a;

生成右值的运算:

  • 常量是临时量,属于右值

  • 返回非引用类型的函数

  • 算数运算符结果

  • 关系运算符结果

  • 位运算符结果

  • 后置递增递减运算符的结果

2.类型转换

C++中,某些类型之间有关联,如果两种类型有关联,那么当程序需要其中一种类型的运算对象时,就可以用另一种关联类型对象或值类替代。如果两种类型可以相互转换,那么它们就是关联的。

2.1隐式转换

看一个例子:

int val = 3.541 + 3; 

C++语言不会将两个不同的类型相加,而是3.541转换成整型3,再进行相加,这个类型转换是自动执行的,无需程序员的介入,因此,被称为隐式转换。

①何时发生隐式类型转换

  • 在大多数表达式中,比int类型小的整型值首先提升为较大的整数类型(int)。(为了内存对齐),如:
int a = 1;
short b = 2;
int c = a + b; //short自动隐式转换成int型之后再进行相加
  • 非布尔值转换成布尔值
bool b = -1; //非0值转换成true
  • 初始化过程中初始值转换成变量的类型;在赋值语句中,右侧运算对象转换成左侧运算对象的类型
int a = 3.14; //初始值浮点型,隐式转换成整型
a = 4.56; //赋值运算符,右侧运算对象浮点型,隐式转换成左侧对象的整型
  • 如果算术运算符或关系运算符运算对象有多种类型需要转换成同一种类型,就像刚才的例子。
int val = 3.541 + 3;
  • 函数调用时也会发生类型转换。实参向形参进行值传递时相当于进行赋值运算语句的隐式类型转换。
void fun (Test &t) ;
fun (1); //隐式转换类型将1转换成Test类型
  • 数组转换成指针:在大多数用到数组的表达式中,数组名自动转换成指向数组首元素的指针。
int a[10] = {1, 2, 3}; //数组名自动转换成指向数组首元素的指针
//相当于
int *p = a[0];
  • 指针的转换常量整型0字面值nullptr能转换成任意指针类型指向任意非常量的指针能转换成void* ;指向任意对象的指针

  • 转换成常量允许将指向非常量类型的指针转换成指向相应的常量类型的指针,对于引用也是这样。也就是说,如果T是一种类型,我们就能将指向T的指针或引用分别转换成指向const T的指针或引用。

    在函数形参使用const引用的形参有两个作用:

    1. 扩大函数接收范围,不仅能接受常量实参,还能接受变量实参将变量实参隐式转换成常量。
    2. 函数设置为只读状态防止改变实参状态
int i; 
const int &j = i;  //非常量转换成const int的引用
const int *p = &i; //非常量的地址转换成const的地址
int &r = j, * q= p; //错误:不允许const转换成非常量
  • 类类型定义的转换: 类类型能定义由编译器自动执行的转换。如:
string s = "abc"; //将字符串字面值类型"abc"隐式转换成string类型,再进行赋值

2.2强制类型转换

强制类型转换干扰了正常的类型检查,并且充满了风险,强烈建议不要使用强制类型转换!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值