为什么是“&&”而不是“&”?

2023-12-11

Why is &&优于& and ||优于|?

我问了一个从事编程多年的人,他的解释是:

例如,在if (bool1 && bool2 && bool3) { /*DoSomething*/ }, bool1必须是真实的才能进行测试bool2在继续之前这必须是正确的bool3等等。如果我使用一个&相反,即使所有测试都必须正确才能进入下一行,测试也没有顺序,那么为什么它很重要呢?

注意:我想指出的是,我的编程能力相当于一个幼儿,这不是一个严肃或紧急的问题。更重要的是理解为什么事情应该以某种方式而不是另一种方式完成。


在多数情况下,&& and ||优先于& and |因为前者是短路的,也就是说,一旦结果明确,评估就被取消。

Example:

if(CanExecute() && CanSave())
{
}

If CanExecute回报false,完整的表达式将是false,无论返回值如何CanSave。因为这,CanSave没有被执行。

这在以下情况下非常方便:

string value;
if(dict.TryGetValue(key, out value) && value.Contains("test"))
{
    // Do Something
}

TryGetValue回报false如果在字典中找不到提供的键。由于短路的性质&&, value.Contains("test")仅当执行时TryGetValue回报true因此value is not null。如果您想使用按位与操作员&相反,你会得到一个NullReferenceException如果在字典中找不到该键,因为无论如何都会执行表达式的第二部分。

一个类似但更简单的示例是以下代码(如 TJHeuvel 提到的):

if(op != null && op.CanExecute())
{
    // Do Something
}

CanExecute仅在以下情况下执行op is not null. If op is null,表达式的第一部分(op != null) 评估为false以及其余的评价(op.CanExecute()) 被跳过。

除此之外,从技术上来说,它们也有所不同:
&& and ||只能用于bool然而& and |可用于任何整型(bool, int, long, sbyte, ...),因为它们是按位运算符。& is the 按位与运算符和| is the 按位或操作员。

