【问题标题】:How to do short circuit print in C?如何在C中进行短路打印?
【发布时间】:2021-10-07 14:50:02
【问题描述】:

大家好:我有这样的表达方式:

if (a == 1) {
   printf("hello\n");
}

有没有办法做这样的事情?

 a== 1 && printf("hello\n");

这叫做短路表达式,但我对此一无所知。它存在于C中吗?怎么做。

【问题讨论】:

  • 如果您有if(a && b),如果a 产生false,则不会评估表达式b。这是短路。但是,如果您的任何表达式有副作用,这是一个糟糕的设计
  • 是的,这适用于 C:godbolt.org/z/TKc55Td6T 并不意味着您应该这样做。在大多数情况下,if 声明通常会更清晰。
  • 即使是有效的 C 代码也不要这样做。除非您参加的是混淆 C 竞赛,否则请关注可读性。
  • 你也有三元运算符方式:a==1?printf("hello\n"):0;,反正这里的可读性不是很好。一个简单的if 似乎是最有效和可读的。看看@alagner 的回答,从我的观点来看,内部三元的可读性较差。
  • 您的两个示例都是完全相同的。一个更好的例子是两件事,例如a == 1 && b == 2 && whateverif (a== 1 && b == 2) { whatever } 在这种情况下它们将完全相同。

标签: c if-statement printf expression short-circuiting


【解决方案1】:

正如 cmets 中已经指出的那样,执行 a == 1 && printf("hallo\n"); 确实会按照我的预期工作,即只有在条件为真时才会打印“hallo”,如果在这种情况下 a 为 1。简短的回答是肯定的,短路表达式确实存在于 C 中。

这可以通过编译和运行代码轻松确定,如果您只是在探索该语言的工作原理,这是推荐的方法。但是,如果问题是,“使用它来决定何时打印是一种好习惯吗?”,很多人会说。最好使用示例中的if 语句,使用更易读、更易于维护的代码。

【讨论】:

    【解决方案2】:

    这里有个警告: 只要&& 右侧的表达式返回可转换为布尔值的东西,它就可以工作,例如在这种情况下,printf 返回一个 int。它是有效的 C 代码,没错,但对我来说似乎是一种代码味道,很多人会在审查期间抱怨。

    还要注意,是这样的:

    void foo(char*)
    {
    //whatever
    }
    
    int main(void)
    {
        int a = 1;
        a == 1 && foo("abc");
    }
    

    不会起作用,您将不得不使用一些技巧,例如带逗号运算符: a == 1 && (foo("abc"),1);

    因此,为了可维护性,您可能希望使用其他构造,例如三元运算符: printf(a==1?"Hello\n":""); 这不完全等效,但在您的特定情况下可能(或可能不会)更好地工作。

    编辑: 根据以下评论:

    确实,将条件输入传递给 printf 的格式字符串可能被认为是一种不好的做法,尤其是在更复杂的情况下,因为消除了与 printf 的输入参数相关的编译器诊断之一。 @chqrlie 建议仅在以下情况下使用单行:if(a==1)printf("hello\n");,只要编码约定允许,这很好。有时他们不会。

    如果是这样,更简洁的三元版本是:printf("%s",a==1? "Hello\n":"");。但是请注意,这完全取决于编码约定/程序员和审阅者的品味/linter 设置/在此处插入您的良好实践来源。因此,人们很可能可以用更多方式给这只猫剥皮,而且这份清单绝对不是详尽无遗的。

    【讨论】:

    • 很好的答案,但我不建议,甚至不建议printf(a==1?"Hello\n":"");,这会破坏编译器对printf 的变量参数进行类型检查的能力。更可口的单线替代品是if (a == 1) printf("hello\n);
    • @chqrlie printf("%s", condition?"hello\n":""); 怎么样?我经常会使用one-liner if 比问号更大的禁忌代码,所以这可能只是我的品味/习惯。但是当然,将裸字符串传递给 printf 也不是很好。
    • 调用 printf("") 会消耗 CPU 周期。不叫就不行。就这么简单。
    猜你喜欢
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多