C语言中使用的括号及其用途

3

非常抱歉如果这个问题以前已经被问过了,但我是C语言的初学者,想知道有人能否帮忙解释以下代码中()括号的用法。

我从在线教程中获取它并且它也可以正常运行,但有一部分我不理解。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int age;
    printf("Please enter the age");
    scanf("%d", &age);
    if (age > 18 /*condition */ ) {
       printf("You may enter the club");
       if (age < 21)
       {
        printf("The age is greater than 18 but less than 21");

    }    else
        (printf("The age is greater than 18 and greater than 21"));


} else if (age == 18)
{
    printf("The age is equal to 18");
}
else {
    printf("The age is not greater than 18");
    }

return 0;
}

据我所了解,圆括号用于包含if语句的条件,花括号用于表明跟随该条件的操作。除了粗体字中嵌套的else条件外,在这种情况下,else语句后面跟着一个圆括号,其中包含了print命令。
有人能解释一下为什么会这样吗?

2
这些是完全冗余的。 - Eugene Sh.
1
那些可能被认为是错误的。那些应该是花括号。 - Carcigenicate
1
它们有效是因为printf()函数调用返回一个int- 它是一个表达式; 你可以将一个表达式放在()括号中进行分组,就像(5 + 3)一样。总之,最好找另一个教程。 - Antti Haapala -- Слава Україні
else 后面的括号风格很奇怪。它们按照运算顺序使用,但只有一个操作且是多余的。 - rtpax
我怀疑这是一个无害的打字错误,所以从未被修复,这肯定不是正常的。 - pm100
7个回答

7

圆括号()(以及花括号{})在不同的上下文中扮演不同的角色。

if语句中的花括号主要用于将多个语句组合成一个复合语句,作为if的真或假分支。例如,在您的情况下,if (age < 21)的每个分支已经是一个语句,因此其分支中的花括号并不是必需的。您可以将该if语句简写为:

if (age < 21)
  printf("The age is greater than 18 but less than 21");
else
  printf("The age is greater than 18 and greater than 21");

同时,if (age > 18) 的真分支包含多个语句,这就是为什么需要花括号的原因。

与此同时,围绕 if 条件的圆括号只是 if 语句的语法元素 - 语法要求在 if 条件周围使用一对圆括号,就像在 forwhile、函数调用和其他语法结构中需要圆括号一样。

但是,圆括号也可以在完全不同的角色中使用:在表达式中,它们的主要目的是将运算符与其操作数分组,例如 (2 + 2) * (5 - 3)。然而,在表达式中,您可以自由地使用冗余括号,例如您可以写成 (((2))) + (3) 而不是 2 + 3。或者您可以在整个表达式周围添加多余的括号,例如 (((2 + 3))) 而不是 (2 + 3) 等等。

这正是您在示例中观察到的情况。

printf("The age is greater than 18 and greater than 21");

这只是一个表达式语句,即由单个表达式组成的语句。该表达式是对printf的调用。如果您愿意,您可以将该调用括在任意数量的多余圆括号中。

(((printf("The age is greater than 18 and greater than 21"))));

这两个因素的组合:你不需要在 printf 周围加上 {},而且你可以在 printf 周围放置任意多的 (),这创造了一种错觉,即在该 printf 的情况下,一对 {} 被一对 () 替换了。实际上,这是两个完全不相关的操作。

无论如何,这只是一个语法上的奇特之处,没有任何实际价值。代码教程中发生了什么 - 任何人都猜不出来。

不更改其含义。


2
else条件应该加上花括号,表示哪些语句应该作为else子句的一部分执行。如果else子句中只有一个语句,则可以省略这些大括号,但有些人认为这是不好的编码风格。在这种情况下,大括号已被省略。此外,还添加了多余的普通括号,使代码更加混乱。
我强烈建议用花括号替换这些括号,即使代码在技术上是正确的。此外,代码应该以一致的缩进模式编写。这可以使程序的逻辑流程更容易跟踪:
int main()
{
    int age;
    printf("Please enter the age");
    scanf("%d", &age);

    if (age > 18 /*condition */ ) {
        printf("You may enter the club");
        if (age < 21) {
            printf("The age is greater than 18 but less than 21");
        }
        else {
           printf("The age is greater than 18 and greater than 21");
        }

    }
    else if (age == 18) {
        printf("The age is equal to 18");
    }
    else {
        printf("The age is not greater than 18");
    }

    return 0;
}

我相信这段代码不是原帖作者写的,他们是从在线教程中获取的。 - mgarey
刚刚注意到这个问题。已修复。 - TimD1
我担心这个答案中的断言对于一个新手来说不是很有帮助。我认为更有用的是观察到ifelse分支始终只执行一个语句,但它可以是由大括号括起来的零个或多个语句组成的复合语句。这展示了语言的一致性,而不是将其措辞为规则和例外。然而,在这种情况下,建议始终使用复合语句形式也是可以的。 - John Bollinger
生产力提示:错位的 if else 等代码意味着手动格式化。找一个接近你团队风格的自动格式化工具,并与之配合使用。将格式化细节留给自动化处理。 - chux - Reinstate Monica

0

我怀疑这是一个打字错误。任何表达式,包括括号内的表达式,都可以在任何时候引入。如果正确格式化,这里的大括号会更有意义,并且与代码的其余部分保持一致。


0

看起来像是笔误:没有合法的编程原因可以使用那些括号。但请注意,它可以正常编译,因为它什么也不做:(x)与x相同,因此在更多的括号中封装printf(...)是可接受的,但不会改变任何东西。


0

由分号;终止的表达式就成为了语句。

printf是一个返回int的函数。

因此,printf的结果是一个表达式(所以printf()是一个表达式)。

用大括号括起来的表达式也是一个表达式。

因此,大括号括起来并后跟分号的printf()就是一个语句。

语句必须跟随else。 因此,在这里没有语法问题。


0

你应该熟悉在数学表达式中常用的括号。

例如,3*(1+1)将计算为6,因为加法先于乘法进行,并且乘法使用右侧的值。

你可能不知道的是,在C语言中,函数调用也是表达式。因此,即使对于printf()的返回值没有任何操作,将其放在多余的括号中也是合法的(尽管有些古怪)。

因此,以下内容是有意义的:

  int count=printf("Hello");

假设没有错误,count将被初始化为5(打印的字符数)。但是写成以下形式同样有效(尽管多余):
  int count=(printf("Hello"));

但是赋值不影响语法,以下代码都是合法且等效的。

printf("Hello");
(printf("Hello"));

0

这是合法的,但完全没有用处,这要归功于 C 语言灵活的语法系统。

这个表达式是合法的:

int i =  printf("The age is greater than 18 and greater than 21");

可以是这样的

int i =  (printf("The age is greater than 18 and greater than 21"));

并且可以是这样的

(printf("The age is greater than 18 and greater than 21"));

如果printf返回void,那么它是不合法的。 将其视为一个用括号括起来但未使用其值的表达式。这可能是一个打字错误,因为代码仍然是合法的。


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