为什么C语言需要在if语句中围绕一个简单条件的parens?

时间:2010-01-14 01:18:53

标签: c# java javascript c++ c

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

从内存中有一个Bjarne Stroustrup提到的用例,但我找不到它的引用。

那你为什么不能用C语言呢?

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

我可以接受“我们不能为添加对词法分析器的支持而烦恼”的原因,我只想弄清楚这种语法是否打破了其他语言结构。考虑到C / C ++中有多少令人讨厌的语法特性,我几乎认为这不会增加太多的复杂性。

13 个答案:

答案 0 :(得分:48)

如果if构造中的表达式周围没有括号,以下语句的含义是什么?

if x * x * b = NULL;

是吗

if (x*x)
    (*b) = NULL;

或者是

if (x)
    (*x) * b = NULL;

(当然这些都是愚蠢的例子,甚至没有明显的原因,但你明白了)

TLDR:C中需要使用括号来消除任何语法模糊的可能性。

答案 1 :(得分:12)

告诉我如何插入以下内容:

if x ++ b;

看起来很傻但是......

if( x ) ++b;

if( x++ ) b;

或者“x”有一个重载的运算符然后......

if( x ++ b){;}

编辑:

正如Martin York所说,“++”具有更高的优先级,这就是为什么我必须添加运算符重载tidbit的原因。在处理现代编译器时,他是完全正确的,直到你允许C ++带来的所有重载优势。

答案 2 :(得分:4)

我认为一个更好的问题是“为什么我们想要这样的东西?”比“我们为什么不拥有它?”它在词法分析器中引入了另一个不必要的边缘情况,这样就可以避免输入4个额外的字符;通过允许对已经支持所有可能情况的简单语法的例外,可以增加规范的复杂性。更不用说在模糊语言中没有多少价值的模糊性。

答案 3 :(得分:1)

另外还有一件事要记住:C是在磁带存储很常见的时候创建的,因此随机搜索或向后查看当前文件甚至其他文件并不是真的可行(这也解释了为什么你必须把一些东西(即前向声明)放在其他东西(即函数的使用)之前,即使编译器应该能够自己解决它。)

答案 4 :(得分:0)

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

用于多个陈述:

if val 
{ 
    doSomething();
    doOthers();
}

一个陈述:

if val: 
   doSomething();

答案 5 :(得分:0)

它只是结束语句的条件子句的一种方法。 其他语言使用其他方式,如“then”或Python“如果条件 :(后面跟着返回)” (:总是让我进入python我会一直把它们排除在外并得到错误,而不是因为结果不是很明显。)

计算机语法通常喜欢一些独特的机制来识别语句或表达的不同部分。在这方面,它比任何其他语言都没有更好或更差。 C / C ++的其他问题是从概率的角度来看的模糊性的一个例子,必须作为特殊情况来处理,以确保正确的操作。 (即它为编译器实现者增加了额外的工作。)

答案 6 :(得分:0)

除非您需要大量空白,否则您需要能够判断条件何时结束 在某些语言中,它是()围绕条件的某些它是关键字然后是一个如果在答案中给出的那个

如果x * x * b = NULL可能是一个总是评估为false的条件,则在(x x)的情况下为 b分配null,编译器无法知道何时条件结束并开始以下操作。因此,需要有一个明确的“后退标记”,以便编译器知道条件何时结束。在C(++),Java,c#和其他语言中,它标记了F#中的条件,它是关键字“then”,而在其他语言中,它是换行符/缩进

答案 7 :(得分:0)

根本原因是C和朋友没有'then'关键字,所以他们需要另一种方法来分隔条件表达式。像Pascal和PL / 1这样的语言不需要括号。同样适用于'while',其中Pascal,PL / 1等具有'do'。

答案 8 :(得分:0)

这是因为它可以帮助程序员使编译器理解表达式(包括一系列算术,逻辑,赋值等运算符类型)需要按哪个顺序求解才能得到所需的输出。

答案 9 :(得分:-1)

我认为你将“括号”与“括号”混为一谈

这在C:

中是可能的
void doSomething(){}
void doSomethingElse(){}

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

<击>

并非所有“C”语言都强制使用parethesis,并将大括号保留为可选。 Go(问题)编程语言与opposite完全相同。

在Issue9中编写相同句子的正确方法是:

if val {
    doSomething();
} else {
    doSomethingElse();
}

这样,以下内容无效:

if x * x * b = NULL; 

它应该是以下之一:

if x*x {
    *b=NULL;
}

或    如果x {         X B = NULL;    }

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

答案 10 :(得分:-1)

我可以给出至少一个例子,为什么在C中有条件的约束,

例如,请考虑以下内容

while(1) do_something();

以上将在无限循环中永远调用do_something()

需要parenthis的原因是因为以下内容不明确

while 1 ; do_something(); 这是否意味着,评估do_something并在while循环中什么都不做?或者它是否与上面的代码示例相同?

我想这表明为什么在C语法中为什么需要围绕条件评估,并且通过扩展相同的语法(为了保持一致),它会扩展到if语句。

Discalaimer:我可能完全错了,并且完全不同的原因可能完全不同,但至少我已经展示了它如何有用的一个例子

答案 11 :(得分:-2)

我想不出任何具体案例,省略这些案例实际上会引起任何歧义,但某处可能存在一个角落案例。

它可能与本地声明的变量有关(如if (bool b = foo())...中没有括号,更难确定bool是一个类型声明还是整个条件。 case,b将成为if语句主体的第一个标记,而不是条件的一部分。

答案 12 :(得分:-2)

因为C允许人们这样做:

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

正如你所看到的,灵活性会引起歧义,正如其他人所表明的那样。