Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么可以';我不知道++;i++;用C语言?_C#_C_Post Increment_Pre Increment - Fatal编程技术网

C# 为什么可以';我不知道++;i++;用C语言?

C# 为什么可以';我不知道++;i++;用C语言?,c#,c,post-increment,pre-increment,C#,C,Post Increment,Pre Increment,半开玩笑半认真的:为什么我不能用类C语言,特别是C语言来做++I++ 我希望它增加值,在我的表达式中使用它,然后再次增加。因为你关心下一个程序员维护(或试图重新编写)你的代码,而这是在你因违反流行惯例而被解雇很久之后 简短回答:i++不是“左值”,因此不能作为赋值的主题。我认为递增(或递减)运算符需要一个左值来赋值。然而,++i不是左值,它是一个表达式。精通编译器的人可能能够澄清此约束是否有任何技术原因。因为i++的结果不是左值。来自以下第7.5.9节: 后缀增量或的操作数 递减操作必须是 被分

半开玩笑半认真的为什么我不能用类C语言,特别是C语言来做
++I++


我希望它增加值,在我的表达式中使用它,然后再次增加。

因为你关心下一个程序员维护(或试图重新编写)你的代码,而这是在你因违反流行惯例而被解雇很久之后

简短回答:
i++
不是“左值”,因此不能作为赋值的主题。

我认为递增(或递减)运算符需要一个左值来赋值。然而,++i不是左值,它是一个表达式。精通编译器的人可能能够澄清此约束是否有任何技术原因。

因为
i++
的结果不是左值。

来自以下第7.5.9节:

后缀增量或的操作数 递减操作必须是 被分类为变量的表达式 属性访问,或索引器访问。 操作的结果是一个值 与操作数的类型相同。如果 后缀增量或的操作数 减量操作是一个属性或属性 索引器访问、属性或 索引器必须同时具有get和set 存取器。如果不是这样的话,a 发生编译时错误

此外,将首先计算增量后表达式(
i++
),因为它比增量前(
++i
)运算符具有更高的优先级。

虽然简短的回答“它不是左值”是正确的,但这可能只是在回避问题。为什么它不是左值?或者,正如我们在C#中所说的,一个变量

原因是你不能既有蛋糕又吃。逻辑地解决它:

首先,C#中的++运算符(无论是后缀还是前缀)的含义是“获取该变量的值,增加该值,将新值分配给该变量,并生成一个值作为结果”。结果产生的值是原始值还是增量值,取决于它是后缀还是前缀。但无论哪种方式,都会产生价值

其次,变量的值始终是该变量的当前内容。(对某些奇异的线程场景进行模块化,这将把我们带到很远的地方。)

我希望你同意这些规则是完全合理的

现在应该很清楚为什么i++的结果不能是变量,但如果不是,让我澄清一下:

假设我10岁。i++的含义应该是“获取i-10的值-增加它-11-存储它-我现在是11-并给出原始值作为结果-10”。所以当你说print(i++)时,它应该打印10,11应该存储在i中

现在假设i++的意思是返回变量,而不是值。你说打印(i++),会发生什么?你得到i-10的值-递增it-11-存储it-现在i是11-并返回变量作为结果。变量的当前值是多少?11! 这正是你不想打印的

简言之,如果i++返回一个变量,那么它将与操作符的预期含义正好相反!您的提案在逻辑上不一致,这就是为什么没有任何语言会这样做。

我测试了(++I,I++)作为解决办法:

#include <stdio.h> 

int main(){
  int i=0;

  printf(" i:         %i\n", i         );
  printf(" (++i,i++): %i\n", (++i,i++) );
  printf(" i:         %i\n", i         );
}

即使它真的起作用,你也不应该,因为你不应该憎恨生活:(.看到++i++在任何情况下都会让我难过,不管解释是什么。我不知道有“愚蠢的操作员技巧”标签,谢谢约翰!@zvolkov:没有……约翰只是为了你的问题而创建了这个标签;)当我们在看的时候,这是为什么它是“不道德的”,但事实上它是非法的以及不道德的。不幸的是,很多C++(希望固定在下一个标准中)是不道德的,在政治上是不正确的,但是合法的…这是一个与程序设计相关的评论,不仅仅是与语言设计有关…++i将首先被评估。事实上,增量后优先。增量后优先于增量前;你想说
i++
不是左值,不是
++i
。(尽管这两种方法都不起作用)
++i
是一个左值,因此
(++i)+
将是有效的,但事实上它在没有插入序列点的情况下写入
i
两次。问题是语法指定<代码> ++i++< /COD>相当于‘++(i++)’。@ Charles Bailey:+i是C和C++中的一个LIVE,但IIRC不是C中的。+i不是C中的一个LValk。尝试分配给它,看看你的编译器说了什么。好点,好。不过,我想强调的是,更多的是“问题具体地说是C#”,而不是“我记不起C和C++之间令人尴尬的区别”。C中的++I类型是左值。你能澄清一下吗?我试图编译“++I=4;”,但得到一个错误,表示操作数的左侧需要一个左值。也许我的误解在于左值的定义?我理解它是可以赋值的。标准第5.3.2节第1段:“值是操作数的新值;它是一个左值。”(这当然是关于“prefix++”的段落)当然,“++I=4;”也是在没有插入序列点的情况下两次更改I值的尝试,因此未定义的行为。“f(++)i”与“int f(int &)”将涉及一个序列点,应该合法。好,它绝对是一个C++中的左值,我现在找不到C.的一个确定答案。当然,除非你的答案是关于C,在这种情况下,
++i
实际上不是左值。在C99草案n1256中,您会发现:“赋值表达式具有赋值后左操作数的值,但不是左值”,而它表示<

i:         0
(++i,i++): 1
i:         2