在C编程中,你可以使用三个连续的减号吗?它代表什么意思?

59

可能是重复问题:
为什么在C语言中a+++++b不能正常工作?

我从David Simon的《嵌入式软件基础》第113页上看到了这个内容。

我看到了下面这个语句:

iHoursTemp = iHoursTemp + iZoneNew ---iZoneOld;

在这一行中,你真的可以有三个减号吗?三个减号代表什么意思?

我认为这是C编程语句。


58
如果你知道如何在队友的愤怒中生存下来,你就可以做到。 - R. Martinho Fernandes
8
@elyashiv,不要过分依赖简单的测试结果。在每个角落都潜伏着未定义的行为。 - R. Martinho Fernandes
10
又是一个值得获得“棘手问题”徽章的问题 - 诱骗多个被贬低的回答。 - Mysticial
7
等一下,这个内容在一本没有解释的书里?哦天啊! - chris
5
有趣的事实: iZoneNew --+--iZoneOld 可以编译并且会按预期工作。然而 iZoneNew -----iZoneOld 将无法编译,因为编译器会将其解释为 ((iZoneNew--)--) - iZoneOld - Leo
显示剩余12条评论
5个回答

95

它相当于:

iHoursTemp = iHoursTemp + (iZoneNew--) - iZoneOld;

这符合最大匹配原则


9
终于,一个完全正确的答案 :) - chris
1
为什么有人想要像原始语句那样编程呢?难道你不认为像这样修改过的语句对计算机来说更好、更清晰吗?iHoursTemp = iHoursTemp - iZoneOld + (iZoneNew--); - Joseph Lee
8
没有人希望编写这个程序。然而,这并不是电脑的问题(如果您有正确的编译器,它会知道规则),而是人们会不断地无法理解它。说实话,我甚至不会进行内联递增,就像“可读”版本一样,除非性能绝对不允许将其拆分为几个语句。因为即使人们可以读懂它的含义,真正理解它还是有所不同。 - Thirler
然而,“++++”在语法规则中明确被禁止。我认为“--”和“++”也应该在C++标准中被给予“no-munch”条款。缺乏这一点可能是疏忽,而不是对这种可怕的编码风格的默许。 - Warren P
1
@WarrenP - "++++"在语法规则上并没有被“明确禁止”。请考虑这个程序 - Robᵩ

49

正确答案是(如Rob所说)以下内容:

iHoursTemp = iHoursTemp + (iZoneNew--) - iZoneOld;

原因在于它是这样而不是那样

iHoursTemp = iHoursTemp + iZoneNew - (--iZoneOld);

这是一种被称为最大匹配策略的约定,它指出如果下一个词元有多个可能性,则使用(取出)具有最多字符的那个。在本例中,可能性是-----显然更长。


为什么有人想要像原始语句那样编程呢?难道你不认为像这样修改过的语句对计算机来说更好、更清晰吗?iHoursTemp = iHoursTemp - iZoneOld + (iZoneNew--) - Joseph Lee
1
@JosephLee,是的,这样做会更好,更容易阅读。但是这个问题引发了关于编译器策略的有趣讨论。 - imreal
1
@Cthulhu,这很有趣,因为Rob是第一个在现在已删除的答案的评论中提到它的人。 - chris
@JosephLee 针对计算机?那人类读者呢?!!!!!1 - unwind
哈哈..哇,不知道呢。@chris我把定义加到他的答案中,表扬一下。 :) - Anirudh Ramanathan
1
我想不出任何情况,在同一表达式中混合使用 -- 或 ++ 运算符与其他运算符有任何意义。我可以想到许多情况会使读者感到困惑,并导致未定义或未指定的行为。因此,为了程序员自己以及人类读者的利益,修复此代码的正确方法是将 iZoneNew-- 移动到它自己的一行。 - Lundin

12
根据C++11草案 (PDF) 2.5 预处理令牌,第3条和C11草案 (PDF) 6.4 词法元素,第4条,编译器解析最长可能的字符序列作为下一个令牌。
这意味着---将被解析为两个令牌---,即
iHoursTemp = iHoursTemp + (iZoneNew--) - iZoneOld;

这也表明,如果您对优先级或解析规则不确定,请使用括号来澄清代码。


3
只允许这些解释中的一个。 - R. Martinho Fernandes
22
有的。在C99标准中,第6.4节"词法元素"第4段规定:"如果输入流已经解析成预处理记号到给定字符,下一个预处理记号是可以构成预处理记号的最长字符序列"。这被非正式地称为最大匹配原则,在这里的注释和其他答案中已经多次阐述过。 - R. Martinho Fernandes
11
在C++11中,它在§2.5预处理记号的第3段中:“如果输入流已经解析为给定字符的预处理标记:[原始字符串文字的规则] [< ::]的规则]- 否则,下一个预处理标记是最长的字符序列,即使这会导致进一步的词法分析失败也是如此。”看起来你没有仔细查找。 - R. Martinho Fernandes
2
17下,4上 - 按我的计算,这意味着@OlafDietsche在此答案上增加了6个声望。分享并享受 :-) - Bob Jarvis - Слава Україні
3
很酷,为了不放弃面对这么多的负评而向你致敬。我刚刚取消了我的反对票,并给了你一个赞 :) - jalf
显示剩余5条评论

5
等于
#include <stdio.h>

int main()
{

int iHoursTemp = 2, iZoneOld = 3, iZoneNew = 4;

//2+4 - 2 = 4
iHoursTemp = iHoursTemp + iZoneNew ---iZoneOld;
//2+(4--) -3 = 3   

printf("\n :%d \n", iHoursTemp);

return 0;

}

在gcc中给我3。

谢谢。我已经完全忘记了10年前的C语言编程。 - Joseph Lee
1
看看我的示例代码和结果。 - Jeyaram
@rjayavrp,iHoursTemp = 2 + 4 - (3 - 1); 括号起到了关键作用。 - chris
是的,正确。() 是改变游戏规则的关键 :) - Jeyaram
这个程序帮了我很多,谢谢。 - Joseph Lee

-9

当然可以,为什么不呢。

iHoursTemp = iHoursTemp + iZoneNew ---iZoneOld;

等同于

iHoursTemp = iHoursTemp + iZoneNew -(--iZoneOld); //first decrement iZoneOld then perform rest of the arithmetic operation.

一个小脑筋急转弯,但很有趣写的 :-)


6
不对,那是对那个陈述的错误解释。 - talonmies

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接