1. 缺省参数前言:更多内容请看总纲《嵌入式C/C++学习路》
- 可以为函数的参数指定缺省值,调用该函数时若未指定实参,则与该实参相对应的形参取缺省值
- 函数参数的缺省值只能在函数声明中指定(编译器只看声明,不看定义)
- 如果函数的某一个参数具有缺省值,那么该参数后面的所有参数必须都具有缺省值
- 不要因为使用缺省参数而导致重载歧义
#include2. 哑元using namespace std; void foo(int a, char b, float c = 4.56f, const char *d = "Hello C++ !") { cout << a << ' ' << b << ' ' << c << ' ' << d << endl; } void bar(int x = 666); // 在声明中定义缺省参数 int main(void) { foo(10, 'A', 1.23f, "Hello world!"); foo(10, 'A', 1.23f); // 缺省 foo(10, 'A'); // 缺省 bar(); // 缺省 return 0; } void bar(int x) { // 这是函数定义,声明在main上面,在声明里定义缺省参数 cout << x << endl; }
- 只指定类型而不指定名称的函数参数,我们称为哑元
- ——保证函数的向下兼容
- ——形成函数的重载版本
#include3. 内联using namespace std; void foo(int){ // 哑元参数 cout << "foo(int)" << endl; } int main(void){ foo(10); return 0; }
- 内联就是用函数已被编译好的二进制代码,替换对该函数的调用指令
- 内联在保证函数特性的同时,避免了函数调用开销
- 注意内联与有参宏(宏函数)的区别
- 内联会使可执行文件的体积和进程代码的内存变大,因此只有频繁调用的简单函数才适合内联
- 若函数在类声明中直接定义,则自动被优化为内联,否则可在其声明处加上inline关键字
- inline关键字仅表示期望该函数被优化为内联,但是否适合内力那则完全由编译器决定
- 稀少被调用的复杂函数和递归函数都不适合内联
- 继续使用标准C库函数malloc/calloc/realloc/free
- 使用new/delete操作符在堆中分配/释放内存
int pi = new int;
delete pi;
- 在分配内存的同时初始化
int *pi = new int (100);
- 以数组方式new的也要以数组方式delete
int *pi = new int[ 4 ]{1,2};
delete[] pi;
#includeusing namespace std; int main() { int *p1 = new int; *p1 = 1234; cout << *p1 << endl; delete p1; p1 = new int(1000); // 带初值 cout << *p1 << endl; delete p1; p1 = new int[4]{10, 20, 30, 40}; // 如果不赋初值,默认为0 cout << p1[0] << ' ' << p1[1] << ' ' << p1[2] << ' ' << p1[3] << endl; delete[] p1; // 记得加中括号 return 0; }
- 通过new操作符分配N维数组,返回N-1维数组指针
int (*prow)[4] = new int [3][4]; // 二维数组的首地址是一维数组
int (*ppage)[4][5] = new int [3][4][5]; // 三维数组的首地址是二维
- 不能通过delete操作符释放已释放过的内存
- delete野指针后果未定义,delete空指针安全,即 p = NULL;
- 内存分配失败,new操作符抛出bad_alloc异常
- 定位分配:
new(指针)类型(初值);
在一个已分配的内存空间中创建对象
#includeusing namespace std; int main() { int *p1 = new int; *p1 = 1234; cout << *p1 << endl; delete p1; p1 = new int(1000); // 带初值 cout << *p1 << endl; delete p1; p1 = new int[4]{10, 20, 30, 40}; // 如果不赋初值,默认为0 cout << p1[0] << ' ' << p1[1] << ' ' << p1[2] << ' ' << p1[3] << endl; delete[] p1; int (*p2)[4] = new int[3][4]{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; for (size_t i = 0; i < 3; i++) { for (size_t j = 0; j < 4; j++) { cout << p2[i][j] << ' '; } cout << endl; } delete[] p2; return 0; }
#includeusing namespace std; int main() { int *p1 = new int; *p1 = 1234; cout << *p1 << endl; delete p1; p1 = new int(1000); // 带初值 cout << *p1 << endl; delete p1; p1 = new int[4]{10, 20, 30, 40}; // 如果不赋初值,默认为0 cout << p1[0] << ' ' << p1[1] << ' ' << p1[2] << ' ' << p1[3] << endl; delete[] p1; int(*p2)[4] = new int[3][4]{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; for (size_t i = 0; i < 3; i++) { for (size_t j = 0; j < 4; j++) { cout << p2[i][j] << ' '; } cout << endl; } delete[] p2; short buf[4]; // 在栈里面不需要释放内存 p1 = new(buf) int(0x12345678); cout << showbase << hex << *p1 << endl; // showbase打印前缀 hex是16进制 cout << buf[0] << ' ' << buf[1] << endl; // 内存地址重叠 return 0; }



