首页 > 分享 > C 中 i=i+i++之类问题。

C 中 i=i+i++之类问题。

i=i+i++之类问题,根本不是优先级的问题。

简单说吧,a = b ,意思是,先计算出表达式b的值,然后把这个值赋给a。

表达式的定义为: 一个单独的字面值,或者一个单独的变量,或者通过算术/逻辑运算甚至函数调用连接起来的表达式。

显然,对于表达式b来说,它的运算符优先级有多复杂都不是问题。

但,请注意,表达式里面不允许出现赋值操作,因为这个操作并不是算术/逻辑运算。

————————————————————
显然,i++的问题在于,虽然i++看起来只有操作符和操作数组合、而且通常作为表达式使用,但其实它的含义是i=i+1 ——这根本不是一个表达式,而是“计算表达式i+1的值,并将其赋予变量i”:换句话说,这是一个标准的赋值操作。

事实上,i++本身就可以是一个合法的c/c++语句;而 2+3、a&&b、!a之类真正的表达式则不是。原因就是i++另外还隐含了一个赋值操作。

c/c++标准里面对这类有表达式外表、但却另有额外语义的“假”表达式叫做“有side effect的表达式”(关于何谓side effect,c/c++标准也专门给出了定义),实质上也是强调了它和原始意义上的表达式的不同之处。

但是呢,为了写代码的便利,c/c++系语言提供了一个语法糖,允许程序员将i++用到表达式里面,同时规定其含义为:首先取i的值,用这个值代入表达式,供以后求值用;之后,执行i=i+1(执行i=i+1的确切时机不限,在表达式求值之前还是之后都行,只要执行了就对)。

如此一来,i++看起来就可以作为表达式的一个组成部分了。

但,必须注意,i++毕竟不是一个表达式。通过规定允许它掺乎进去,就必然带来很多棘手的问题。

比如说,i=i++,这个语句如何解释?

首先,这显然是一个赋值语句,所以最终i应该存的是等号右侧表达式的值;虽然i++不是表达式,但按照规定,它可以解释为“语句执行前i的取值”;所以,这其实是把语句执行前,i的取值赋给i的一个赋值语句——也就是说,执行后,i的值应该不变。

但,注意i++还有一个赋值动作。即:把语句执行前的i值加一,然后赋值给变量i——所以,执行后,i的值应该增加了1。

显然,两个赋值动作的执行结果出现了矛盾。究竟哪个对呢?

进一步的,i=(i++)+(i++)呢?这里面可有三个针对i的赋值操作啊。

不仅如此,对于函数调用,如max(i++, i++),这又是什么意义呢?

很显然,不是表达式的i++,绝对不能和表达式混淆。

虽然,为了表达简洁,c/c++系列语言允许它在特定场合代替表达式,但这并不等于说,c/c++就认为它和表达式没有差别。

相反,c/c++自始至终都认为它是一个赋值操作,只是可以在严格限定的场景替代表达式而已——这个“严格限定”,就是“不允许一个变量在一对序列点之间两次改变其值”(不太严谨的说法)。

换句话说,i++本身是一个有着特定内涵(对i赋值)的指令,并不是单纯的数学表达式。
显然,把它当基本数学表达式滥用,得到的复合表达式是没有数学意义(因而也没有现实意义)的。

把它用对,是程序员的责任。

相关知识

建筑图纸排水管中i=0.003是什么意思?
菜的笔顺 笔画数:11 拼音:cài 部首:艹
for (let i = 0; i < haystack.length; i++)
Search engine marketing (SEM) là gì? Chiến lược SEM tối ưu
C/C++中的段错误(Segmentation fault)
曲线积分问题.求∫根号下(2y²+z²)ds,其中积分曲线c为封闭曲线x²+y²+z²=a²过程是I=∫根号下a²dL=a∫dL=a·(2πa)请问2πa是怎么来的,它应该是圆的周长啊,而积分曲线c为封闭
假设在一个两部门经济中, Y是收入, 消费函数为C=1000+0.8Y, 投资I
for i in range(3) print(i) i = i + 3 pri
C语言之正确使用const
传教士问题c语言

网址: C 中 i=i+i++之类问题。 https://m.huajiangbk.com/newsview1234864.html

所属分类:花卉
上一篇: 怪!为啥有人在农村大量收购碎木?
下一篇: 水生态修复技术知识点5:海绵城市