首页 > 编程学习 > C++入门:运算符

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C++ 内置了丰富的运算符,并提供了以下类型的运算符:

  • 算术运算符

  • 关系运算符

  • 逻辑运算符

  • 位运算符

  • 赋值运算符

  • 杂项运算符

& :只有2个都为1,那么结果是1,否则为0;例如:1&1=1,1&0=0,0&0=0,0&1=0;

11 & 3 = 3

   00001011
&  00000011
=  00000011 = 3

| :只要有一个是1,那么结果为1,否则为0;例如:1&1=1,1&0=1,0&0=0,0&1=1;

11 | 3 = 11

   00001011
|  00000011
=  00001011 = 11

>> :向右位移,就是把尾数去掉位数,例如:153 >> 2,153的二进制是:10011001,屁股后面去掉 2 位 100110,100110 转化成十进制就是 38,153 = 10011001,38 =100110,"01" 去掉了。

<< :向左位移,就是把开头两位数去掉,尾数加位数00,例如:

107 = 0110 1011 <<2
<<
172 = 1010 1100

在计算机中由于是32位的

107 = 0000 0000   0000 0000   0000 0000   0110 1011 <<2
<<
428 = 0000 0000   0000 0000   0000 0001   1010 1100

^ :两个相同的数会变成0,反之是1,例如:1&1=0,1&0=1,0&0=0,0&1=1;

11^3 = 8

   00001011
^  00000011
=  00001000 = 8

关于逻辑运算符 && ,|| 的巧用方式

逻辑与 &&

&& 会先判断左边的值是否为真。

如果为假,那么整个表达式毫无疑问也为假。

如果为真,那就还需要判断右值,才能知道整个式子的值。

这个时候判断右值的过程就起了一个if的作用,可以利用这个过程判断右边表达式是否为真。

下面代码:

/*不用任何循环语句,不用if,来实现1+2+3+...+10的值*/
#include <iostream>
using namespace std;int add(int c)
{int a=0;c&&(a=add(c-1));//递归循环,直到传入c的值为0则结束循环cout<<c+a<<endl;return c+a;
}
int main()
{ add(10);return 0;
}

逻辑或 ||

其实与上面的逻辑与 && 大同小异。

都是先判断左边是否为真,再来考虑右边。

因为逻辑与 || 只需要左边为真,那么整个表达式就有值,就不会再去算右边的值了。

所以我们加个 ! 让 c 值为假时,!c 才为真,这样的话逻辑与 || 还需要判断右边的表达式才能计算出整个表达式的值。

(!c)||(a=add(c-1));

这样就达到了和用逻辑与&&时一样的目的。

代码:

/*不用任何循环语句,不用if,来实现1+2+3+...+10的值*/
#include <iostream>
using namespace std;int add(int c)
{int a=0;(!c)||(a=add(c-1));//递归循环,直到传入c的值为0,(!c)就为真,结束循环cout<<c+a<<endl;return c+a;
}
int main()
{ add(10);return 0;
}

除法/和求模%若两个操作数是正数,则除法的结果是正数,求模的结果也是正数若两个操作数是负数,则除法的结果是正数,求模的结果是负数若只有一个操作数是负数,则除法和求模的结果取决于机器,除法可以确定结果是负数逻辑与和逻辑或操作符总是先计算其左操作数,然后再计算其右操作数,只有在仅靠左操作数的值无法确定该逻辑表达式的结果时,才会求解其右操作数区分 if(i<j<k) 和 if(i<j && j<k)第一个i<j或者为0或者为1,只要k大于1,表达式就为true第二个必须i<j且j<k表达式才为true区分 if(val) 和 if(val == true)第一个只要val非零则表达式为true,val为0则表达式为false第二个只有val为1表达式为true,val非1则表达式为false

int val = 2;
if(val==true){              //不会进入ifcout<<"val==true"<<endl;
}

多个赋值操作符中,各对象必须具有相同的数据类型,或者具有可转换为同一类型的数据类型。

int ival; int *pval;
ival = pval = 0;  //error 尽管ival和pval都可以赋值为0
string s1,s2;
s1 = s2 = "OK"    //ok

如果指针指向不是用new分配的内存地址,则在该指针上使用delete是不合法的。

通常编译器不能断定一个指针是否指向动态对象,因此尽管这样做是错误的,但在大部分编译器上仍能运行通过,但是会产生运行时错误。整形提升

对于所有比int小的整形(char, signed char, unsigned char, short, unsigned short),如过该类型所有可能值都包含在int中,他们会被提升为int型,否则,他们将被提升为unsigned int。

对于包含signed和unsigned int型的表达式,表达式中的signed型整数会被转换为unsigned型。

int i = -5;
unsigned int ii = 1;
cout<<(i>ii)<<endl;   //输出1,非常有趣的结果 原因是int型的i转换为unsigned int型
short i = -5;
unsigned short ii = 1;
cout<<(i>ii)<<endl;  //输出0 比较时short和unsigned short都提升为int型

运算符优先级助记歌(自己编的,优先级从高到低):

先算右一后左一,①

乘除加减移位比。②

与异或或位逻辑,③

三目赋值逗号稀。④

①先算右面的一元运算符,后算左面的。

②乘除代表*/%,加减就是+和-,移位就是<<和>>,比就是比较运算符,注意比较运算符先算<、>、<=和>=这4个含不等号的,后算==和!=这两个。

③先算按位逻辑运算符,再算普通的逻辑运算符;按位逻辑运算符的顺序是&^|,逻辑运算符先算&&再算||,只是少了逻辑异或。

④先算三目运算符,再算赋值运算符,逗号运算符的优先级最低,所以说它“稀”。


本文链接:https://www.ngui.cc/article/show-861246.html
Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000