0

我在 c89 模式下使用 gcc 4.7.0。

我有这个 if-else 语句并且有 2 个问题。

  1. 我只是想知道我应该先测试 FALSE 还是 TRUE 条件。什么通常更好。我知道这没有太大区别,但我只是想知道其他工程师是做什么的?在下面的示例中,我首先检查 FALSE。

  2. 我总是喜欢做一些防御性编程。因此,如果我可以明确检查每个条件,我总是会这样做。例如,而不是做 if() - else。我会做 if() - else if()。在下面的示例中,条件可以是 TRUE 或 FALSE。但是,我总是喜欢检查 else 条件以确保它为 TRUE。这有什么实际意义吗?

非常感谢您的任何建议。

if(event->status == FALSE) {
    g_release_call_test(module, channel_id);
}
else if(event->status == TRUE) {
    if(UNIT_TEST & KARAOKE) {
        if(g_record_karaoke(module, channel_id) == FALSE) {
            g_release_call_test(module, channel_id);
        }
    }
    else if(UNIT_TEST & RECORD) {
        if(g_record_file_test(module, channel_id) == FALSE) {
            g_release_call_test(module, channel_id);
        }
    }
    else if(UNIT_TEST & GET_DIGITS) {
        if(g_collect_digits_test(module, channel_id) == FALSE) {
            g_release_call_test(module, channel_id);
        }
    }
}
4

4 回答 4

2
  1. 我只是想知道我应该先测试 FALSE 还是 TRUE 条件。什么通常更好。我知道这没有太大区别,但我只是想知道其他工程师是做什么的?在下面的示例中,我首先检查 FALSE。

    对您的条件进行分析。如果您有一些数据显示 20% 的情况为 False,80% 的情况为 true,请将 true 分支放在第一个分支。在某些情况下,这可能有助于提高性能。

  2. 我总是喜欢做一些防御性编程。因此,如果我可以明确检查每个条件,我总是会这样做。例如,而不是做 if() - else。我会做 if() - else if()。在下面的示例中,条件可以是 TRUE 或 FALSE。但是,我总是喜欢检查 else 条件以确保它为 TRUE。这有什么实际意义吗?

    除非您担心 event->status 可能会被一些技巧问题损坏,否则在大多数情况下,我认为我们只使用 if (!event->status) else 样式

于 2012-09-05T05:10:39.567 回答
1

1)我只是想知道我应该先测试 FALSE 还是 TRUE 条件。什么通常更好。我知道这没有太大区别,但我只是想知道其他工程师是做什么的?在下面的示例中,我首先检查 FALSE。

从语法上讲,它并没有太大的区别,再次明智地编程通常并不重要。但是,对于特定用例,它可能会影响性能。让我们考虑一个例子,如果你正在播放一个媒体文件并且这个条件是检查它是媒体帧还是标题。在这里,您知道标题后面将有 100 个媒体帧,因此您需要检查媒体帧然后是标题。因为检查标头意味着 100 次冗余检查 == 100 条冗余 CPU 指令 [可能更多]。除非您正在编写一般的东西,否则根据您的用例编写代码总是更好。

2)我总是喜欢做一些防御性编程。因此,如果我可以明确检查每个条件,我总是会这样做。例如,而不是做 if() - else。我会做 if() - else if()。在下面的示例中,条件可以是 TRUE 或 FALSE。但是,我总是喜欢检查 else 条件以确保它为 TRUE。这有什么实际意义吗?

防御性编程有其优点和缺点。在上述场景中,编译器将为您进行必要的优化。

你可能想看看这里 http://www.eventhelix.com/realtimemantra/basics/optimizingcandcppcode.htm#

干杯..快乐学习

于 2012-09-05T05:00:32.003 回答
1

1)您首先检查哪个条件并不重要,因为编译器会为您优化代码。

2) 如果status只能有两个值 ( TRUE/FALSE),那么else if对于普通读者来说,有一个似乎有点令人困惑。另一方面,如果status可以有其他值,那么第三个 else 部分将与assert(). 一般来说,添加断言是一个很好的习惯,可以添加到你的防御工具箱中以捕捉错误的假设。

于 2012-09-05T05:00:35.710 回答
1

首先,不要对布尔值执行此操作:

if (something == TRUE)
if (something == FALSE)

这些应该是这样的:

if (something)
if (!something)

布尔值也应该被智能命名,以便if语句自然阅读,例如if (isFinished)or while (stillSomeMoreToGo)status不是布尔值好名字,除非它是为了表明某物具有状态,即使那样,我也会使用hasStatus或类似的东西。

在任何情况下,即使它不等于您的TRUE值,C 中的某些东西也可能是真的。TRUE必然是一个值,而 C 将某些值定义为真,如果它不为零(2 32 -1不同的可能值,当然这取决于您的int规范)。

明确地测试真假是一个坏主意,因为所做的只是生成另一个布尔值,你在哪里停下来?

if ((event->status == TRUE) == TRUE) ...
if (((event->status == TRUE) == TRUE) == TRUE) ...
if ((((event->status == TRUE) == TRUE) == TRUE) == TRUE) ...
if (((((event->status == TRUE) == TRUE) == TRUE) == TRUE) == TRUE) ...

就您的具体问题而言,对于(1),从性能的角度来看,它可能不会产生任何影响。但是,有时它会影响代码的可读性。选择能够为您提供“最漂亮”代码的方法,并让编译器整理出将源代码转换为本机形式的最佳方法。

我优化的第一件事是可读性,因为这是防止大多数问题出现的原因。一旦您分析了可读代码并解决了性能问题,您可以考虑改进的方法。

但我会免费给你这个建议:最令人印象深刻的改进通常可以在宏观层面(比如算法选择和数据结构选择)进行,而不是在微观层面(测试真假,倒计时)循环等)。

举一个可读性的例子,我倾向于先做短的(里面的块if相对简洁)。我也倾向于先进行早期返回,因为它们通常会减少缩进。换句话说,类似:

def fn (x):
    if (x < MIN_X_ALLOWED):
        return -1

    # Now carry on, knowing that x >= MIN_X_ALLOWED.

对于(2),不,这没有真正意义。您已明确决定需要一个布尔值,并且只有两种可能的情况。你在捍卫不可能。

如果它是一个整数,并且只有值、 、 和23允许5,那将是不同的,因为您想要防御(例如)值。71110

于 2012-09-05T05:00:55.227 回答