在 C 中,是单 & 和单 |有效以免短路?还请在 C# 中给出一些相同的实用程序示例 [关闭]

Posted

技术标签:

【中文标题】在 C 中,是单 & 和单 |有效以免短路?还请在 C# 中给出一些相同的实用程序示例 [关闭]【英文标题】:In C, is single & and single | valid so as to avoid short circuit? Also please give some examples of utility of same in C# [closed] 【发布时间】:2018-06-04 05:36:23 【问题描述】:

&& 是逻辑与,|| 是逻辑或

例如,在 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");
    

现在对于&amp;&amp;,只有当两个条件都为真时,才会执行if 块,否则执行else 块。

所以对于输入2 条件num&gt;=0num&lt;=10 都是true。所以条件num&gt;=0&amp;&amp;num&lt;=10trueif 语句被执行。获取输出Hi

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

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

现在,在这种情况下,如果第一个条件 num&gt;=0flase,编译器不会检查第二个条件 num&lt;=10,因为在 &amp;&amp; 的情况下,如果两个条件都是 true,则只有那么num&gt;=0&amp;&amp;num&lt;=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");
    

这里不是&amp;&amp;,而是&amp;

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

但是在这里,在评估条件num&gt;=0&amp;num=&lt;10 期间,如果输入是-2,那么第一个条件num&gt;=0false。但与&amp;&amp; 不同的是,即使在第一个条件为false 之后,第二个条件num&lt;=10 也被求值,然后控制权传递到下一条语句。


逻辑或也类似;考虑以下 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&lt;=0true,第二个条件num&gt;=10false。因为在|| num&lt;=0||num&gt;=10true 如果两个语句中的任何一个是true,所以if 块被执行并且输出是Hi

如果输入是12 第一个条件num&lt;=0false 但第二个条件num&gt;=10true。对于|| num&lt;=0||num&gt;=10true 如果任一条件为true,则执行if 块并且输出为Hi

如果输入是2 第一个条件num&lt;=0false。第二个条件num&gt;=10 也是假的。由于这两个条件都是 false num&lt;=0||num&gt;=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&lt;=0true。由于num&lt;=0||num&gt;=10 要成为true 任何一个条件都必须是true 并且第一个条件num&lt;=0 已经为真,编译器不会检查第二个条件num&gt;=10

但是当使用| 并且这里的输入也是-2 时,即使在评估第一个条件num&lt;=0 为真之后,编译器也会检查第二个条件num&gt;=10


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 &amp;&amp; ++b; 中,当a 的值增加1 时,它的新值是00 被评估为 false。在&amp;&amp; 中,如果第一个条件或第二个条件为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;

++a1 并且 1 被评估为 true。在|| 中,如果第一个条件或第二个条件为true,则整个条件为true。由于第一个条件++a 为真,因此编译器永远不会检查第二个条件++b。所以b 的值永远不会增加并保持10


现在,我的问题 -

    &amp;| 在 C 中是否有效以避免短路?

    在 C# 中,bool 只能是 truefalsenull。与 C 不同,0 不是 false 并且所有 non-zero 值都不是 true。 所以短路永远不会在 C# 中发生。那么在C#中&amp;|的用处是什么?

【问题讨论】:

天哪,这是很多文字。为什么要“避免”短路?这是一个的东西! 这里的老C#程序员真的不用解释C#是如何工作的,我想他们都很清楚。 C# 中的短路绝对是一个既有用又能正常工作的东西,尝试评估两个分支中的方法。 在 C 中,|&amp;bit-wise 运算符,而 ||&amp;&amp;logical 运算符。这与 C# 不同。 这个评论线程现在没有用。阅读 C 和 C# 的文档,您会发现所有内容都有很好的文档记录。 【参考方案1】:

以下是您问题的答案:

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

没有。 C 中的 &amp;| 运算符与它们的 C# 逻辑对应物相比具有不同的含义。

在 C 中,&amp;| 是按位运算符。他们将评估双方并根据运算符组合结果值的。之后,如果在逻辑上下文中使用结果值,它将被处理为 0=false,其他所有值=true。

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

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

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

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

举个例子:

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

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

与此相反:

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

请注意,我在此处切换到非短路 &amp; 运算符。在这里,如果s 为空,both 操作数仍将被计算并且代码将抛出NullReferenceException

在某些情况下,这可能是有益的,并且需要您评估双方即使您知道无论第二个操作数说什么结果都不会是错误的。在这些情况下,您将使用非短路运算符。


在 C 中,运算符的含义是:

| = 按位或运算符 &amp; = 按位与运算符 || = 短路的逻辑 OR 运算符 &amp;&amp; = 短路的逻辑 AND 运算符

在 C# 中,运算符的含义如下:

| = 按位或运算符如果应用于整数,逻辑非短路或运算符如果应用于布尔值 &amp; = 按位与运算符如果应用于整数,逻辑非短路与运算符如果应用于布尔值 || = 短路的逻辑或运算符 &amp;&amp; = 短路的逻辑 AND 运算符

【讨论】:

【参考方案2】:

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

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

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

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

【讨论】:

虽然在 C# 中,&amp;| 也是逻辑运算符,非短路逻辑运算符,如果应用于布尔值。如果应用于整数,它们是按位的。 |&amp; 不是 ||&amp;&amp; 的简写。如果您知道 C,请坚持回答 C :) ||| 含义不同。相同的基础操作,逻辑 OR,但确切的行为不同,因此您无法通过省略其中一个字符来保存代码中的字符并保留当前行为。因此,它们不是简写的。 C 确实允许 &amp; | ^ ~ 用于布尔操作数,因为否则您将如何设置布尔值的位? :) 事实证明,C 实际上会将布尔操作数隐式提升为signed int。所以像~false 这样的代码实际上会给你一个否定的结果。快乐的日子。【参考方案3】:

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

我不太明白你的问题的重点:

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

【讨论】:

在 C# 中 |&amp; 是非短路布尔运算符 位运算符(就像它们在 C 中一样),因此这些运算符具有双重含义取决于涉及的类型。也就是说,为了澄清,如果运算符用于整数,它们是按位的,如果它们用于布尔值,它们是逻辑的。

以上是关于在 C 中,是单 & 和单 |有效以免短路?还请在 C# 中给出一些相同的实用程序示例 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何在C中进行短路打印?

spring中创建bean对象时多例和单例的区别

c中的内部短路评估

C语言中的短路现象

c++中怎么输出引号

图算法|Dijkstra最短路径算法