当前位置: 首页 > news >正文

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++ 标准中是左值,因此,语句++a=1;在C++中是正确的语句。虽然该语句在C++中是正确,但不建议这样写。

表达式a++=1在C或C++中都是错误的,因为它试图两次修改同一个对象,这是不允许的。讨论这个话题就像讨论一个错误的时钟在一个小时后的时间是多少而已。

注:左值(Ivalue)这个词最初源自赋值表达式E1=E2,其中左操作数E1必须是(可修改的)表达式。对象(object)是一块内存区域,可以读取它的值或者向它存储数据。一般将左值视为对象的“定位值(locator value)”,即左值是一种表达式,可以通过它读取或修改它所引用的对象。例如,表达式a和b都是左值,但表达式3和b+3都不是左值。再如,若一元表达式E是一个指向对象的指针,则*E是一个左值,表示E指向的对象。

C99左值的定义是:左值是具有对象类型非void的不完整类型的表达式,如果左值在求值时没有指定对象,则其行为是未定义的。

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语言辨析——深入理解格式字符的用法

相关文章:

  • 在 Python 中实现语音合成的四种方法
  • js监听返回当前页面的方法
  • HCIP-BGP实验3
  • Mysql中的日志系统
  • ChatGPT与文心一言:AI助手之巅的对决
  • 利用appium自动控制移动设备并提取数据
  • 从 GPT1 - GPT4 拆解
  • 【Java】JDBC的使用
  • Yaklang 中的类型和变量
  • 华南理工大学计算机23考研复试(线下)经验分享
  • PGSQL安装PostGIS扩展模块
  • 基于YOLOv8深度学习的100种中草药智能识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战
  • 零基础学Python(2)— 安装Python开发工具之PyCharm
  • 《Python数据分析技术栈》第01章 02 Jupyter入门(Getting started with Jupyter notebooks)
  • haiku生成随机数
  • @jsonView过滤属性
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • angular学习第一篇-----环境搭建
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • php面试题 汇集2
  • scrapy学习之路4(itemloder的使用)
  • Selenium实战教程系列(二)---元素定位
  • spring boot 整合mybatis 无法输出sql的问题
  • 如何合理的规划jvm性能调优
  • 如何学习JavaEE,项目又该如何做?
  • 微信公众号开发小记——5.python微信红包
  • 消息队列系列二(IOT中消息队列的应用)
  • 小试R空间处理新库sf
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • 阿里云移动端播放器高级功能介绍
  • (1)Nginx简介和安装教程
  • (52)只出现一次的数字III
  • (C语言)二分查找 超详细
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (三)Honghu Cloud云架构一定时调度平台
  • (未解决)macOS matplotlib 中文是方框
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .net mvc部分视图
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .net专家(张羿专栏)
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示
  • @Builder用法
  • @zabbix数据库历史与趋势数据占用优化(mysql存储查询)
  • [ CTF ]【天格】战队WriteUp- 2022年第三届“网鼎杯”网络安全大赛(青龙组)
  • [1] 平面(Plane)图形的生成算法
  • [APIO2015]巴厘岛的雕塑
  • [ASP.NET MVC]Ajax与CustomErrors的尴尬
  • [bbk5179]第66集 第7章 - 数据库的维护 03
  • [BUG]Datax写入数据到psql报不能序列化特殊字符
  • [BZOJ 3680]吊打XXX(模拟退火)