左值就是在赋值中可以放在赋值操作符两边的值,比如:

int a = 1;
double b = 2.0

a = b;
b = a;

这里a和b都是左值,一切变量都是左值,但const变量是例外。

*p是一个左值,和变量一样,只要在*p的右边加上赋值运算符,就可改变*p的值。

如果p是一个指向常量的指针,*p就是一个不能修改的左值,即它不能被放到赋值运算符的左边。

i和 -i 都是表达式
但一个是左值(i),一个是右值(-i)。
++,--这两种操作符要求作用于左值,所以i++合法,(-i)++不合法。

不严谨的讲,左值右值的区分在于位于等号的那一侧,左侧的是左值,通常是一个变量,右侧的是右值,可以是一个变量,或者是一个表达式。

先看什么是表达式:
表达式由一个或多个操作数通过操作符组合而成。最简单的表达式仅包含一个字面值常量或变量。较复杂的表达式则由操作符以及一个或多个操作数构成。
再看什么是左值:
C++ 中存在两种表达式:左值可以出现在赋值语句的左边或右边。右值只能出现在赋值的右边,不能出现在赋值语句的左边。
另外说明一下,i不仅是一个表达式,它还是一个变量,但是-i却不是一个变量,这是他们一个可以自增一个不能自增的根本原因
对于i++来说,i是一个变量,所以是一个左值,执行i=i+1
但是对于(-i)++来说,-i是一个表达式,而不是一个变量,一个表达式是不可以作为左值的,因为没有办法执行这条语句:-i=-i+1(-i+1的值不能附给-i,因为没有-i这个变量存储空间)

一个赋值表达式:
X = Y;
在这个表达式里,符号X的含义是X所代表的地址,这被称为左值,左值在编译时可知,左值表示存储结果的地方;
在这个表达式里,符号Y的含义是Y所代表的地址的内容,这被称为右值,右值在运行时才可知,如无特别说明,右值表示“Y的内容”。 在《C专家编程(中文版)》中第4章,对左值和右值的基本描述。
而右值则是只可以放在赋值操作符右边的值,比如:
int a = 0;
char *b = "hello";

3 = a; // ERROR
"howdy" = b // ERROR

这里3和"howdy"都是右值,所以不能放在赋值操作符左边,一切常数、字符和字符串都是右值。

l-value 与 r-value 区别
左值是引用某个对象的表达式,就是可以放在赋值左边的东西,如:*(p+1)=7, 没有名字的变量(*(p+1)表达式一定是一个类型的对象)被赋值了,但左值并不一定能被赋值,因为左值可以引用某个常量。 所有的引用都是左值。
右值是表达式的值(不是引用),可以放在赋值右面。
所有的左值都可以是右值,反之不成立
int i, j, *p;
i = 7; // Correct. A variable name, i, is an l-value.
7 = i; // ERROR. A constant, 7, is an r-value.
j * 4 = 7; // ERROR. The expression j * 4 yields an r-value.
*p = i; // A dereferenced pointer is an l-value.
const int ci = 7; // Declare a const variable.
ci = 9; // ERROR. ci is a nonmodifiable l-value

普通引用和const引用的初始化
当引用的初始式是一个左值(是一个对象,你可以取得他的地址)时,其初始化就是非常简单的事情。普通T&的初始式必须是一个T类型的。而cosnt T&则不必是一个左值,甚至可以不是T类型的。在这样的情况下,经过以下几个步骤。
(1)首先,如果需要的话,将应用到类型T的隐式类型转换。
(2)而后,将结果存入一个类型T的临时变量。
(3)最后,将此临时变量用作初始化的值。
例如
double& d=1; //错误,d是左值,不能用右值1 来初始化
const double& cd=1; //ok

对后一个初始化的解释是:
double temp=double(1); //首先建立一个具有正确数据类型的临时变量
const double& cd=temp; //而后用这个临时变量作为cd的初始式,temp是个右值

由于左值的一大特点是可以对其赋值,而const正好将这个特点给阉割了,使该表达式成为了一个右值,所以可以用右值来初始化。

===7.3.1引用参数===
函数的引用参数
把参数声明成引用,实际上改变了缺省的按值传递参数的传递机制。在按值传递时,函数操纵的是实参的本地拷贝。当参数是引用时,函数接收的是实参的左值而不是值的拷贝。
这意味着函数知道实参在内存中的位置,因而能够改变它的值或取它的地址。
int obj;
void frd( double & );
int main()
{
frd( obj ); // 错误: 参数必须是 const double &
return 0;
}
对frd()的调用是错误的.实参类型是int 必须被转换成double 以匹配引用参数的类型,
该转换的结果是个临时值,因为这种引用不是const 型的,所以临时值(不是左值)不能被用来初始化该引用

什么时候将一个参数指定为引用比较合:
1、允许改变实参的值
2、向主调函数返回额外的结果
3、向函数传递大型类对象

使用指针还是引用作为参数的一个重要区分:
引用必须被初始化为指向一个对象,一旦初始化了,它就不能再指向其他对象,而指针可以指向一系列不同的对象也可以什么都不指向
所以,如果一个参数可能在函数中指向不同的对象,或者这个参数可能不指向任何对象,则必须使用指针参数

===7.3.3 数组参数===
在C++中数组永远不会按值传递它是传递第一个元素(准确地说是第0 个)的指针
如下声明
void putValues( int[ 10 ] ); //当编译器对实参类型进行参数类型检查时,并不检查数组的长度,编泽器忽略10
被编译器视为
void putValues( int* );
数组的长度与参数声明无关,因此下列三个声明是等价的
// 三个等价的putValues()声明
void putValues( int* );
void putValues( int[] );
void putValues( int[ 10 ] );

