关于如何理解printf(“%d \ n”,({int n; scanf(“%d”,& n); n * n;}));在C中工作

时间:2013-04-26 15:51:34

标签: c printf block

我通过quora answer

看到了这个程序
 #include<stdio.h>
 int main() {
    printf("%d\n", ( { int n; scanf("%d", &n); n*n; } ));
    return 0;
 }

我想知道这是如何工作的,如果这符合标准?

3 个答案:

答案 0 :(得分:7)

此代码使用名为statement-expressions的“GNU C”功能,其中括号括起的复合语句可用作表达式,其类型和值与复合语句中最后一个语句的结果相匹配。这不是语法上有效的C,而是一个GCC特性(也被一些其他编译器采用),这可能是因为它被认为对编写不会多次评估其参数的宏很重要。

如果你在必须阅读的代码中遇到它,你应该知道它是什么以及它做了什么,但我会避免自己使用它。这是令人困惑,不必要和非标准的。使用静态内联函数几乎总能实现同样的功能。

答案 1 :(得分:0)

我认为它不起作用... n在大括号内有本地范围...当你退出大括号时,n变得未定义但我认为可以< / strong>仍然存在于堆栈的某个位置,可能工作。它正在乞求实施问题,我保证是依赖于实现的。

我可以告诉你的一件事是,任何为我写作的人都会读到暴乱行为。

答案 2 :(得分:0)

有效。我没有得到gcc的警告,所以我认为它符合标准。

魔术就是封闭:

{ int n; scanf("%d", &n); n*n; }

这个块从控制台扫描一个整数(没有错误检查)并将其平方,返回平方数。在C的古老实现中,返回堆栈上的最后一个数字。 n*n将数字放在堆栈上。

该值传递给printf:

printf("%d\n", <scanned>);

所以,回答你的问题:是的,它有效。是的,这是“标准”(在任何人都完全遵循标准的程度)。不,这不是一个很好的做法。这是一个很好的例子,我通过下意识反应称之为“编译器情书”,主要是为了表明程序员有多聪明,不一定能解决问题或提高效率。