三元运算符与 if 语句的优点

2023-12-10

我正在浏览一些代码,发现其中有一些三元运算符。这段代码是我们使用的一个库,它应该非常快。

我在想除了空间之外我们是否还可以节省任何东西。

你的经验是什么?


表现

三元运算符的性能与编写良好的等效运算符不应有差异if/else声明...它们很可能解析为抽象语法树中的相同表示,进行相同的优化等。

你只能用它来做的事情? :

如果您正在初始化常量或引用,或者计算出在成员初始化列表中使用哪个值,那么if/else不能使用语句,但是? : can be:

const int x = f() ? 10 : 2;

X::X() : n_(n > 0 ? 2 * n : 0) { }

简洁代码的分解

按键使用理由? :包括本地化,并避免冗余地重复相同语句/函数调用的其他部分,例如:

if (condition)
    return x;
else
    return y;

...只比...更好

return condition ? x : y;

...如果与非常缺乏经验的程序员打交道,或者某些术语足够复杂,则出于可读性的考虑? :结构在噪音中消失。在更复杂的情况下,例如:

fn(condition1 ? t1 : f1, condition2 ? t2 : f2, condition3 ? t3 : f3);

同等的if/else:

if (condition1)
    if (condition2)
        if (condition3)
            fn(t1, t2, t3);
        else
            fn(t1, t2, f3);
    else if (condition3)
            fn(t1, f2, t3);
        else
            fn(t1, f2, f3);
else
    if (condition2)
       ...etc...

这是编译器可能会也可能不会优化的大量额外函数调用。

更远,?允许您选择一个对象,然后使用其中的成员:

(f() ? a : b).fn(g() ? c : d).field_name);

相当于if/else将会:

if (f())
    if (g())
        x.fn(c.field_name);
    else
        x.fn(d.field_name);
else
    if (g())
        y.fn(c.field_name);
    else
        y.fn(d.field_name);

命名临时变量不能改善上面的 if/else 问题吗?

如果表达式t1, f1, t2等太冗长而无法重复输入,创建命名临时变量可能会有所帮助,但是:

  • 获得性能匹配? :你可能需要使用std::move,除非将相同的临时值传递给两个&&被调用函数中的参数:那么你必须避免它。这更加复杂并且容易出错。

  • c ? x : y评估c那么其中之一但不是两者x and y,这使得可以肯定地说测试指针不是nullptr在使用它之前,同时提供一些后备值/行为。该代码仅获得以下任一者的副作用x and y实际上是被选中的。对于命名临时对象,您可能需要if / else周围或? :在它们的初始化中,以防止执行不需要的代码,或者代码执行的频率超过预期。

功能差异:统一结果类型

考虑:

void is(int) { std::cout << "int\n"; }
void is(double) { std::cout << "double\n"; }

void f(bool expr)
{
    is(expr ? 1 : 2.0);

    if (expr)
        is(1);
    else
        is(2.0);
}

在上面的条件运算符版本中,1经过标准转换为double使类型匹配2.0,意味着is(double)即使对于true/1情况。这if/else语句不会触发此转换:true/1分行呼叫is(int).

您不能使用具有整体类型的表达式void在条件运算符中,而它们在条件运算符下的语句中有效if/else.

强调:需要值的行动之前/之后的值选择

有不同的侧重点:

An if/else语句首先强调分支,而要做什么是次要的,而三元运算符则强调要做什么而不是选择要执行的值。

在不同的情况下,两者都可能更好地体现程序员对代码的“自然”视角,并使其更易于理解、验证和维护。您可能会发现自己根据编写代码时考虑这些因素的顺序来选择其中一个 - 如果您已经开始“做某事”,那么您可能会使用几个(或几个)值中的一个来执行操作它与,? :是表达这一点并继续编码“流程”的破坏性最小的方式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

三元运算符与 if 语句的优点 的相关文章

