六、C++布尔类型
1、bool类型是C++中基本数据类型,专门表示逻辑值;
true表示逻辑真,false表示逻辑假
2、bool类型在内存中占一个的内存:1表示true,0表示false
3、bool类型的变量可以接收任意类型的表达式的值,其值非0则为true,0为false
七、操作符别名(了解)
&& ==> and
|| ==> or
{ ==> <%
} ==> %>
...
八、C++的函数(重点)
1、函数重载
eg:图形库的一些绘图函数
void draw(int x, int y, double r){}
void draw(int x, int y, int w, int h){}
1)定义
在相同的作用域中,定义同名的函数,但是它们的参数不同,这样的函数构成重载关系。
注意:
函数的重载和返回的类型无关;通过函数指针调用重载关系的函数,由函数指针类型决定调用哪个版本,而不再由实参类型决定调用哪个版本。
2)函数重载匹配
调用重载关系的函数时,编译器将根据实参和形参的匹配程序,自动选择最优的匹配版本。
g++ v6.3.0:
完全匹配 > 常量转换 > 升级转换 > 降级转换 > 省略号匹配
3)函数重载的原理
C++编译器是通过对函数进行换名,将参数类型信息整合到新的名字中,解决函数重载与名字冲突的矛盾。
笔试题:extern "C"
声明的作用???
答案:要求C++编译器不对函数做换名,便于C程序调用该函数。(无法重载)
语法:
extern "C" void func();
extern "C" {
void func1();
void func2();
...
}
- 扩展:函数的重入、重载、重写区别
2、函数的缺省参数(默认实参)
1)可以为函数的参数执行缺省值,调用该函数时,如果不给实参,就取缺省值作为相应的形参的值。
eg:
void mysend(int sockfd, void* buf, int size, int flag=0);
2)如果函数的声明和定义分开,缺省参数写在声明部分,而定义部分不写。
3)缺省参数必须靠右,如果一个参数有缺省值,那么这个参数的右侧所有参数都必须带有缺省值。
3、函数的哑元参数(了解)
1)定义:只有类型而没有形参变量名的形参称为哑元参数;
eg:
void func(int/* 哑元 */){}
int main(){
func(10);
}
2)使用场景
–>为了兼容旧的代码
eg:算法函数
void math_func(int a, int = 0){..}
//使用者:
int main(){
math_func(10, 20);
...
math_func(30, 40);
}
//升级算法函数:
void math_func(int a){..}
–>操作符重载中,区分前后++/--
(后面讲)
4、内联函数(inline)
笔试题:inline
关键字的作用?
1)定义
使用inline关键字修饰的函数,表示这个函数就是内联函数,编译器会对内联函数做内联优化,避免函数调用的开销。
inline 返回类型 函数名(形参表){} //内联函数
2)适用场景
a. 多次调用小而简单的函数适合内联;
b. 调用次数极少或者大而复杂的函数不适合内联;
c. 递归函数不适合内联;
注意:
内联只是一种优化的建议而不是强制要求,能否内联优化主要取决于编译器,有些函数不加inline关键字也会默认处理为内联优化,有些函数即使加了inline也会被编译器忽略。
//循环一:
for(int i = 0;i < 1000;i++)
for(int j=0;j < 100000;j++)
dosomething();
----------------------------
//循环二:
for(int j=0;j < 100000;j++)
for(int i = 0;i < 1000;i++)
dosomething();
//循环一的效果好,循环跳入跳出的次数较少。
九、C++的动态内存分配
笔试题: C++中的new/delete,和C中malloc()/free()区别
1、回顾C语言中动态内存分配
1)分配:malloc()/calloc()/realloc()
2)释放:free()
3)错误处理:返回值
2、C++使用new/delete运算符分配内存
1)分配:new new[]
2)释放:delete delete[]
3)错误处理:异常(后面讲)
//int* p = (int *)malloc(sizeof(int));
int* p = new int;
*p = 100;
//free(p);
delete p;
----------------------------------
//int* p = (int *)malloc(sizeof(int));
//*p = 0;
int* p = new int(0); //分配内存同时初始化
*p = 100;
//free(p)
delete p;
----------------------------------
//int* pa = (int*)malloc(sizeof(int)*10);
int* pa = new int[10];
//free(pa);
delete[] pa;
十、C++引用(reference)(重难点)
1、定义:
1)引用就是某个变量的别名,对引用的操作与对该变量的操作相同
2)语法:
类型 & 引用名(别名) = 变量;
注:引用在定义时要绑定一个变量,初始化以后不能修改。
注:引用的类型与绑定类型要一致。
eg:
int a = 100;
int & b = a; // b就是a的别名
b++; // 等价于a++;
cout << a << endl; // 101
int c = 200;
b = c; // 将c的值赋值给b,等价于a = c;
cout << a << endl; // 200
2、常引用
1)定义引用时加const修饰,即为常引用,不能通过常引用修改引用的目标。
2)语法:
const 类型& 引用名(别名) = 变量/右值;(右值只能放在等号右边)
类型 const& 引用名(别名) = 变量/右值;
eg:
int a = 0;
const int& b = a; // b就是a的常引用
b = 10; // error
注:
普通的引用只能引用左值,而常引用既可以引用左值也可以引用右值,所以也可以把常引用称为万能引用。
eg:
int& r = 100; // error
const int& r = 100; // ok
关于左值和右值;
1)左值:可以放在赋值运算符的左侧
int a = 10; //不是赋值运算,是初始化
a = 20; //赋值
–>普通的变量都是左值;
–>前++/–表达式结果是左值;
int num = 0;
++num = 10; //ok
++++++num; //ok
–>赋值表达式结果是左值;
int a = 0;
int b = 10;
(a = b) = 20;
cout << a << ',' << b << endl; // 20,10
2)右值:只能放在赋值运算符右侧
–>字面值常量都是右值
–>大多数表达式结果都是右值
eg:后++/–算符运算 逻辑运算 …
int num = 0;
num++ = 10; //error