i++为什么不能作为左值,而++i可以作为左值
今天看书见到如下代码:
int a=2;
++a++;
根据操作符的优先级和结合性知,操作符++的优先级为3,结合性为右结合,即++a++;可以理解为++(a++);
但我把代码放在vs2015上,结果报错,如图:

意思就是所a++不能作为左值,那a++为什么不能作为左值呢?我们先来看左值的定义:
左值(lvalue) 是B语言/C语言/C++语言等类C语言中的一类表达式。“左”(left)的原意是指可以放在赋值符号“=”的左边,但其实也表示能作为&和++等操作符的操作数(B语言中已经如此)。左值不但具有空间实体,还具有读写访问权。
现在我们来看a++的实现:
int temp;
temp=a;
a=a+1;
return temp;
因为a++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通过地址对它进行操作.(换句话说就是不能作为左值)。
而++a的实现为:
a=a+1;
return a;
因为++a返回的是a,它是程序中定义的可寻址变量的引用,所以它可以作为左值。
附加:++与--是连体操作符,中间不能有空格。如果有多于两个的+或-连写,则编译器按“贪吃法则”理解。所谓贪吃,是指只要能理解(能成为操作符),就尽量多读入字符。例如:
(1)int a=1, b=5, c;
(2)c = a + b; //ok
(3)c = a ++ b; //错:a++和b两个表达式,缺乏相运算的操作符
(4)c = a +++ b; //ok:a++ +b;
(5)c = a ++++ b; //错:a++和++b两个表达式,缺乏相运算的操作符
(6)c = a +++++ b; //错:a++ ++ +b,a++非左值,不能++
根据“贪吃法则”,上面第3行,编译器不会理解成a + +b;同样第5行也不会理解成a++ + +b;以及第6行也不会理解成a++ + ++b;编译器对表达式的理解是没有二义性的。如果要使上面的非法代码可行,只能通过书写格式人为控制表达式的意义,如下代码:
using namespace std;
int a = 1, b = 5, c;
c = a + +b;
cout << c << endl;
c = a++ +b;
cout << c << endl;
c = a++ + +b;
cout << c << endl;
c = a+ ++++b;
cout << c << endl;
}

i++为什么不能作为左值,而++i可以作为左值的更多相关文章
- js/jquery获取文本框的值与改变文本框的值
我们就用它来学习获取文本框的值及改变文本框的值. 代码如下 复制代码 <script>function get1(){ document.getElementById("txtb ...
- Android(java)学习笔记105:Map集合的遍历之键值对对象找键和值
package cn.itcast_01; import java.util.HashMap; import java.util.Map; import java.util.Set; /* * Map ...
- Java基础知识强化之集合框架笔记53:Map集合之Map集合的遍历 键值对对象找键和值
1. Map集合的遍历(键值对对象找键和值) Map -- 夫妻对 思路: A: 获取所有结婚证的集合 B: 遍历结婚证的集合,得到每一个结婚证 C: 根据结婚证获取丈夫和妻子 转换: A: ...
- 在HTML页面布局中,position的值有几种,默然的值是什么
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- (转)函数中使用 ajax 异步 同步 返回值错误 主函数显示返回值总是undefined -- ajax使用总结
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAloAAAE0CAIAAAB7LwoKAAAgAElEQVR4nO2dy6sc152A6+/R2mXwSn ...
- 如果nginx 中worker_connections 值设置是1024,worker_processes 值设置是4,按反向代理模式下最大连接数的理论计算公式: 最大连接数 = worker_processes * worker_connections/4
如果nginx 中worker_connections 值设置是1024,worker_processes 值设置是4,按反向代理模式下最大连接数的理论计算公式: 最大连接数 = worker_pro ...
- 表A中有两个表示时间的字段A,B;如果B的值大于A的值,则把B的值更新为A的值
sql语句:表A中有两个表示时间的字段A,B:如果B的值大于A的值,则把B的值更新为A的值 update 表名 set B=A where B>A
- 'k1': 大于66的所有值, 'k2': 小于66的所有值
#!/usr/bin/env python # -*- coding: utf-8 -*- #有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值 ...
- 混淆矩阵、准确率、精确率/查准率、召回率/查全率、F1值、ROC曲线的AUC值
准确率.精确率(查准率).召回率(查全率).F1值.ROC曲线的AUC值,都可以作为评价一个机器学习模型好坏的指标(evaluation metrics),而这些评价指标直接或间接都与混淆矩阵有关,前 ...
随机推荐
- 关于CentOS 7安装solr+tomcat
1.Solr7.1.0 安装部署(centos7) Solr7.1.0为目前的最新版,安装环境需要jdk1.8 或者更高,容器我用的tomcat,也建议tomcat8.0或者更高 1.1.下载solr ...
- Linux 常用命令一 ls
一.ls命令 用于查看目录下的文件信息. ls 当前目录下都有哪些文件: wang@wang:~$ ls examples.desktop workpalce 模板 图片 下载 桌面 tools 公共 ...
- 【HDU - 1241】Oil Deposits(dfs+染色)
Oil Deposits Descriptions: The GeoSurvComp geologic survey company is responsible for detecting unde ...
- 30行JavaScript代码实现一个比特币量化策略
精简极致的均线策略 30行打造一个正向收益系统 原帖地址:https://www.fmz.com/bbs-topic-new/262 没错!你听的没错是30行代码!仅仅30行小编我习惯先通篇来看看 代 ...
- 水题 Codeforces Round #306 (Div. 2) A. Two Substrings
题目传送门 /* 水题:遍历一边先找AB,再BA,再遍历一边先找BA,再AB,两种情况满足一种就YES */ #include <cstdio> #include <iostream ...
- 题解报告:hdu 1406 完数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1406 Problem Description 完数的定义:如果一个大于1的正整数的所有因子之和等于它的 ...
- 安装11g 数据库
出现问题解决: 1.首先确认下载的安装包完整性.2解压包的时候,按顺序解压,解压第一个包后,解压第二个包的时候,要把解压地址与解压第二包的地址要一样. 安装的时候,需要把两个压缩包都解压,并将目录wi ...
- linux安装glassfish并布署
1 https://glassfish.java.net/download.html 2 准备工作:需要jdk7以上版本 Java EE 7 requires JDK 7 (or above) 下载g ...
- c#.net 正则匹配以特定字符串开头,以特定字符串结尾
string[] unit = Getunit(result40, "(?<=(开始字符串))[.\\s\\S]*?(?=(结束字符串))"); private string ...
- 在Windows7下编译调试C#程序
要在 命令行下编译C#代码,要配置一下 1.在环境变量下新建一个变量 参数名: csc 参数值:C:\Windows\Microsoft.NET\Framework\v4.0.30319 2.在系统变 ...