我在c89模式下使用gcc 4.7.0。
我有这个if-else语句并有两个问题。
我只是想知道我应该首先测试FALSE或TRUE条件。什么通常更好。我知道它没有多大区别,但我只是想知道其他工程师做了什么?在下面的例子中,我首先检查是否为FALSE。
我总是喜欢做一些防御性编程。所以我总是可以明确地检查每个条件。例如,而不是if() - else。我会做if() - 否则if()。在下面的示例中,条件可以是TRUE或FALSE。但是,我总是想检查else条件以确保它是正确的。这有什么真正的意义吗?
非常感谢任何建议。
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);
}
}
}
答案 0 :(得分:2)
我只是想知道我应该首先测试FALSE或TRUE条件。什么通常更好。我知道它没有多大区别,但我只是想知道其他工程师做了什么?在下面的示例中,我首先检查FALSE。
对您的情况进行分析。如果你有一些数据显示20%的情况变为False而80%的情况变为true,则将true分支放在第一个分支。在某些情况下,这可能有助于改善性能。
我总是喜欢做一些防御性编程。所以我总是可以明确地检查每个条件。例如,而不是if() - else。我会做if() - 否则if()。在下面的示例中,条件可以是TRUE或FALSE。但是,我总是想检查else条件以确保它是正确的。这有什么意义吗?
除非你担心这个事件 - >状态可能会被一些技巧问题所破坏,在大多数情况下,我认为我们只是使用if(!event-> status)else style
答案 1 :(得分:1)
1)我只是想知道我应该首先测试FALSE或TRUE条件。什么是 通常更好。我知道它没有多大区别,但我只是想知道其他工程师做了什么?在下面的例子中我是 首先检查错误。
从语法上讲,它并没有太大的区别,编程明智再一般并不重要。但是,对于特定用例,它可能会影响性能。让我们考虑一个例子,如果您正在播放媒体文件,这个条件是检查它是媒体帧还是标题。在这里,您知道在标题后面将有100个媒体帧,因此您需要检查媒体帧然后标题。检查标头意味着100个冗余检查== 100个冗余CPU指令[可能更多]。除非你正在编写一般内容,否则根据你的用例编码总是更好。
2)我总是喜欢做一些防御性编程。所以我总是可以明确地检查每个条件。例如,而不是if() - else。我会做if() - 否则if()。在下面的示例中,条件可以是TRUE或FALSE。但是,我总是想检查else条件以确保它是正确的。这有什么真正的意义吗?
防御性节目有其自己的优点和缺点。在上面提到的场景中,编译器将为您进行必要的优化。
你可能想看看这里 http://www.eventhelix.com/realtimemantra/basics/optimizingcandcppcode.htm#
干杯.. 快乐学习
答案 2 :(得分:1)
1)首先检查哪种情况并不重要,因为编译器会为你优化代码。
2)如果status
只能有两个值(TRUE/FALSE
),那么else if
似乎对普通读者来说有点混乱。另一方面,如果status
可能有其他值,那么第三个其他部分可能会有assert()
。一般来说,添加断言是一个很好的习惯,可以添加到防御工具箱中以捕捉错误的假设。
答案 3 :(得分:1)
首先,不要对布尔值执行此操作:
if (something == TRUE)
if (something == FALSE)
这些应该是这样的:
if (something)
if (!something)
还应智能地命名布尔值,以便自然地读取if
语句,例如if (isFinished)
或while (stillSomeMoreToGo)
。 status
不是布尔值的好名称,除非它意味着某些东西具有状态,即使这样,我也会使用hasStatus
或类似的东西。
在任何情况下,即使它不等于你的TRUE
值,C中也可能是真的。必要时,TRUE
将是一个值,而如果C非零,则将C定义为true(2 32 -1 不同当然可能的值取决于您的int
规范。
明确地测试true或false是一个坏主意,因为所有这一切都是生成另一个布尔值,你在哪里停止?
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),不,没有真正的意义。您已明确决定需要布尔值,并且只有两种可能的情况。你正在防御不可能。
如果它是一个整数,并且只允许值2
,3
,5
,7
和11
,则会有所不同你想要防范(例如)价值10
。