C#中的&和&&运算符有什么区别?

48

我想了解在C#中&&&运算符之间的区别。我上网搜索没有找到答案。请有人能举个例子来解释一下吗?

9个回答

54

& 是按位与运算符。对于整数类型的操作数,它将计算操作数的按位与,并且结果将是一个整数类型。对于布尔操作数,它将计算操作数的逻辑与。 && 是逻辑与运算符,不适用于整数类型。对于可以应用两者的布尔类型,差异在于 && 的“短路”特性。如果 && 的第一个操作数求值为 false,那么第二个操作数根本不会被求值。这不是 & 的情况:

 bool f() {
    Console.WriteLine("f called");
    return false;
 }
 bool g() {
    Console.WriteLine("g called");
    return false;
 }
 static void Main() {
    bool result = f() && g(); // prints "f called"
    Console.WriteLine("------");
    result = f() & g(); // prints "f called" and "g called"
 }

||在这个属性中类似于&&,它只有在第一个操作数为false时才会计算第二个操作数。

当然,用户定义的类型可以重载这些运算符,使它们做任何想要做的事情。


谢谢Mehrad。您的意思是'&'运算符等于'||'吗...? - BreakHead
1
当与布尔类型一起使用时,& 是逻辑 AND,&& 被描述为“条件 AND 运算符”(至少在 Microsoft 中是这样)。http://msdn.microsoft.com/en-us/library/2a723cdk.aspx - GrahamS
1
@BreakHead:不对。&&& 是 AND。||| 是 OR。&&|| 都是短路运算符,而 |& 都不是短路运算符。 - Mehrdad Afshari

10

强烈推荐Dotnet Mob的这篇文章:http://codaffection.com/csharp-article/short-circuit-evaluation-in-c/

&&是短路逻辑运算符。

对于AND操作,如果任何一个操作数计算结果为false,则整个表达式的计算结果为false,因此无需计算剩余的表达式;类似地,在OR操作中,如果任何一个操作数计算结果为true,则可以跳过其余的计算。

& 运算符可用作一元或二元运算符。也就是说,在不安全的上下文中,可以使用一元 & 来获取其操作数的地址。


谢谢,你的文章很好 :) ,但我想这句话中有一个拼写错误:“而对于 OR 操作,如果任何操作数的求值结果都是 true,则可以跳过剩余的求值。” 在逻辑 | 运算符中,两个操作数都会被计算,不会被跳过。查看我的答案。我从你的文章中学到了一些东西。 - Shaiju T
1
@stom 这是一个通用的语句 - 如果任何操作数的结果为True,则整个语句将为True。这就是使用||操作符时发生的情况(它从左到右评估操作数)。在|运算符的情况下,没有跳过任何内容。这两个|和||都是OR运算符。 - Shamseer K
是的,对于 |(管道)运算符,所有操作数都会被计算,但在 ||(双管道)运算符 中,由于短路计算,操作数会被跳过。但是,在您的文章中有一点混淆,因为您在解释逻辑 ANDOR 运算符之后就说了那句话。 :) - Shaiju T

8
&可以用于整型(如intlong等)或bool类型。
当用于整型时,它执行按位与操作并给出结果。当用于bool类型时,它对两个操作数执行逻辑与操作并给出结果。 &&不作为按位与运算符使用。它作为逻辑与运算符使用,但它不一定检查两个操作数。如果左操作数的值为false,则它不会检查右操作数。
以下是一个例子:
void Action() 
{
    string name = null;
    if(name != null && name.EndsWith("ack"))
    {
        SomeOtherAction();
    }
}

如果name为空,则name.EndsWith("ack")将永远不会被执行。它足够智能,知道如果左操作数为false,则右操作数不需要被评估(也称为“短路”)。这很好,因为在空值上调用方法会抛出NullReferenceException异常。
如果将其更改为if(name != null & name.EndsWith("ack")),那么两个条件都将被评估,并且会抛出NullReferenceException异常。
一个细节:在不安全的上下文中,&也可以是一元运算符(因此它只有一个操作数)。它将给出值或对象的地址。这并不重要,因为大多数人从未接触过语言的这部分。

6
以下的示例和解释可能会有所帮助。
示例:

Example:

    public static bool Condition1()
    {
        Console.WriteLine("Condition1 is evaluated.");
        return false;
    }

    public static bool Condition2()
    {
        Console.WriteLine("Condition2 is evaluated.");
        return true;
    }

1. 逻辑运算符