传递数组长度的三种机制
1、提供一个含有数组长度的额外参数:void putValues( int[], int size );
2、将参数声明为数组的引用:void putValues( int (&arr)[10] );
当参数是一个数组类型的引用时,数组长度成为参数和实参类型的一部分,编译器检查数组实参的长度与在函数参数类型中指定的长度是否匹配
// 参数为10 个int 的数组
// parameter is a reference to an array of 10 ints
void putValues( int (&arr)[10] );//只接受10 个int的数组
int main() {
int i, j[ 2 ];
putValues( i ); // 错误: 实参不是 10 个 int 的数组
putValues( j ); // 错误: 实参不是 10 个 int 的数组
return 0;
}

3、使用抽象容器
void putValues(const vector<int> &vec );

C语言中什么叫做左值?右值?相关推荐

  1. ​Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数

    ​Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数 7.4.4  为外部参数设置默认值 开发者也可以对外部参数设置默认值.这时,调用的时候,也可以省略参数传递本文选自Swift ...

  2. C语言求x和y的乘积,计算方程式,求x,C语言中怎么计算x,y的值?

    导航:网站首页 > 计算方程式,求x,C语言中怎么计算x,y的值? 计算方程式,求x,C语言中怎么计算x,y的值? 匿名网友: (x-1)=0吧,写题也这么不仔细呀. 哈哈m/x=n/(x-1) ...

  3. C语言中函数参数传递的方式:值传递,地址传递

    ** C语言中函数参数传递的方式:值传递,地址传递 ** 值传递:将实参的值复制至形参的相应存储单元中,实参与形参占用不同存储单元,单向传递 地址传递:使用数组名或者指针作为函数参数,传递的是该数组的 ...

  4. java中的左值右值_快速了解C/C++的左值和右值

    最近在segmentfault上看到一个提问<c++隐式的类类型转换问题>:一时不知怎么回答,查阅相关资料后整理了本文,以供参考学习. 定义 早期的C给出的定义:左值是一个表达式,可能出现 ...

  5. c语言表达式和逻辑表达式是,C语言中关系表达式和逻辑表达式的值是什么

    C语言中关系表达式和逻辑表达式的值是什么? 关系表达式和逻辑表达式的值是布尔型:真或假(true or false),即0或1,但c语言没有布尔类型,以0为假,非0即真. 逻辑运算又称布尔运算.布尔用 ...

  6. C++11新特性之左值右值及移动语句与完美转发

    C左值右值 左值和右值的由来 什么是左值和右值 左值右值的本质 引用 左值引用 右值引用 移动语句与完美转发 移动语句 实现移动构造函数和转移赋值函数 stdmove 完美转发Perfect Forw ...

  7. C、C++差异之左值右值

    C与C++在语法细节上还是有一些差异的,虽然一般情况下可能这些差异不足以造成结果的区别,但有些代码确实会有影响. 这次,主要总结下左值右值的差异. 在C中,很多左值运算符的结果都不再是左值,然而在C+ ...

  8. c++ 左值 广义左值 右值 纯右值 将亡值

    为什么C/C++等少数编程语言要区分左右值? 历史原因: C语言作为一门古老的编程语言,其设计初衷是为了在硬件资源有限的系统上进行高效的编程,因此其语法和语义设计相对较简单.左值和右值的概念最初是由C ...

  9. 左值/右值/左值引用/右值引用/move的用法介绍

    目录 问题 左值和右值 概念总结: 需要用到左值的运算符: 引用分类 左值引用 右值引用 右值引用到底什么用? std::move()函数介绍 问题 什么是左值和右值? 什么是左/右值引用? 左/右值 ...

最新文章

  1. LeetCode实战:求众数
  2. CAS是什么?ABA问题的产生和解决方法
  3. c++中的list用法
  4. Spring Cloud Config的配置中心获取不到最新配置信息的问题
  5. 无法通过sak判断卡片类型_如何判断你家门能否更换智能锁?选锁门道你要懂!...
  6. Deeper Network将于明日启动DPR/USDC流动性质押第三季
  7. 如何用SQL为每一行均产生一个随机数
  8. Python模块:生成随机数模块random
  9. VPP 助你创新更高效、更灵活的报文处理方案
  10. 1000以内完数c语言程序_求1000以内完数 c语言 。。
  11. 【复习笔记】电分-第三章-电力系统潮流分析与计算
  12. PyTorch 实现kmax-pooling
  13. 程序集(dll) 安装到 GAC 程序集添加到VS引用开窗(转)
  14. python 爬取doc文档
  15. 微信支付中xml和map互转
  16. arduino双按钮同时点灯
  17. android studio开发十一 Library第三方类库源码, Jar包和SO库
  18. Python搭建简单的web服务器
  19. Matlab 矩阵及其元素表示
  20. 关于日期格式的书写及对应含义(便于查找)

热门文章

  1. S-DES加密算法介绍与实现
  2. TIA博途中FC功能块的介绍与管脚定义
  3. linux模拟usb发包,Linux下USB模拟ps2鼠标驱动
  4. 中国书信礼仪 (三)
  5. 2021-03-15我的博客
  6. windows 远程连接服务器和安装nginx
  7. 即刻报名|飞桨黑客马拉松第三期盛夏登场,等你挑战
  8. 逻辑 - 联言命题,选言命题
  9. oral-b app Android,oral b app
  10. 2019年最新中文TTS算法实现个合成样本