【问题标题】:The else condition does print anything when printf is used in ternary operator.. why?当 printf 在三元运算符中使用时,else 条件会打印任何内容。为什么?
【发布时间】:2019-04-14 07:29:12
【问题描述】:

三元运算符中的else部分是printf语句在代码中不起作用,语法是否正确??还是一些愚蠢的错误??

#include<stdio.h>
#define isNegative(x) x<0 ? 1 : 0
#define isPositive(x) isNegative(x) ? 0 : 1
#define isEven(x) x%2 ? 0 : 1
#define isOdd(x) isEven(x) ? 0 : 1
main(){
 int n,ch;
do{
printf("Enter a number\n");
scanf("%d",&n);
printf("Choose an operation :\n 1.isEven\n 2.isOdd\n 3.isPositive\n 4.isNegative\n");
scanf("%d",&ch);
switch(ch){
case 1 :isEven(n) ? printf("Its even number\n") : printf("Its not an even number\n") ;
        break;
case 2 :isOdd(n) ? printf("Its odd number\n") : printf("Its not an odd number\n") ;
        break;
case 3 :isPositive(n) ? printf("Its a positive number\n") : printf("Its not a positive number\n");
        break;
case 4 :isNegative(n) ? printf("Its a negative number\n") : printf("Its not a negative number\n");
        break;
default : printf("Enter valid option\n");
        break;
}
printf("Press 5 to continue or 6 to exit\n");
scanf("%d",&ch);
}while(ch!=6);
}

代码的逻辑是否正确? 头文件内容

【问题讨论】:

  • 这可能会有所帮助 - stackoverflow.com/questions/5240789/…
  • 不工作”是一个或多或少值得的故障报告。请更具体。你得到了什么?你期望得到什么?
  • @alk 替换 else 的第二条语句不起作用......真正的条件有效,但不是假的......除了最后一个
  • 为什么不只是printf("It's %san even number\n", isEven(n) ? "" : "not ")?但在实践中,使用printf("It's an %s number\n", isEven(n) ? "even" : "odd") 通常更有用

标签: c


【解决方案1】:

三元运算符不像if-then-else 语句;它本身就是一个表达式,这意味着它的 value 是以通常的方式计算的值。您在代码中看不到它,因为您使用的三元运算符表达式的结果没有被任何人捕获。这在 C++ 中被称为 rvalue

您实际上可以通过这样做向自己证明这一点:

size_t i = 1;    
(i == 2) ? printf("hello\n") : printf("goodbye\n")

输出:

goodbye

这里我们只是评估谓词并评估“else”表达式。毫不奇怪,输出是goodbye。但这并不是故事的全部。

很多人没有意识到printf 有一个返回值。它返回写入标准输出的字符数,或者在fprintf 的情况下返回到您指定的任何输出流。与scanf 函数一样,printfs 将在错误时返回负数。这就是为什么检查 scanf 的返回值很重要的原因。不幸的是,很多人没有意识到这些函数有返回值,所以很明显他们不会检查他们不知道存在的东西。

不过,通过下一个示例,您可以清楚地看到三元表达式的返回值。

size_t i = 1;    
int result = (i == 2) ? printf("hello\n") : printf("goodbye\n");
printf("Result: %d\n", result);

输出:

goodbye
Result: 8

回到实际的三元运算符,我想强调它是一个表达式。如果你愿意的话,你在函数式编程语言中经常看到这样的事情,尽管不是相同的“形状”。 printf 函数打印到 stdout 的事实就是所谓的副作用,在仍然拥有有用的编程语言的同时尽可能减少副作用的概念是函数式编程的基础之一。


回答您的具体问题:

代码的逻辑是否正确?

我重新格式化了一些代码并添加了大量括号。在同时使用宏和三元运算符时必须非常小心,以确保括号正确,否则会出现类似的错误。

#include <stdio.h>

#define isNegative(x) x<0 ? 1 : 0
#define isPositive(x) isNegative(x) ? 0 : 1
#define isEven(x) x%2 ? 0 : 1
#define isOdd(x) isEven(x) ? 0 : 1

int main()
{
    int n, ch;

    do {
        printf("Enter a number\n");
        scanf("%d", &n);

        printf("Choose an operation :\n 1.isEven\n 2.isOdd\n 3.isPositive\n 4.isNegative\n");
        scanf("%d", &ch);

        switch (ch) {
            case (1): ((isEven(n)) ? printf("Its even number\n") : printf("Its not an even number\n"));
                break;
            case (2): ((isOdd(n)) ? printf("Its odd number\n") : printf("Its not an odd number\n"));
                break;
            case (3): ((isPositive(n)) ? printf("Its a positive number\n") : printf("Its not a positive number\n"));
                break;
            case (4): ((isNegative(n)) ? printf("Its a negative number\n") : printf("Its not a negative number\n"));
                break;
            default: printf("Enter valid option\n");
                break;
        }

        printf("Press 5 to continue or 6 to exit\n");
        scanf("%d",&ch);
    } while(ch != 6);

    return EXIT_SUCCESS;
}

执行:

Enter a number
5
Choose an operation :
 1.isEven
 2.isOdd
 3.isPositive
 4.isNegative
4
Its not a negative number
Press 5 to continue or 6 to exit
5
Enter a number
3
Choose an operation :
 1.isEven
 2.isOdd
 3.isPositive
 4.isNegative
3
Its a positive number
Press 5 to continue or 6 to exit

希望这会有所帮助,伙计,祝你好运。如果您有任何问题,请告诉我。

【讨论】:

  • 我会在宏定义周围加上括号,如下所示:#define (isNegative(x) x&lt;0 ? 1 : 0)
  • @Jose Fernando Lopez Fernandez 谢谢,它的工作原理.. 但我在这些宏中添加了括号,而不是在 main 方法中添加它们,它也有效......这些括号如何影响返回值? ?
  • 问题是,C 预处理器正在查找和替换这些宏,它没有做任何特别的事情。所以问题是,虽然有时你可以逃脱不完美的括号纪律,但有时你并不那么幸运。这些错误可能特别难以找到,因为编译器和您正在查看不同的源文件,所以如果您用尽了想法,那么尝试的一个好方法是在不编译的情况下运行预处理器并查看预处理的源文件是否真的看起来像它应该是什么。
猜你喜欢
  • 2020-02-02
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 2022-12-06
  • 1970-01-01
  • 2015-05-30
  • 2013-10-30
  • 1970-01-01
相关资源
最近更新 更多