【问题标题】:C – How to use an exit/return statement in ternary operator?C – 如何在三元运算符中使用退出/返回语句?
【发布时间】:2021-02-13 04:10:18
【问题描述】:

我想用更短的方式来表述这两个 if 语句:

//FUNCTION PROTOTYPES
int checkCommandLineArguments(int argc, char *argv[]);
int checkFile(char *argv[]);

//MAIN FUNCTIONxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
int main(int argc, char *argv[])
{
    checkCommandLineArguments(argc, &argv[1]);
    checkFile(&argv[1]);
    return 0;
}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx



//F1–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
int checkCommandLineArguments(int argc, char *argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./recover image\n");
        exit(1);
    }
    return 0;
}
//–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

//F2–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
int checkFile(char *argv[])
{
    FILE *file = fopen(argv[1], "r");
    if (NULL == file)
    {
        printf("Cannot open file!\n");
        exit(1);
    }
    return 0;
}
//–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

我考虑过使用三元运算符:

(argc != 2) ? printf("Error X\n"), exit(1) : (NULL == file) ? printf("Cannot open file!\n"),
        exit(1): return 0 ;

但是,它似乎不起作用(可能是因为返回/退出语句)。我该如何解决这个问题,或者有任何其他(更合适的)方法可以做到这一点?

谢谢!

编辑 1 有人评论说三元运算符不适用于语句,因此该选项不在讨论范围内。 但是,我仍在寻找更好的方法来做到这一点。

编辑 2 我添加了一个更扩展的代码示例,因为它已在 cmets 中被要求。

【问题讨论】:

  • 最好不要尝试将难以阅读的代码塞进一行。一种方法是创建自己的myexit(char *reason) 函数,然后可以将代码缩短为if (NULL == file) myexit("Cannot open file!");(两行)。
  • 您是否认为它使您的代码更具可读性或效率?不,不是。
  • 这能回答你的问题吗? Ternary operators and Return in C 简短回答:你不能,但是你可以返回一个三元表达式。无论如何,两个嵌套的三元运算符,逗号运算符......你可能认为这很酷,但事实并非如此。编写干净的代码,这是很酷的代码。
  • 不推荐,这是有效的:int cond = 1; cond ? (void)puts("hello") : exit(1);(同时表达真假void
  • @dtell 我也会接受“哇,读起来像 Perl”。

标签: c conditional-statements conditional-operator


【解决方案1】:

如何在三元运算符中使用退出/返回语句?

你不能。三元运算符的第二个和第三个操作数必须是表达式,return statement 不是表达式(参见Ternary operators and Return in C)。但是,允许两者都是 void 表达式,例如 exit(1),在这种情况下,操作的结果也是 void 表达式。

此外,对于您的特定代码,逗号运算符 (,) 在所有 C 运算符中的优先级最低。因此,如果您打算在任何其他操作中使用逗号表达式作为操作数,则需要将其括起来。

我想用更短的方式来表述这两个 if 语句:

为什么?仅仅简洁或简洁不是一个有用的目标。如果它使您的代码难以让人阅读和理解,那么缩短您的代码就是一种负担。

但如果你的意思是你想要更简单、更清晰和/或更少冗余地表达同样的事情,那么可以引导您使用更短的表格。例如,您可以将逻辑封装在函数或宏中。我个人经常提供一个看起来像这样的宏:

#define ERROR_IF_NZ(cond, message) do { \
    if (cond) { \
        fputs(message, stderr); \
        exit(1); \
    } \
} while (0)

使用它,您的代码可能如下所示:

ERROR_IF_NZ(argc != 2, "Error X\n");
ERROR_IF_NZ(NULL == file, "Cannot open file!\n");

调整宏名称,使其对您最有意义,然后看!它不仅比原始代码更清晰,而且更短,即使你计算宏定义的长度。

更新

对该问题的编辑几乎已经提出了这个答案。如果您已经拥有与此处描述的宏具有相同作用的函数,则只需调用它们即可。用三元表达式替换函数和对它们的调用没有任何价值,也不值得将您拥有的函数转换为宏。当然,减少源代码大小并不是进行此类更改的合理动机。

【讨论】:

  • 你为什么使用宏?一个函数完全能够表达这种重复
  • @Alexander-ReinstateMonica,谁说必须为函数无法解决的情况保留宏?我想我使用宏是因为我有一些老派的习惯。这是一种风格选择。
  • 事实上,我听过很多人这么说。有很好的理由:1)(正确)宏需要do { } while (0)和`\`废话,2)宏在某些编辑器和大多数网站(SO,GitHub等)中无法突出显示代码,3)它在性能方面是不必要的(优化器可以同时内联函数和错误的“大纲”宏,所以它实际上并没有做任何事情)
  • 嗨@JohnBollinger,我喜欢你的回答方式。但是我没有那么有经验,所以如果你能更详细地解释一下你的宏是如何工作的,那将对我有很大帮助。非常感谢。
  • @Alexander-ReinstateMonica,抱歉,我说错了。我的意思是,“无论我关心谁的意见,我都会说 [...]”。我没有对性能或内联做出任何断言,我认为没有理由将您提出的其他观点归类为风格考虑以外的任何内容。正如我所说,在我使用宏的地方,例如呈现的宏,这是一种风格选择。
【解决方案2】:

您通过编辑添加的代码是可读的,或多或少都很好,您不需要使用三元运算符技巧来混淆它。

只有checkFile 是毫无意义的,你打开文件然后退出函数而不对文件做任何事情并最终泄露文件句柄。

你可能想要这个模式:

int main(int argc, char *argv[])
{
    checkCommandLineArguments(argc, &argv[1]);
    FILE *file = checkFile(&argv[1]);

    // do stuff with file

    fclose(file);
    return 0;
}

FILE *checkFile(char *argv[])
{
    FILE *file = fopen(argv[1], "r");
    if (NULL == file)
    {
        printf("Cannot open file!\n");
        exit(1);
    }
    return file;
}

【讨论】:

    猜你喜欢
    • 2012-08-28
    • 2018-05-30
    • 2019-11-08
    • 1970-01-01
    • 2011-04-24
    • 2019-11-14
    • 2020-04-30
    • 2020-08-02
    • 2016-03-05
    相关资源
    最近更新 更多