C# 为什么C语言在if语句中需要一个简单条件的参数?

C# 为什么C语言在if语句中需要一个简单条件的参数?,c#,java,javascript,c++,c,C#,Java,Javascript,C++,C,这听起来很愚蠢,但多年来我一直无法想出一个需要这样做的用例。快速的谷歌搜索并没有发现任何有价值的东西 根据记忆,比亚恩·斯特劳斯特鲁普提到了一个用例,但我找不到它的参考 那么,为什么不能在C语言中使用此功能: int val = 0; if val doSomehing(); else doSomehinglse(); 我可以接受“我们不必费心添加对lexer的支持”的理由,我只是想弄清楚这种语法是否会破坏其他语言结构。考虑到C/C++中有多少古怪的语法特性,我几乎不认为这会增加太多的

这听起来很愚蠢,但多年来我一直无法想出一个需要这样做的用例。快速的谷歌搜索并没有发现任何有价值的东西

根据记忆,比亚恩·斯特劳斯特鲁普提到了一个用例,但我找不到它的参考

那么,为什么不能在C语言中使用此功能:

int val = 0;
if val
  doSomehing();
else
  doSomehinglse();

我可以接受“我们不必费心添加对lexer的支持”的理由,我只是想弄清楚这种语法是否会破坏其他语言结构。考虑到C/C++中有多少古怪的语法特性,我几乎不认为这会增加太多的复杂性。

我认为一个更好的问题是“我们为什么想要这样的东西?”而不是“我们为什么没有它?”。它在lexer中引入了另外一个不必要的边缘大小写,这样你就可以避免额外键入4个字符;并且通过允许已经支持所有可能情况的简单语法出现异常,增加了规范的复杂性。更不用说歧义了,这在编程语言中没有多大价值。

如果在
If
构造中表达式周围没有括号,那么下面的语句是什么意思

if x * x * b = NULL;
是吗

还是这样

if (x)
    (*x) * b = NULL;
(当然,这些都是愚蠢的例子,因为显而易见的原因都不起作用,但你明白了)


TLDR:C中需要括号来消除任何语法歧义的可能性。

我想不出任何特定情况下省略paren会导致任何歧义,但可能在某个地方有一个角落

它可能与本地声明的变量有关(如
if(bool b=foo())如果没有括号,就很难确定
bool
是类型声明还是整个条件。在后一种情况下,
b
将是if语句体的第一个标记,而不是条件的一部分。

我认为您混淆了“括号”和“括号”

这在C中是可能的:

void doSomething(){}
void doSomethingElse(){}

void main() {
    int val = 0;
    if( val ) 
        doSomething();
    else
        doSomethingElse();
}

并不是所有的“C”语言都强制使用括号,并将大括号保留为可选。Go(问题)编程语言正是这样做的

在第9期中,正确的写法是:

if val {
    doSomething();
} else {
    doSomethingElse();
}
这样,以下内容无效:

if x * x * b = NULL; 
它应该是以下内容之一:

if x*x {
    *b=NULL;
}
或 如果x{ xb=NULL; }


这里大括号消除了由于缺少括号而产生的歧义。

我至少可以举一个例子,说明为什么C语言中存在对条件的偏执

例如考虑以下

while(1) do_something();
上面将在无限循环中永远调用do_something()

之所以需要parenthis,是因为以下内容不明确

while 1;dou_something();
这是否意味着,在while循环中计算do_something而不计算doo_nothing?还是与上面的代码示例相同

我想这说明了为什么在C语法中,条件求值需要parenthis,并且通过扩展相同的语法(为了一致性),它被扩展到if语句


Discalaimer:我可能完全错了,拥有pranthesis的原因可能完全不同,但至少我已经展示了一个它如何有用的例子告诉我如何解释以下内容:

if x ++ b;
看起来很傻,但是

if( x ) ++b;

或者“x”有一个重载运算符,那么

if( x ++ b){;}
编辑:


正如马丁·约克所指出的“++”有一个更高的优先级,这就是为什么我必须添加运算符重载的TIDIT。在处理现代编译器时,他是完全正确的,直到你允许C++中所有超载的好处。

< P> >记住:C是在磁带存储很常见的时候创建的,所以随机查找或BAC。通过当前文件甚至其他文件进行KWARD实际上是不可行的(这也解释了为什么您必须将某些内容(即转发声明)放在其他内容(即函数的使用)之前,即使编译器应该能够自己解决它).

我也喜欢这种语法,但为了避免解析歧义,必须采用以下形式:

对于多个语句:

if val 
{ 
    doSomething();
    doOthers();
}
一句话:

if val: 
   doSomething();

这只是一种结束语句条件子句的方法。 其他语言使用其他方式,如“then”或Python中的“if condition:(后跟返回)” (问题:总是让我使用python,我总是忽略它们,结果会出现一些不明显的错误。)


计算机语法通常喜欢一些独特的机制来识别语句或表达式的不同部分。在这方面,它并不比任何其他语言更好或更差。C/C++的dangle else问题是一个从语法角度来看的歧义示例,必须作为特例来处理,以确保正确操作。(也就是说,它为编译器实现者增加了额外的工作。)

除非您需要大量的空白,否则您需要能够知道条件何时结束 在某些语言中,它是()围绕着条件,在某些语言中,它是关键字,然后是if,就像答案中给出的那样


如果x*x*b=NULL可能是一个总是求值为false的条件,那么在(xx)的情况下,一个将NULL赋值给b的条件,编译器无法知道该条件何时结束以及以下操作何时开始。因此,编译器需要有一个显式的“返回标记”来知道该条件何时结束。在C(++)中,Java,c#和其他语言它()在F#中标记条件,它是关键字“then”,在其他语言中它是换行/缩进,因为c允许这样做:

if (x) { // As opposed to java where you need to do if (x == something)
   // your code
}

正如您所看到的,正如其他人所示,灵活性会引起歧义。

根本原因是C和friends没有“then”关键字,因此他们需要另一种方法来定义条件表达式
if val: 
   doSomething();
if (x) { // As opposed to java where you need to do if (x == something)
   // your code
}