表达式
4.1、基础
一元运算符:作用于一个对象。(&,解引用*)
二元运算符:作用于两个运算对象(==,乘法*);;
优先级
给大家写个例子(前几天正好群里有人问):
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int i = 1;
cout<<i++ + i++<<endl;//等于3
int j = 1;
cout<<++j + ++j<<endl;//等于6
system("pause");
return 0;
}
我比较不喜欢记录那些很繁琐的(我一般都给链接),这种网上一大堆,但是一些经验类的东西,每个人都有不同的答案(良莠不齐),我尽量记录我的理解。
回归正题,为什么结果一个3一个6?
int & int:operator++(){
//++i的是实现
*this += 1;
return * this;
}
const int int::operator++(int){
//i++的实现
int old = *this;
++(*this);
return old;
}
4.2、算术运算符
简单的加减乘除取余等。
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int i = 2;
int b = 3;
cout<<"求余"<<b % i;
system("pause");
return 0;
}
因为很多类型占的位数是有最大值的,如果超出最大值会溢出。
4.3、逻辑运算符
与或非,大于小于等于= =,这玩意没啥难度吧。
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int i = 2;
if(i != 1 || !(i < 0)) i--;
cout<<i<<endl;
system("pause");
return 0;
}
4.4、赋值运算符
这里我感觉 +=,/=等操作需要说一下,这种赋值运算符完全等价于 a = a op b;op就是你的操作。
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int i = 2;
i += 1;
cout<<i<<endl;
system("pause");
return 0;
}
4.5、递增递减运算符
递增递减运算符不光光可以进行数值上的递增递减,还可以用于迭代器的迭代。C++ primer不推荐使用递增递减运算符的后置版本。
4.6、成员访问运算符
重点写了程序里去了,下面两个方法等价。
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
int main()
{
string i = "我爱你", *i_ptr = &i;
cout<<(*i_ptr).size()<<"等价于"<<i_ptr->size();
system("pause");
return 0;
}
4.7、条件运算符
条件?条件为真输出:条件为假输出
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
int main()
{
string i = "我爱你";
string a = (i == "我爱你") ? "我喜欢你":"对不起";
cout<<a;
system("pause");
return 0;
}
4.8、位运算符
移位是刷题经常用到的一种思想,可以减少运算花费的时间。
链接
4.9、sizeof运算符
返回一个表达式或一个类型名字所占的字符是数。
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
int main()
{
cout<<sizeof(int)<<" "<<sizeof("aaa");
system("pause");
return 0;
}
对数组执行sizeof就算得到整个数组所占空间大小,对指针使用sizeof得到的是指针本身所占空间大小。
4.10、逗号运算符
按照从左到右的顺序运算,得到的永远是最后边最后一个运算。
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
int main()
{
int i, j;
j = 1;
i = (j++, j+100, 10+j);
cout << i;
system("pause");
return 0;
}
4.11、类型转换
很简单的道理,你如果把数据存了char_32t中占31位,然后转成了char_16t,那数据肯定会丢失对吧,还有浮点型转换整型。明白原理永远比死记硬背更重要啊。
显示转换(这里就比较有趣了):
- static_cast:任何具有明确定义的转换,只要没有底层const都可以用static_cast。
- dynamic_cast:支持运行时的类型识别。
- const_cast:专门用来改变运算对象的底层const。
- reinterpret_cast(差点打成interpret_cast最近背单词串了= =):为运算对象提供较低层次上的重新解释。
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
int main()
{
int j = 1;
double j1 = static_cast<double>(j);
char p = '1';
const char *p_ptr = &p;
char * p_ptr1 = const_cast<char *>(p_ptr);
int *j_ptr = &j;
char *j_ptr1 = reinterpret_cast<char*>(j_ptr);
cout<<"const_cost的结果"<<*p_ptr1<<endl;
cout<<"static_cost的结果"<<j1<<endl;
cout<<"reinterpret_cost的结果"<<*j_ptr1<<endl;
system("pause");
return 0;
}
旧式的强制类型转换:
是我比较常用的方法(效果与reinterpret_cast一样)
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
int main()
{
int j = 1;
int *j_ptr = &j;
char *j_ptr1 = (char *)j_ptr;
cout<<"reinterpret_cost的结果"<<*j_ptr1<<endl;
system("pause");
return 0;
}