编程中的短路评估
短路评估:短路是一种编程概念,编译器通过它跳过逻辑表达式中某些子表达式的执行或评估。一旦表达式的值被确定,编译器就停止对进一步的子表达式求值。下面是一个相同的例子:
C++
if (a == b || c == d || e == f) {
// do_something
}
C++
// C program to illustrate the concept
// of short circuiting
#include
// Driver Code
int main()
{
int x = 1;
if (x || ++x) {
printf("%d", x);
}
return 0;
}
C
// C program to illustrate the concept
// of short circuiting
#include
// Driver Code
int main()
{
int a = 10;
int b = -1;
// Here b == -1 is not evaluated as
// a != 10 is false
if (a != 10 && b == -1) {
printf("I won't be printed!\n");
}
else {
printf("Hello, else block is printed");
}
return 0;
}
C
// C program to illustrate the concept
// of short circuiting
#include
#include
// Function to calculate the square root
int calculate_sqrt(int i)
{
printf("Sqrt of %d: %.2f\n",
i, sqrt(i));
return i;
}
// Driver Code
int main()
{
int a = 15;
// Here since a is 10, calculate_sqrt
// function will be called
if (a >= 10 && calculate_sqrt(a)) {
printf("I will be printed!\n");
}
return 0;
}
C
// C program to illustrate the concept
// of short circuiting
#include
// Driver Code
int main()
{
float nr = 5, dr = 0;
dr&& printf("a/b = %.2f", nr / dr);
}
C
int a = 0;
// myfunc(b) will not be called
if (a != 0 && myfunc(b)) {
// do_something();
}
解释:在上面的表达式中,如果表达式a == b为真,那么c == d和e == f根本不会被计算,因为表达式的结果已经确定。类似地,如果逻辑 AND (&&)运算符而不是逻辑 OR (||)并且表达式a == b为false ,则编译器将跳过评估其他子表达式。
示例 1:
C++
// C program to illustrate the concept
// of short circuiting
#include
// Driver Code
int main()
{
int x = 1;
if (x || ++x) {
printf("%d", x);
}
return 0;
}
1
说明:在上面的C程序中,在if语句中,第一个子表达式即x的值是1(表示布尔值为真),所以第二个子表达式的值不影响第一个子表达式的值表达式,因此编译器会跳过检查它。所以 x 的值不会增加。
示例 2:
C
// C program to illustrate the concept
// of short circuiting
#include
// Driver Code
int main()
{
int a = 10;
int b = -1;
// Here b == -1 is not evaluated as
// a != 10 is false
if (a != 10 && b == -1) {
printf("I won't be printed!\n");
}
else {
printf("Hello, else block is printed");
}
return 0;
}
Hello, else block is printed
说明:上述程序打印else 块的输出,因为第一个条件为假,这足以确定表达式的值,因此不计算第二个条件。
示例 3:以下是计算平方根的 C 程序,以演示短路评估的概念:
C
// C program to illustrate the concept
// of short circuiting
#include
#include
// Function to calculate the square root
int calculate_sqrt(int i)
{
printf("Sqrt of %d: %.2f\n",
i, sqrt(i));
return i;
}
// Driver Code
int main()
{
int a = 15;
// Here since a is 10, calculate_sqrt
// function will be called
if (a >= 10 && calculate_sqrt(a)) {
printf("I will be printed!\n");
}
return 0;
}
Sqrt of 15: 3.87
I will be printed!
说明:在上面的程序中,如果数字小于 10,则不执行平方根。因此,也避免了负数的错误。
应用:短路的概念在许多情况下都有帮助。其中一些如下所列:
- 避免意外行为:它可用于避免由于第二个参数引起的意外行为。例如:考虑以下代码片段:
C
// C program to illustrate the concept
// of short circuiting
#include
// Driver Code
int main()
{
float nr = 5, dr = 0;
dr&& printf("a/b = %.2f", nr / dr);
}
解释:由于表达式(nr/dr)给出了运行时错误,但由于将表达式dr && 与操作相加,因此避免了错误,因为dr 的值为0 ,排除了(nr/dr)的计算。
- 避免昂贵的计算:它有助于避免只需要在特定条件下执行的昂贵计算。下面是说明相同的代码片段:
C
int a = 0;
// myfunc(b) will not be called
if (a != 0 && myfunc(b)) {
// do_something();
}
示例:在上面的示例中,如果需要使用myfunc()对值0执行昂贵的操作,则可以通过使用此概念来避免对非零值的昂贵操作。这也可以用于文件处理,以避免在文件已经处于就绪状态时每次都准备好文件的昂贵任务
isFileReady() || getFileReady()
短路评估的优点:
- 在某些情况下,它有助于避免计算成本高的任务。
- 它提供对第一个参数的检查,如果没有第二个参数可能会导致运行时错误。
短路评估的缺点:
- 如果使用不当,可能会导致意外行为。对于代码片段中进行某种系统资源/内存分配的任何函数,我们可能会出现意外行为。
- 短路执行路径的代码执行效率会降低,因为在某些编译器中,新的短路检查本身就是额外的执行周期。