在C中,是单个和单个|有效是为了避免短路?另外请在C#中给出一些实用程序的例子[关闭]

问题描述 投票:-5回答:3

&&是逻辑AND,||是逻辑OR

例如,在C#中,

using System;

class Program {
    static void Main() {
        Console.WriteLine("Enter a number");
        int num = int.Parse(Console.ReadLine());
        if(num>=0&&num<=10)
            Console.WriteLine("Hi");
        else
            Console.WriteLine("Hello");
    }
}

现在对于&&只有两个条件都为真,那么if块被执行,否则else块被执行。

所以对于输入2条件num>=0num<=10都是true。所以条件num>=0&&num<=10trueif语句被执行。得到输出Hi

对于输入-2条件num<=10true但条件num>=0false。由于两个条件都应该为真,因此条件num>=0 && num<=10为false,而不是for语句else语句被执行。所以输出是Hello

对于输入12条件num>=0true但条件num<=10false。由于两个条件都应该为真,因此条件num>=0 && num<=10为false,而不是for语句else语句被执行。所以输出是Hello

现在,在这种情况下,如果第一个条件num>=0出来是flase编译器不检查第二个条件num<=10,因为在&&的情况下如果两个条件都是true,那么num>=0&&num<=10才是true

现在考虑以下程序 -

using System;

class Program {
    static void Main() {
        Console.WriteLine("Enter a number");
        int num = int.Parse(Console.ReadLine());
        if(num>=0&num<=10)
            Console.WriteLine("Hi");
        else
            Console.WriteLine("Hello");
    }
}

这里没有&&,而是给出了&

输出将与&&&的真值表相同。

但在这里,在评估条件num>=0&num=<10期间,如果输入是-2,那么第一个条件num>=0false。但与&&不同,即使在第一个条件是false第二个条件num<=10被评估,然后控制传递到下一个语句。


逻辑OR也是如此;考虑以下C#示例 -

using System;

class Program {
    static void Main() {
        Console.WriteLine("Enter a number");
        int num = int.Parse(Console.ReadLine());
        if(num<=0||num>=10)
            Console.WriteLine("Hi");
        else
            Console.WriteLine("Hello");
    }
}

如果输入是-2,第一个条件num<=0true,第二个条件num>=10false。因为在|| num<=0||num>=10true,如果两个陈述中的任何一个是true,那么if块被执行并且输出是Hi

如果输入是12第一个条件num<=0false但第二个条件num>=10true。对于|| num<=0||num>=10true,如果任一条件是true,所以if块被执行,输出是Hi

如果输入是2第一个条件num<=0false。第二个条件num>=10也是假的。由于两个条件都是false num<=0||num>=10flaseelse块被执行。因此输出是Hello

现在考虑以下程序 -

using System;

class Program {
    static void Main() {
        Console.WriteLine("Enter a number");
        int num = int.Parse(Console.ReadLine());
        if(num<=0|num>=10)
            Console.WriteLine("Hi");
        else
            Console.WriteLine("Hello");
    }
}

这里使用的不是|| |。这两个程序都生成与|||的真值表相同的输出。

但是当使用||并且如果输入是-2时,首先条件num<=0true。因为num<=0||num>=10true要么条件需要true和第一个条件num<=0已经是真的,编译器不检查第二个条件num>=10

但是当使用|时,输入是-2,即使在评估第一个条件num<=0为真之后,编译器检查第二个条件num>=10


Concept of ""Short Circuit" in C

让我们考虑以下示例 -

#include <stdio.h>
int main() {
    int a, b, c;
    a = -1;
    b = 0;
    c = ++a && ++b;
    printf("a = %d, b = %d, c = %d\n", a, b, c);
    return 0;
}

预期产量:

a = 0, b = 1, c = 0

实际输出:

a = 0, b = 0, c = 0

