C++超详细讲解逻辑操作符

 更新时间:2022年06月01日 08:39:16   作者:清风自在 流水潺潺  
在C语言中,逻辑运算符有&&、||、!;&&表示“与”的意思,需要两端的表达式的值都为true,该式的值才为true。||表示“或”的意思,两端的表达式的值只要有一端为true,该式的值就为true。!表示“非”的意思,将该式的真值换成相反的真值,即false和true互换

一、逻辑运算符的原生语义

  1. 操作数只有两种值( true和 false )逻
  2. 辑表达式不用完全计算就能确定最终值
  3. 最终结果只能是 true 或者 false

下面看一个逻辑表达式的代码:

#include <iostream>
#include <string>
using namespace std;
int func(int i)
{
    cout << "int func(int i): i = " << i << endl;
    return i;
}
int main()
{
    if (func(0) && func(1))
    {
        cout << "Result is true!" << endl;
    }
    else 
    {
        cout << "Result is False!" << endl;
    }
    cout << endl;
    if (func(0) || func(1))
    {
        cout << "Result is true!" << endl;
    }
    else 
    {
        cout << "Result is False!" << endl;
    } 
    return 0;
}

输出结果如下:

这就是逻辑操作符的短路规则,可以参照我之前写的详细讲解逻辑运算符的使用

二、重载逻辑操作符

逻辑操作符可以重载吗?重载逻辑操作符有什么意义?

下面看一个重载逻辑操作符示例:

#include <iostream>
using namespace std;
class Test
{
    int mValue;
public:
    Test(int v)
    {
        mValue = v;
    }
    int value() const
    {
        return mValue;
    }
};
bool operator &&(const Test& l, const Test& r)
{
    return l.value() && r.value();
}
bool operator ||(const Test& l, const Test& r)
{
    return l.value() || r.value();
}
Test func(Test i)
{
    cout << "Test func(Test i): i.value() = " << i.value() << endl;
    return i;
}
int main()
{
    Test t0(0);
    Test t1(1);
    if (func(t0) && func(t1))
    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }
    cout << endl;
    if (func(t0) || func(t1))
    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }
}

输出结果如下:

按照短路法则,func(t0) && func(t1) 应该只执行 func(t0),这里却输出了func(t0) 和 func(t1) 运行后的值,这是为什么呢?且看下面解析。

问题的本质分析

  1. C++ 通过函数调用扩展操作符的功能
  2. 进入函数体前必须完成所有参数的计算
  3. 函数参数的计算次序是不定的
  4. 短路法则完全失效

逻辑操作符重载后无法完全实现原生的语义。

上述代码等效写法如下:

#include <iostream>
using namespace std;
class Test
{
    int mValue;
public:
    Test(int v)
    {
        mValue = v;
    }
    int value() const
    {
        return mValue;
    }
};
bool operator &&(const Test& l, const Test& r)
{
    return l.value() && r.value();
}
bool operator ||(const Test& l, const Test& r)
{
    return l.value() || r.value();
}
Test func(Test i)
{
    cout << "Test func(Test i): i.value() = " << i.value() << endl;
    return i;
}
int main()
{
    Test t0(0);
    Test t1(1);
    if (operator && (func(t0), func(t1)))
    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }
    cout << endl;
    if (operator || (func(t0), func(t1)))
    {
        cout << "Result is true!" << endl;
    }
    else
    {
        cout << "Result is false!" << endl;
    }
}

输出结果和上面一样:

将func(t0) && func(t1) 改写成operator && (func(t0), func(t1)),就不难理解为什么了。核心就两点:

1.进入函数体前必须完成所有参数的计算

2.函数参数的计算次序是不定的

一些有用的建议

  • 实际工程开发中避免重载逻辑操作符
  • 通过重载比较操作符代替逻辑操作符重载
  • 直接使用成员函数代替逻辑操作符重载
  • 使用全局函数对逻辑操作符进行重载

三、小结

  • C++ 从语法上支持逻辑操作符重载
  • 重载后的逻辑操作符不满足短路法则
  • 工程开发中不要重载逻辑操作符
  • 通过重载比较操作符替换逻辑操作符重载
  • 通过专用成员函数替换逻辑操作符重载

到此这篇关于C++超详细讲解逻辑操作符的文章就介绍到这了,更多相关C++逻辑操作符内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++实现分水岭算法(Watershed Algorithm)

    C++实现分水岭算法(Watershed Algorithm)

    这篇文章主要为大家详细介绍了C++实现分水岭算法Watershed Algorithm,具有一定的参考价值,感兴趣的小伙伴们可以参考一 下
    2018-01-01
  • C++ 类访问控制的条件总结

    C++ 类访问控制的条件总结

    这篇文章主要介绍了C++ 类访问控制的条件总结的相关资料,需要的朋友可以参考下
    2017-05-05
  • C++中的vector容器对象学习笔记

    C++中的vector容器对象学习笔记

    这篇文章主要介绍了C++中的vector容器对象学习笔记,其中文章最后标红的resize与reserve方法的差别特别需要注意,需要的朋友可以参考下
    2016-05-05
  • C 语言关于联合体的相关知识

    C 语言关于联合体的相关知识

    这篇文章主要介绍了C 语言关于联合体的相关知识,文中讲解非常细致,代码帮助大家更好的理解学习,感兴趣的朋友可以了解下
    2020-06-06
  • C++运算符重载图文详解

    C++运算符重载图文详解

    运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的
    2021-09-09
  • 基于C++编写一个密码系统

    基于C++编写一个密码系统

    这篇文章主要为大家详细介绍了如何基于C++编写一个简单的密码系统,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • 解读C++中枚举(enum)的使用

    解读C++中枚举(enum)的使用

    对于开发C++来说,枚举是一个几乎必然用到的功能。当然今天要讲的枚举肯定不是平常漫不经心的使用,而是从里到外地深扒它。本文就来逐渐揭开它神秘地面纱,发现一些未曾注意到的东西吧
    2023-03-03
  • C++11新特性“=default”,“=delete”的使用

    C++11新特性“=default”,“=delete”的使用

    =default、=delete 是C++11的新特性,分别为:显式缺省(告知编译器生成函数默认的缺省版本)和显式删除(告知编译器不生成函数默认的缺省版本),本文就来介绍一下如何使用
    2021-05-05
  • 利用Matlab实现阴影柱状图的绘制

    利用Matlab实现阴影柱状图的绘制

    阴影柱状图绘制的代码MATHWORKS上也有,不过是生成图片后,识别图像上不同颜色块并直接修改像素生成阴影线。这样的生成方式不可逆且自由度较低,所以本文为大家带来的是一个直接画线条填充的硬画版本,希望有所帮助
    2022-09-09
  • C语言每日练习之冒泡排序

    C语言每日练习之冒泡排序

    这篇文章主要介绍了C语言冒泡排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-11-11

最新评论