C语言辨析——int a=5;为什么++a=1能编译通过而a++=1不行呢?

1. 问题

有人问:int a=5; 为什么++a=1能编译通过a++=1编译错误呢?

解释:不管是++a=1还是a++=1在C编译环境下都无法编译通过,但在C++中,++a=1可以编译通过,而a++=1无法编译通过,这也是C和C++的一个不同。因此,这是一个关于C++的问题

2. 分析

不管是C还是C++,语句a++=1;的行为是未定义的,因为它违反了"如果在没有序列点表达式中多次修改 同一标量的行为是未定义行为"。

对于++a=1,等效于(a+=1)=1,对于C而已 (a+=1)不是左值,因此不能将1赋值给++a。因此,在C中编译通不过,给出的错误信息是:

Error\] lvalue required as left operand of assignment 但对于C++而言,表达式++a=1是正确的,因为++a在C++ 标准中是[左值](http://mp.weixin.qq.com/s?__biz=MzIyNDQyMzQ5Ng==&mid=2247492482&idx=5&sn=ff87ab834885cdf557d0ca1dde5eeb99&chksm=e80d98a5df7a11b37ad62ec0da5593f69465131ec5ce7a029c1c1894f187c06f252e4c8d6619&scene=21#wechat_redirect "左值"),因此,语句++a=1;在C++中是正确的语句。虽然该语句在C++中是正确,但不建议这样写。 表达式a++=1在C或C++中都是错误的,因为它试图两次修改同一个对象,这是不允许的。讨论这个话题就像讨论一个错误的时钟在一个小时后的时间是多少而已。 注:**左值** **(Ivalue)** 这个词最初源自赋值表达式E1=E2,其中左操作数E1必须是(**可修改的** )表达式。[对象(object)](http://mp.weixin.qq.com/s?__biz=MzIyNDQyMzQ5Ng==&mid=2247491525&idx=1&sn=fc627b346fcc183b506d144030f12fa9&chksm=e80e64e2df79edf4cbaba847dcb9cc890d7dca0a5bdea74eece80bcc1e6442030394ea267dbf&scene=21#wechat_redirect "对象(object)")是一块内存区域,可以读取它的值或者向它存储数据。一般将左值视为对象的"**定位值** (locator value)",**即左值是一种表达式,可以通过它读取或修改它所引用的对象。**例如,表达式a和b都是左值,但表达式3和b+3都不是左值。再如,若一元表达式E是一个指向对象的指针,则\*E是一个左值,表示E指向的对象。 **C99** 对**左值的定义是** :左值是具有[对象](http://mp.weixin.qq.com/s?__biz=MzIyNDQyMzQ5Ng==&mid=2247491525&idx=1&sn=fc627b346fcc183b506d144030f12fa9&chksm=e80e64e2df79edf4cbaba847dcb9cc890d7dca0a5bdea74eece80bcc1e6442030394ea267dbf&scene=21#wechat_redirect "对象")**类型** 或**非void的不完整类型的表达式** ,如果左值在求值时没有指定**[对象](http://mp.weixin.qq.com/s?__biz=MzIyNDQyMzQ5Ng==&mid=2247491503&idx=1&sn=363b8f308acd6dbd5a80ef0e4ccb2dea&chksm=e80e6488df79ed9e3e7944441ca89cd087d9e2fa5a6db56100c19cba8b6a054eeaaa50f69aeb&scene=21#wechat_redirect "对象")**,则其行为是未定义的。 **C11起** 对**左值的定义是** :左值是一个表达式,该表达式潜在地指示一个**对象** ,且该**对象类型不是void**,如果左值在求值时没有指定对象,则其行为是未定义的。 **3. 进一步分析** 在C标准中,由自增和自减运算符构成的表达式是右值(在C标准中,有时把右值(rvalue)描述为表达式的值),但在C++中,前缀形式的运算符构成的表达式是左值。因此,在C语言中,即a++和++a不是左值而是右值,因此无法为它们赋值。而在C++ 中++a是左值,因此可以给++a赋值,这就是为什么在C++中语句++a=1; 能编译通过的原因。 注:在C标准中,赋值和复合赋值运算符构成的表达式是右值,但在C++中是左值。例如 表达式(a=3\*4)=5+6在C中是错误的,但在C++ 中是正确的。对于表达式a=3\*4来说,在C中不是左值,因此不能将表达式5+6赋值给它,但在C++ 中它是左值,因此,可以将5+6赋值给(a=3\*4)。 **4. 经验** 如果一个变量出现在一个函数的多个参数中,不要对该变量使用递增或递减运算符。 如果一个变量多次出现在一个表达式中,不要对该变量使用递增或递减运算符。 C语言学习50 C语言学习 · 目录 上一篇C 语言基本概念----序列点下一篇C语言辨析------深入理解格式字符的用法

相关推荐
MSTcheng.37 分钟前
【数据结构】顺序表和链表详解(下)
数据结构·链表
SY师弟1 小时前
台湾TEMI协会竞赛——0、竞赛介绍及开发板介绍
c语言·单片机·嵌入式硬件·嵌入式·台湾temi协会
Q8137574601 小时前
中阳视角下的资产配置趋势分析与算法支持
算法
yvestine1 小时前
自然语言处理——文本表示
人工智能·python·算法·自然语言处理·文本表示
HUN金克斯1 小时前
C++/C函数
c语言·开发语言·c++
慢半拍iii1 小时前
数据结构——F/图
c语言·开发语言·数据结构·c++
m0_637146931 小时前
零基础入门 C 语言基础知识(含面试题):结构体、联合体、枚举、链表、环形队列、指针全解析!
c语言·开发语言·链表
GalaxyPokemon1 小时前
LeetCode - 148. 排序链表
linux·算法·leetcode
iceslime2 小时前
旅行商问题(TSP)的 C++ 动态规划解法教学攻略
数据结构·c++·算法·算法设计与分析
aichitang20243 小时前
矩阵详解:从基础概念到实际应用
线性代数·算法·矩阵