这是因为在c = ++a && ++b;语句中,当a的值增加1时,它的新值是00被评估为false。在&&,如果第一个条件或第二个条件是false,整个条件是false。所以这里++a被评估为false,条件++b永远不会被编译器检查。所以b永远不会增加,它的价值保持0

现在考虑以下示例 -

#include <stdio.h>

int main() {
    int a, b, c;
    a = 0;
    b = 10;
    c = ++a || ++b;
    printf("a = %d, b = %d, c = %d\n", a, b, c);
    return 0;
}

预期产量:

a = 1, b = 11, c = 1

实际输出:

a = 1, b = 10, c = 1

在声明中

c = ++a || ++b;

++a11被评为true。在||,如果第一个条件或第二个条件是true,整个条件是true。这里因为第一个条件++a为真,所以编译器从不检查第二个条件++b。所以b的价值永远不会增加并保持10


现在,我的问题 -

  1. &|在C中是否有效,以便可以避免短路?
  2. 在C#bool只能是truefalsenull。不像C 0不是false和所有non-zero值不是true。所以C#中永远不会发生短路。所以在C#中,&|的效用是什么?
c# c short-circuiting
3个回答
3
投票

以下是您的问题的答案:

是&和|在C中有效可以避免短路?

不。与C#逻辑对应物相比,C中的&|运算符意味着不同的东西。

在C中,&|是按位运算符。他们将根据操作员评估两侧并合并结果值的位。之后,如果在逻辑上下文中使用结果值,则将其处理为0 = false,其他值= true。

这与C#的短路逻辑运算符不同。

在C#中,bool只能是true,false或null。与C 0不同,并非所有非零值都不为真。所以C#中永远不会发生短路。

那么在C#中,&和|的效用是什么?

&|作为C#逻辑运算符的目的是支持非短路评估。

举个例子:

// s is string
if (s != null && s.Length > 0) { ... }

这里,如果s确实是null,则第一个操作数的值是false,因此整个表达式永远不能是true,因此第二个操作数s.Length > 0不被评估。

与此形成鲜明对比:

if (s != null & s.Length > 0) { ... }

注意我在这里切换到非短路&操作员。这里,如果s为null,则仍将评估两个操作数,并且代码将抛出NullReferenceException

在某些情况下,即使您知道无论第二个操作数是什么意思,结果都不会是假的,您可能会对双方进行评估,这可能是有益的。在这些情况下,您将使用非短路运算符。


在C中,运算符意味着:

  • | =按位OR运算符
  • & =按位AND运算符
  • || =短路的逻辑OR运算符
  • && =短路的逻辑AND运算符

在C#中,运算符意味着:

  • | =按位OR运算符,如果应用于整数,逻辑非短路OR运算符,如果应用于bools
  • & =按位AND运算符,如果应用于整数,逻辑非短路AND运算符,如果应用于bools
  • || =短路的逻辑OR运算符
  • && =短路的逻辑AND运算符

1
投票

单字符运算符&|分别是按位AND和OR。它们与布尔测试无关,使用短路&&||

我不太明白你的问题:

  1. 它们是“有效的”,它们是C运算符,但它们不是用于布尔逻辑,而是用于计算二进制结果。
  2. 在C#中,它们似乎有双重用途,在the operators documentation中描述为“整数按位AND,布尔逻辑AND”。但我不使用C#。

0
投票

&和|不是逻辑运算符。将它们用作逻辑运算符利用了C语言特性,即零为假,非零为真(这不是完全类型安全的)。

C#是一种完全类型安全的语言,因此逻辑表达式必须是布尔值。这意味着逻辑运算符仅适用于布尔值(&&,||),而按位运算仅适用于整数类型(&,|,^)

基本上,&,|的目的和^运算符不是在C中进行逻辑测试,只是语言的类型不安全,足以允许它作为副作用。

编辑:我更正,(&,|)在C#中也显然是有效的逻辑运算符(只是&&,||的简写)

© www.soinside.com 2019 - 2024. All rights reserved.