&(和号)逻辑与运算符

|(竖线)逻辑或运算符

用于确保所有操作数都被计算。

if(Condition1() & Condition2())
{
  Console.WriteLine("This will not print");

  //because if any one operand evaluated to false ,  
  //thus total expression evaluated to false , but both are operand are evaluated.
}

 if (Condition2() | Condition1())
 {
   Console.WriteLine("This will print");

   //because any one operand evaluated to true ,  
  //thus total expression evaluated to true , but both are operand are evaluated.
 }

2. 条件短路运算符

&&(双与号)条件 AND 运算符

||(双竖线)条件 OR 运算符

用于跳过右侧的操作数,具有副作用,因此使用时要小心。

if (Condition1() && Condition2())
{
   Console.WriteLine("This will not print");

   //because if any one operand evaluated to false,
   //thus total expression evaluated to false , 
   //and here the side effect is that second operand is skipped 
   //because first operand evaluates to false.
}

if (Condition2() || Condition1())
{
   Console.WriteLine("This will print");

  //because any one operand evaluated to true 
  //thus remaining operand evaluations can be skipped.
}

注意:

为了更好地理解,请在控制台中进行测试。

参考资料

dotnetmob.com

wikipedia.org

stackoverflow.com


1
在条件方法中使用 WriteLine 可以帮助更好地理解。请参见 https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators#logical-and-operator-。 - NullPointerWizard

3

& 是一个按位运算符,&& 是一个逻辑运算符,它适用于 bool 类型的操作数。


6
当操作数为布尔类型时,& 也是一种逻辑运算符。请参阅 http://msdn.microsoft.com/en-us/library/sbf85k1c.aspx。 - GrahamS

2

从逻辑上看,使用 | 符号将会评估两侧的值,无论左侧是否为 false,而短路 && 运算符只有在左侧为 true 时才会评估右侧的值。

d=0;
n=10;

// this throws divide by 0 exception because it evaluates the 
//      mod even though "d != 0" is false
if ( (d != 0) & (n % d) == 0 ) 
   Console.Writeline( d + " is a factor of " + n);

// This will not evaluate the mod.
if ( (d != 0) && (n % d) == 0 ) 
   Console.Writeline( d + " is a factor of " + n);

1
根据 Herbert Schildt 的《C# 4.0 The Complete Reference》
& - 逻辑与运算符 | - 逻辑或运算符
&& - 短路与运算符 || - 短路或运算符
一个简单的例子可以帮助理解这些现象。
using System;

class SCops {
    static void Main() {
        int n, d;
        n = 10;
        d = 2;

        if(d != 0 && (n % d) == 0)
            Console.WriteLine(d + " is a factor of " + n);
        d = 0; // now, set d to zero

        // Since d is zero, the second operand is not evaluated.
        if(d != 0 && (n % d) == 0)
            Console.WriteLine(d + " is a factor of " + n);
        // Now, try the same thing without the short-circuit operator.
        // This will cause a divide-by-zero error.
        if(d != 0 & (n % d) == 0)
            Console.WriteLine(d + " is a factor of " + n);
    }
}

这里的&运算符会检查每个操作数,而&&只检查第一个操作数。

正如你所注意到的,“AND”操作中任何为false的操作数都会将整个表达式评估为false,而不考虑表达式中其他操作数的值。这种短路形式有助于评估第一部分,并且足够聪明以知道是否需要第二部分。

运行程序将在最后一个if条件下抛出除零错误,其中检查了&运算符的两个操作数,并且没有进行异常处理来解决“d”可能在任何时候为0的事实。

C#中的|也适用于相同的情况。

这与C或C ++略有不同,其中'&'和'|'是按位AND和OR运算符。但是,C#也仅将按位性质应用于int变量的&和|。


1

& 是一个逻辑(布尔)与运算符,但当应用于布尔值时,它不是短路的,而 && 是。 - Rune FS

0
嗨,朋友, 运算符&&(逻辑运算符)用于条件语句中。 例如

if(firstName == 'Tilsan' && lastName == 'Fighter')
{
      Response.Write("Welcome Tilsan The Fighter!");
}

只有当变量firstName和lastName都符合其条件时,Response.Write语句才会运行。

而&(位运算符)用于二进制AND操作,即,如果我们写:

bool a, b, c;

a = true;
b = false;

c = a & b;

Response.Write(c); // 'False' will be written to the web page

首先对变量a和b执行二进制与操作,并将结果值存储在变量c中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接