随机推荐

  • 如何获取 os.system() 的输出? [复制]

    这个问题在这里已经有答案了 我想得到输出os system nslookup google com 但我总是得到0 打印时 这是为什么 我该如何解决这个问题 Python 3 Mac 我在看如何在python中存储已打印到stdout的os
  • 使用 WPF + Windows Azure 存储二进制数据(图像、文件等)

    我有一个使用 Windows Azure 作为后端的 WPF 应用程序 我使用 SQL Azure 存储 WPF 应用程序通过 WCF 服务访问的数据 我需要能够在服务器端存储二进制文件 例如图像 并想知道存储这些文件的最佳方法是什么 我可
  • 添加与 GDK 的共享联系人

    我正在研究 Google Glass GDK 并且正在寻找是否可以从应用程序添加共享联系人 我在官方文件中没有看到任何对此的引用 我想知道你是否可以这样做 感谢您的帮助 目前先睹为快的GDK尚不支持添加共享联系人 如果您对此功能感兴趣 请在
  • 将意图保存在共享首选项中

    我有一个应用程序 我可以从中启动手机上安装的其他应用程序 长按我可以获得应用程序选择器 结果我收到一个意图数据 我如何保存它以便用户在关闭时返回我的应用程序有相同的快捷方式设置吗 我保存其他类似的东西 SharedPreferences s
  • 版本不匹配 global tsc 1.0.3.0 != VS Code 的语言服务 (2.2.1)

    I have this popup presented 我尝试通过在 cmd 中执行以下命令来安装正确的 tsc npm install g save dev email protected and npm install save dev
  • python pandas 带括号和不带括号的函数

    我注意到许多 DataFrame 函数如果不带括号使用似乎表现得像 属性 例如 In 200 df DataFrame np random randn 7 2 In 201 df head Out 201 0 1 0 1 325883 0
  • 有没有办法查看架构验证失败的位置?

    我正在尝试根据某种复杂的 模式 如空手道文档中定义 验证 json 我得到的错误并不那么明确 reason not equal 我如何检查它实际上在哪里验证失败 真的很抱歉 这都是我的错 我知道这对你没有帮助 但我现在正在重写空手道的核心
  • 如何定义一个地图接受 Thrift 中不同类型的值?

    我用 thrift 定义了一个结构 struct QuerySetRecord 1 string recordId 2 string crawlerName 3 string recordType 4 map
  • 仅删除 HTML 字符串中标签之间的多余空格

    嗨 我有一个 HTML 字符串 例如 div p You have received an alert from project span class fields Project Name span br p p span class f
  • 我可以暂停和恢复线程吗?

    我正在尝试创建一个线程 它在后台执行操作 我需要能够在需要时有效地 暂停 它 并在以后再次 恢复 它 另外 如果当我 暂停 线程时线程正在执行某些操作 它应该使调用线程等待 直到它完成正在执行的操作 我对 Python 中的多线程还很陌生
  • 如何使用 REST 将数据从 AngularJS 发布到 Struts 2

    我需要从客户端获取到服务器端的值 我正在使用 AngularJS 和 Struts2 REST 我的控制器没有获取传递的值 还是我传递或使用 RESTful 控制器时出错了 这是我的代码 angularcontroller js app c
  • Android Studio 意外的顶级异常:

    今天 我遇到了一个巨大的错误 不允许我在手机上运行示例项目 当 Android Studio 构建项目时 它首先显示以下目标 UP TO DATE demoproject processDebugResources UP TO DATE d
  • 如何获取java中两个日期之间的日期列表?如何还包含/排除开始日期/结束日期?

    我已经尝试过堆栈溢出中给出的示例java中如何获取两个日期之间的日期列表 该代码完美运行 但有一个小问题 我的列表中也没有得到结束日期 如何选择包含 排除开始日期并包含结束日期 我可以使用remove 和add 手动执行此操作吗 或者Jod
  • 将 checkstyle-configuration 从声纳导入到 eclipse-checkstyle-plugin

    我想从声纳导出 checkstyle 规则并将它们导入到 checkstyle eclipse 插件中 不幸的是 sonar 将 checkstyle 规则导出到 csv 文件 但 checkstyle 插件只接受 xml 文件的导入 有什
  • SignalR 2.2 和 ARR3.0 负载平衡

    我正在使用 signalr2 2 Web 应用程序并托管在 IIS 8 中 这里我尝试使用ARR3 0为我的应用程序实现负载均衡 在我的服务器场中 我连接了两台服务器并将路由规则设置为 加权循环 每个服务器都有一个带有 HTML 页面的 j
  • 如何将文本文件从 jar 复制到 jar 外部的文件中?

    假设我的 jar 包 com test io 中有一个名为 test txt 的文件 我将如何编写一个类来检索该文本文件 然后将内容复制到文件系统上的新文件中 假设所述 jar 在您的类路径上 URL url getClassLoader
  • 我找不到 Android keytool

    我正在尝试遵循 Android 映射教程并且到了这部分我必须获得 API 密钥 我已经找到了我的debug keystore但似乎没有keytool应用程序在目录中 C Documents and Settings tward androi
  • Range(Cells()) 中的运行时错误 1004

    我在许多宏中有以下代码 但它需要大量我不需要的信息 公式如下 Range A1 h BD h Value Worksheets ABC1 Range A h BD h Value 我尝试将公式更改为更动态的版本 如下 Sub MFGI NA
  • 将 P 值添加到组内比较箱线图

    我正在尝试创建一个箱线图 它仅显示箱线图中每个条形的组内的显着 p 值 例如 它会比较 I1 和 SI2 的 一般 良好 非常好 等 我尝试使用以下代码来实现上面的情节 library ggplot2 library dplyr data
  • 三元运算符与 if 语句的优点

    我正在浏览一些代码 发现其中有一些三元运算符 这段代码是我们使用的一个库 它应该非常快 我在想除了空间之外我们是否还可以节省任何东西 你的经验是什么 表现 三元运算符的性能与编写良好的等效运算符不应有差异if else声明 它们很可能解析为