更准确地说,在 C# 中,这些运算符 (&, | [and ^])被称为“逻辑运算符”(参见C# spec,第 7.11 章)。这些运算符有多种实现:

  1. 对于整数 (int, uint, long and ulong,第 7.11.1 章):
    它们的实现是为了计算操作数和运算符的按位结果,即&是计算按位逻辑的实现AND etc.
  2. 对于枚举(第 7.11.2 章):
    它们被实现来执行枚举的基础类型的逻辑操作。
  3. 对于 bool 和可为 null 的繁荣(第 7.11.3 和 7.11.4 章):
    结果不是使用按位计算来计算的。结果基本上是根据两个操作数的值来查找的,因为可能性的数量很小。
    由于这两个值都用于查找,因此此实现不会短路。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么是“&&”而不是“&”? 的相关文章

  • 分层架构中的异常处理

    我们正在分层设计中重构 当然还有重新设计 我们的服务 我们有服务操作层 BLL 网络抽象层 gt 处理网络代理 数据抽象层 但我们对我们的异常处理策略有点困惑 我们不想向外界透露太多 BLL 的信息 从其他层到bll就可以了 我们不想让 t
  • 对静态成员变量的未定义引用

    我有一个有静态成员的类 它也是我的程序中其他几个类的基类 这是它的头文件 ifndef YARL OBJECT HPP define YARL OBJECT HPP namespace yarlObject class YarlObject
  • 如何动态加载包含非托管代码的原始程序集?(绕过“无法验证的代码失败策略检查”异常)

    我将举一个使用的例子系统 Data SQLite DLL http sqlite phxsoftware com 这是一个包含非托管代码的混合程序集 如果我执行这个 var assembly Assembly LoadFrom System
  • Linux 使用 boost asio 拒绝套接字绑定权限

    我在绑定套接字时遇到问题 并且以用户身份运行程序时权限被拒绝 这行代码会产生错误 acceptor new boost asio ip tcp acceptor io boost asio ip tcp endpoint boost asi
  • 使用预编译头减少 clang 编译时间

    我正在开发一个数据库项目 该项目将查询 以某种高级语言表示 编译为 C 代码 这段代码由数据库编译并执行 那部分工作得很好 现在 我正在尝试减少 C 查询代码的编译时间 我想知道是否可以使用预编译头来提高性能 该查询被转换为一个名为 Que
  • 在不使用 ncurses 的情况下用 C/C++ 编写“真正的”交互式终端程序,例如 vim、htop...

    不 我不想使用ncurses 因为我想了解如何 终端可以工作 并且我自己编程也很有趣 没有 必须是可移植的 它必须只能在基于 linux xterm 的终端仿真器上工作 我想做的是编写一个交互式终端应用程序 例如 htop 和 vim 我的
  • 无缝滚动瓷砖地图

    我正在开发一个自上而下的角色扮演游戏 并且想要实现无缝滚动地图 也就是说 当玩家探索世界时 地图之间没有加载屏幕 也没有通往下一个区域的 门 我有两种方法可以打破世界 在顶层 我有 区域 它只是 9 个 地图 的集合 这些区域仅由目录表示
  • 如何使用boost库读取和写入.ini文件[重复]

    这个问题在这里已经有答案了 如何使用boost库读取和写入 或修改 ini文件 With Boost PropertyTree您可以读取并更新树 然后写入文件 请参阅load and save功能 看一下如何访问属性树中的数据 http w
  • WinForms - 表单大小错误

    我们有以下代码 private void MainForm Shown object sender EventArgs e RepositionForm private void RepositionForm Rectangle rect
  • C for 循环索引:新 CPU 中的前向索引更快吗?

    在我订阅的邮件列表上 两位知识渊博的 IMO 程序员正在讨论一些优化的代码 并说了以下内容 在 5 8 年前发布的 CPU 上 向后迭代 for 循环稍微快一些 e g for int i x 1 i gt 0 i 因为比较i归零比将其与其
  • 如何填充两个样条线或直线系列之间的区域

    我有这个Chart 如何填充两个之间的区域Series S0 and S1 说蓝色和黄色Series 为此 我们编写了其中之一Paint事件 这里的ValueToPixelPosition https msdn microsoft com
  • 使用 QGraphicsScene 实现流畅的动画

    我希望我的问题并不总是同样的问题 我有一个 QGraphicsScene 它的项目是一些 QGraphicsPixmap 我用一个计时器来移动它们 每秒 SetX 10 我设置 10是因为窗口大100 使用这个解决方案我的动画不流畅 我想我
  • 将一个整数从 C 客户端发送到 Java 服务器

    我使用此代码将一个整数从我的 Java 客户端发送到我的 Java 服务器 int n rand nextInt 50 1 DataOutputStream dos new DataOutputStream socket getOutput
  • 使用宏计算源文件行数?

    是否可以使用 C C 预处理器将源文件中的行数计算为宏或某种编译时可用值 例如 我可以更换吗MAGIC1 MAGIC2 and MAGIC3在下面 并在使用时以某种方式获取值 4MAGIC3 MAGIC1 can be placed whe
  • printf() 使用字符串表“解码器环”调试库

    我写这封信是想看看你们中是否有人见过或听说过我即将描述的想法的实现 我有兴趣为嵌入式目标开发 printf 风格的调试库 目标非常遥远 并且我和目标之间的通信带宽预算非常紧张 因此我希望能够以非常有效的格式获取调试消息 通常 调试语句如下所
  • 从 exit() 和 fork() 返回的结果奇怪地发生了位移

    我有一个 C 代码 有时会自行分叉 每个分叉都会执行一些操作 然后返回一个错误代码 目前 每个子进程返回其 ID 0 n void other int numero exit numero int main for int i 0 i lt
  • 如何使用 xamarin 表单提示用户进行地理定位

    我正在 Xamarin Forms 应用程序中开发一个应用程序 需要请求地理位置权限 如果获得许可 它需要从设备获取地理位置数据 然后将地理位置坐标放入 Forecast io URL 我正在使用 James 的 Geolocator 插件
  • 为什么调试器只显示数组指针中的一个元素?

    首先 我知道new是执行此操作的 C 方法 我只是表明有不止一种方法可以重现此错误 而且两种方法都令人难以置信的令人沮丧 我有两种形式的源文件 我正在尝试调试另一个编程作业 但我并没有寻求帮助 基本上 我正在尝试重新实施set作为一个类 具
  • 清理堆分配对象的良好实践或约定?

    我正在学习C 我有 C C ObjC 背景 相当高级的语言 在 C 或 ObjC 上 作为函数或方法的结果返回堆分配的对象是很简单的 因为对象的清理是受管理的 按照惯例 会在适当的时候销毁 但我不知道在 C 中应该如何处理这个问题 例如 s
  • 扔掉挥发物安全吗?

    大多数时候 我都是这样做的 class a public a i 100 OK delete int j Compiler happy But is it safe The following code will lead compilat

随机推荐