C语言中已经学过有关逻辑运算符**&&,||, ! **以及位运算符 **&, |, ^, ~**的知识,本节我们不再赘述,只介绍一些应用。
值得一提的是,在C++中,&&可以用and代替,|| 可以用or代替,!可以用 not 代替。比如:
if (1 and 2) {
cout << "you are excellent!";
}
if (1 or 0) {
cout << "good morning!";
}
像and,or,not这类可以代替原有运算符作用的单词,我们也称为替代关键词。–> C++替代关键词(and,or,not)_Qt君-CSDN博客
那么逻辑运算和位运算有什么好玩的地方呢?(以下内容参考了JS 的骚操作_爱写bug的小boy的博客-CSDN博客),在此表示感谢!
使用!!将数字转化为布尔代数值(1和0)
cout << !!10; // 1
cout << !!0; // 0
// 当然,用bool转换看得更明白
cout << bool(10) << bool(0); // 1 0
其实在JavaScript语言中,其他类型(比如字符串,数组类型)也可以转换为布尔值,但是C++中却不行。比如:
cout << !!""; // 1
cout << !!"a" // 1
// 虽然上面没有报错,但是所有的字符串(包括空字符串)结果都为1,这样的转换就失去了意义。
cout << !![]; // 报错,然而在JavaScript语言中!![]语法却是正确的
<< 快速算出2的整数倍
cout << (1 << 2); // 2
cout << (1 << 10); // 1024 注: 10月24日是程序员节哦
cout << (1 << 2.5); // 报错:表达式必须具有整数或者未区分范围的枚举类型
// 可见C++中右移小数个2进制位是不行的,可以使用强制类型转换 int(2.5)
// 使用变量时
int x = 2.5;
cout << (1 << x); // 并不报错,输出2,可见应该进行了类型转换,2.5转换为2
// 不只是2的整数次幂!
cout << (1 << 6 + 1); // 65 即 'A'的ASCll码
// 不只是乘法,使用 >> 右移运算符可以快速整除2
cout << (3 >> 1); // 1
cout << (4 >> 1); // 2
判断奇偶性
如果x是奇数, x & 1 == 1
如果x是偶数, x & 1 == 0
cout << (3 & 1); // 1 所以3为奇数
cout << (6 & 1); // 0 所以6为偶数
一行代码交换两变量的值
int x = 10, y = 20;
x^=y^=x^=y;
cout << x << " " << y; // 20 10
^ 判断两数是否相等
// 常规判断
if(x != 20){
cout << "x不等于20";
}
// 使用 ^ 来判断
if(x ^ 20){
cout << "x不等于20";
}
n&(n-1) 来判断是否为2的整数幂
如果结果为0,则说明为2的整数幂
int x = 20;
cout << x&(x-1); // 不为0,20不是2的整数幂
x = 32;
cout << x&(x-1); // 为0,32是2的整数幂
~ 的妙用
我们来设想一种情况:
我们有一个数组 int arr[] = [1,3,6,8,10]; 现在你写了一个函数 int find(int *arr,int e)来查找e在数组arr中的位置,如果没找到,则返回 -1;那么我们怎么根据返回值来判断到底找到了没有呢?
// 第一种做法,很容易理解
if(find(arr,4) != -1){
cout << "找到4了";
}
// 第二种做法,使用~
if(~find(arr,4)){
cout << "找到4了";
}
// 规律是:~x == -(x+1), 所以 -1 按位取反后为0, 其他的0,1,2之类的按位取反后都不为0
本节内容叙述了一些逻辑运算和位运算的用法,并不是我们需要这么写,而是感受这些运算符的神奇之处,即使是很简单的东西,可能也有大智慧蕴含其中。