zoukankan      html  css  js  c++  java
  • 发一个"&&"和“&”,“||”和“|”

    前段时间代码出了个和题目有关的Bug,一直奇怪为何出问题。无奈反了一下,突然就明白了,原来&&、&、||和|的用法,书本上并没有讲全。
     

    &&和&的差别,或许不只是我们从书本表面理解的那样。看两段例子:

     1 //一A
    2 #include <iostream>
    3 using namespace std;
    4
    5 int main()
    6 {
    7 int a = 2,b = 3;
    8 if((a < 2) && (++b < 3))
    9 {
    10 cout<<"Not skip"<<endl;
    11 }
    12
    13 cout<<a<<","<<b<<endl;
    14
    15 return 0;
    16 }

    输出结果:2,3

     

     1 一B
    2 #include <iostream>
    3 using namespace std;
    4
    5 int main()
    6 {
    7 int a = 2,b = 3;
    8 if((a < 2) && (++b < 3))
    9 {
    10 cout<<"Not skip"<<endl;
    11 }
    12
    13 cout<<a<<","<<b<<endl;
    14
    15 return 0;
    16 }

    输出结果:2,4

     

    &&:(Ea && Eb)时,如果Ea==false,则不再去计算Eb。
    &:(Ea & Eb)时,无论Ea为何值,都要计算Eb。
    ————————————————————————————————————————————————
     
    ||和|与&&和&类似。
     1 二A
    2 #include <iostream>
    3 using namespace std;
    4
    5 int main()
    6 {
    7 int a = 2,b = 3;
    8 if((a == 2) || (++b < 3))
    9 {
    10 cout<<"Not skip"<<endl;
    11 }
    12
    13 cout<<a<<","<<b<<endl;
    14
    15 return 0;
    16 }
    输出结果:2,3
     
    //二B(--!不好意思,没考虑到会这样)
    #include <iostream>
    using namespace std;

    int main()
    {
    int a = 2,b = 3;
    if((a == 2) | (++b < 3))
    {
    cout<<"Not skip"<<endl;
    }

    cout<<a<<","<<b<<endl;

    return 0;
    }
    输出结果:2,4
     
    ||:(Ea || Eb)时,若Ea==true,不再计算Eb。
    |:(Ea || Eb)时,先计算Ea与Eb的结果,再执行|。
    从可执行文件的反汇编中也能看出端倪。
     
    ;二A-DEBUG
    int a = 2,b = 3;
    001C14DE mov dword ptr [a],2
    001C14E5 mov dword ptr [b],3
    if((2 == a) || (b++))
    001C14EC cmp dword ptr [a],2 ;比较a和2
    001C14F0 je main+4Dh (1C150Dh) jump equal,跳转到1C150Dh,即if程序块内
    001C14F2 mov eax,dword ptr [b]
    001C14F5 mov dword ptr [ebp-0DCh],eax
    001C14FB mov ecx,dword ptr [b]
    001C14FE add ecx,1
    001C1501 mov dword ptr [b],ecx
    001C1504 cmp dword ptr [ebp-0DCh],0
    001C150B je main+78h (1C1538h)
    {
    cout<<"Not skip"<<endl;
    001C150D mov esi,esp
    001C150F mov eax,dword ptr [__imp_std::endl (1CA340h)]
    001C1514 push eax
    001C1515 push offset string "Not skip" (1C7870h)
    001C151A mov ecx,dword ptr [__imp_std::cout (1CA344h)]
    001C1520 push ecx
    001C1521 call std::operator<<<std::char_traits<char> > (1C1159h)
    001C1526 add esp,8
    001C1529 mov ecx,eax
    001C152B call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (1CA32Ch)]
    001C1531 cmp esi,esp
    001C1533 call @ILT+420(__RTC_CheckEsp) (1C11A9h)
    }
    cout<<a<<","<<b<<endl;
    ;二B-DEBUG
    int a = 2,b = 3;
    008C14DE mov dword ptr [a],2
    008C14E5 mov dword ptr [b],3
    if((2 == a) | (b++))
    008C14EC xor eax,eax
    008C14EE cmp dword ptr [a],2
    008C14F2 sete al ;如果相等,ZF=1。不明白,哪位大牛知道什么意思麻烦留言给我解释一下
    008C14F5 or eax,dword ptr [b]
    008C14F8 mov dword ptr [ebp-0DCh],eax
    008C14FE mov ecx,dword ptr [b]
    008C1501 add ecx,1
    008C1504 mov dword ptr [b],ecx
    008C1507 cmp dword ptr [ebp-0DCh],0
    008C150E je main+7Bh (8C153Bh) ;这里直接跳到if块外面。
    {
    cout<<"Not skip"<<endl;
    008C1510 mov esi,esp
    008C1512 mov eax,dword ptr [__imp_std::endl (8CA340h)]
    008C1517 push eax
    008C1518 push offset string "Not skip" (8C7870h)
    008C151D mov ecx,dword ptr [__imp_std::cout (8CA344h)]
    008C1523 push ecx
    008C1524 call std::operator<<<std::char_traits<char> > (8C1159h)
    008C1529 add esp,8
    008C152C mov ecx,eax
    008C152E call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (8CA32Ch)]
    008C1534 cmp esi,esp
    008C1536 call @ILT+420(__RTC_CheckEsp) (8C11A9h)
    }
    cout<<a<<","<<b<<endl;
    008C153B mov esi,esp
    定是编译器做了优化。
    测试了一下GCC、VC都会有这样的优化,Java不会反,但是编了段代码试了一下,也是一样的。
     
    原来编译器们都知道,就我不知道.......



     

  • 相关阅读:
    第四篇博客
    第三篇博客
    第二篇博客
    DS博客作业04--图
    DS博客作业03--树
    DS博客作业02--栈和队列
    C博客作业05--指针
    C博客作业04-数组
    C语言博客作业03--函数
    C语言博客作业02--循环结构
  • 原文地址:https://www.cnblogs.com/raymon/p/2365068.html
Copyright © 2011-2022 走看看