a++和++a
a++;是先使用a的值,然后增加
b=a++;
执行顺序 b = a; => a++;
b=++a;
执行顺序 a++; => b=a;
移位
将数据改为二进制表示,然后移位,重点考虑移进的位是1还是0,以及是否达到 除2和乘2的效果
右移位 a>>b
只有当a为正数时 右移补零;如果a是负数,右移高位补1,所以不论是正还是负右移都没有问题。
左移位 a<<b
低位补零,高位移出,所以当a为负数时,符号位被移出,结果不确定是正还是负,所以左移位对有符号数据不要用。
异常
抛出异常
void fun(){
throw.std::exception();
}
捕获异常
try{
fun();
}catch(std::exception exception ){
}
const用法
定义常量
const float MATH_PI = 3.1415;
在单片机编程中,被const 修饰的变量会被分配到容量更大的Flash存储区,从而节省RAM(内存)的开销
保护变量
//1.不想传入的参数 a被函数修改,
//2.传指针或者引用,比值传递的效率更高(避免数据复制操作)
void fun(const String * a){
a="haha";//编译器报错
}
定点数Q值和浮点数
定点数:小数点固定,小数点固定在哪里则用表示Q值表示,比如Q15 = 2^15,当小数0.5 表示为Q15的数时为 0.5(Q15)=0.5*2^15 = 16384,也就是用15bits表示小数位,所以定点数一旦Q值确定,则定点数的精度也就确定了,表示范围则与存储数据的位宽有关,一旦位宽确定,表示范围也就确定了。浮点数:小数点不固定(浮动),当然具体怎么浮动,是有一套算法的,也就是浮点数处理器(FPU),对于没有浮点处理器的CPU,浮点处理器的功能将完全由软件取代,这时软件做浮点数处理所耗费的时间就比较长了。浮点数相对定点数的好处在于,数据表示范围更大,比如同样16bits下,浮点数通过浮动的小数点,在数据特别大时用16bits全部表示整数,也可以在数据非常小时用16bits全部表示小数。与此同时,浮点数的精度也是浮动的,浮点数解决精度的办法则是加大浮点数的控件从32bits,64甚至更大。
函数指针
bool Fun_a(int a,int b){
if(a>b) retrun 1;
else return 0;
}
bool Fun_b(int a,int b){
if(a*b>0) retrun 0;
else return 1;
}
//以函数作为参数的传递方法
int Fun_c( int a,int b, int c, bool (*p_Fun)(int ,int)){
if( (*p_Fun)(a,b) ) { //函数指针的调用方法
return c++;
}else{
return c--;
}
}
//调用函数参数的方法
Fun_c(11,10,0,Fun_a);// return 1
Fun_c(11,10,0,Fun_b);// return -1
内联(inline)与宏定义
首先 inline 是C++新增的,C没有,宏是C和C++共有的。
inline int mult_1(int a,int b){
return a*b;
}
#define mult_2(a, b) a*b
#define mult_3(a, b) (a)*(b)
//宏调用
mult_1(2+1,3);// return 9
mult_2(2+1,3);// 宏会无脑展开为 2+1*3 结果则是5
mult_3(2+1,3);// 宏会无脑展开为 (2+1)*(3) 结果是9
C++引用
1.alias(别名) 尽量不要用别名,两个名字代表一个变量会把你搞得更晕
int b = 10;
int &a = b;
此时a就是b;
2.参数传递时避免产生副本,节省内存和运行时间
void fun(int &a);
3.传入参数时加入const 辅助,传递参数时不想被子函数修改,这个const是局部作用的,变量在子函数中是 const 属性,但是在函数外面就没有这个const 属性了
void fun(const int &a);
4.传出参数使用引用
int & fun(int &a);
int a = fun(b); //在fun(b) 执行完输出结果 会产生临时变量 X ;第二步才是将 a = x;如果使用引用 则当X的数据类型很大时的内存开销和拷贝时间,
但是 传出来的引用不能是栈空间数据,因为程序执行完之后,数据内存释放,引用也就没了意义,所以该数据要不是参数引用或指针传入,或者子函数动态分配的
5.传输参数使用引用时 const 修饰
const int & fun(int &a);
这里主要是避免一种语法可行,单容易错误的语句通过
比如
fun(b) = a; //这时语法没有错误 可以理解为返回的那个引用被a赋值了
但是 const 修饰之后 上面的语法就报错了。这个const 属性也是局部的
默认参数
默认参数的写法
void fun(int a=1);
调用方法
fun();或者 fun(2);
注意: void fun(int a=1, int b);是不被允许的,在多个参数时,默认参数要放在参数表右边,应该写为 void fun(int b, int a=1);
常用:在类构造函数中,避免构造函数重载过多。
函数重载
函数的特征标(function signature)即参数表相同是指,参数类型,数量以及排列相同,
1.类型引用和类型为同一特征标
void fun(int &a);与void fun(int a);不构成重载
2.变量名不影响特征标
void fun(int b);与void fun(int a);不构成重载
3.返回值不属于特征标,不能构成重载
int fun(int a); 与 void fun(int a)
4.当重载类型不匹配时,C++会隐性进行强制转换为重载函数,但是可转换的重载过多则会报错。(C++的隐式转换是相较于C#或JAVA的一个缺限,容易产生不易察觉的错误)
函数模板
语法:
template <typename T> //template <class T>
void func(T a);
//调用
int a = 10;
func(a);
float b = 1.0;
func(b); //这里有点像重载,但是模板实现的。
class man c = new man();
func(c);//需要确定func内部是否支持man类的操作。
对于处理逻辑相同,而类型不一样的时候可以使用模板,在类使用模板时,要注意模板内的处理结构是否能与类匹配,比如+操作符如果类没有重载时,是不能实现的.