===>形参带默认值的函数
1.给默认值的时候,从右向左给
2.调用效率的问题
3.定义出可以给形参默认值,声明也可以给形参默认值
4.形参给默认值的时候,不管是定义处给,还是声明处给,形参默认值只能出现一次
#includeusing namespace std; int sum(int a, int b = 20); //若为 int sum(int a = 10, int b) 会报错 默认从右向左给 int sum(int a = 10, int b); int main() { int a = 10; int b = 20; int ret = sum(a, b); cout << "ret:" << ret << endl; ret = sum(a); ret = sum(); // sum(20, 50); system("pause"); return 0; } int sum(int a, int b) { return a + b; }
运行结果:
02 inline内联函数1.inline内联函数 和 普通函数的区别???
inline内联函数:在编译过程中,就没有函数的调用开销了,在函数的调用点直接把函数的代码进行展开处理了,inline函数不再生成相应的函数符号
2.设置成内联函数准则:
短时间内多次调用且函数内部实现较为简单
3.inline只是建议编译器把这个函数处理成内联函数
但是不是所有的inline都会被编译器处理成内联函数 ——递归/函数内部代码过多
4.debug版本上,inline是不起作用的; inline只有在release版本下才能出现
inline int sum(int x, int y) // *.o sum_int_int .text
{
return x + y;
}
int main()
{
int a = 10;
int b = 20;
int ret = sum(a, b);
// 此处有标准的函数调用过程 参数压栈,函数栈帧的开辟和回退过程
// 有函数调用的开销
// x+y mov add mov 1000000 x+y
//例如,循环100次sum函数调用,可能函数调用时间开销大过内部指令生成的时间,则函数调用的开销过大,inline可以省去函数调用开销(参数压栈 函数栈帧的开辟和回退)
//相当于ret = a + b;
return 0;
}
03 函数重载
1.定义
一组函数,其中函数名相同,参数列表的个数或者类型不同,那么这一组函数
就称作函数重载。
2.C++为什么支持函数重载,C语言不支持函数重载?C++代码产生函数符号的时候,函数名+参数列表类型组成的!
C代码产生函数符号的时候,==函数名=来决定!
3.函数重载需要注意些什么?1.一组函数要称得上重载,一定先是处在同一个作用域当中的。
在局部进行函数声明,会在局部作用域选择声明的函数
bool compare(int a, int b) // compare_int_int
{
cout << "compare_int_int" << endl;
return a > b;
}
bool compare(double a, double b) // compare_double_double
{
cout << "compare_double_double" << endl;
return a > b;
}
bool compare(const char *a, const char *b) // compare_const char*_const char*
{
cout << "compare_char*_char*" << endl;
return strcmp(a, b) > 0;
}
int main()
{
bool compare(int a, int b); // 函数的声明 优先调用
compare(10, 20); // call compare_int_int
compare(10.0, 20.0); // double -> int 造成错误
compare("aaa", "bbb"); // const char* => int
return 0;
}
//输出结果会优先调用compare_int_int,造成错误
2.const或者volatile的时候,是怎么影响形参类型的。
void func(int *a) {} // int
void func(int *const a) {}
int main()
{
int a = 10;
const int b = 10;
cout << typeid(a).name() << endl;
cout << typeid(b).name() << endl;
return 0;
}
//const不会改变类型还是int 造成函数重定义
//加入指针后 则可以被重载 不加指针 相当于函数重定义
3.一组函数,函数名相同,参数列表也相同,仅仅是返回值不同?
不叫重载(重载和返回值无关)
4.C++和C语言代码之间如何互相调用C 调用 C++:无法直接调用,怎么办?
把C++源码扩在extern “C”
//c++文件中写入
extern "C"{
int sum(int a, int b) // sum_int_int .text
{
return a + b;
}
}
C++ 调用 C代码:无法直接调用,怎么办?
把C函数的声明扩在extern "C"里面
//c++文件中写入
extern "C" // 按C的规则生成符号
{
int sum(int a, int b); // sum "UND"
}
int main()
{
int ret = sum(10, 20);
cout << "ret:" << ret << endl;
return 0;
}
5.多态
静态(编译时期)的多态:函数重载
动态(运行时期)的多态:虚函数
04 const用法1.c++的const
必须初始化的,叫常量
叫常变量 因为初始值不是立即数,是一个变量
2.C和C++中const的区别是什么?
const的编译方式不同,C中,const就是当作一个变量来编译生成指令的。
C++中,所有出现const常量名字的地方,都被常量的初始化替换了!!!
3.const怎么理解?
const修饰的变量不能够再作为左值!!!初始化完成后,值不能被修改!!!
int main()
{
int b = 20;
const int a = b; // 已经改了!!!
//int array[a] = {};
int *p = (int*)&a;
*p = 30;
// 20 30 20
printf("%d %d %d n", a, *p, *(&a));
return 0;
}
05 const与一二级指针结合应用
1.const+一级指针
const和一级指针的结合
const修饰的量 叫常量
普通变量的区别是什么?
C++有两点区别:
1.编译方式不同 2.不能作为左值了
const修饰的量常出现的错误是:
1.常量不能再作为左值 《= 直接修改常量的值
int main() {
const int a = 10;
a = 20;//直接修改常量的值
return 0;
}
2.不能把常量的地址泄露给一个普通的指针或者普通的引用变量 《= 可以间接修改常量的值
int main() {
const int a = 10;
int *p = &a;//常量的地址泄露给一个普通的指针或者普通的引用变量==
//应改为 const int *p = &a;
return 0;
}
const和一级指针的结合:有两种情况
C++的语言规范:const修饰的是离它最近的类型
情况1:
const int *p = &a; *p = 20;//不能赋值 p = &b;//可以指向不同类型的内存 //可以任意指向不同的int类型的内存,但是不能通过指针间接修改指向的内存的值
情况2:
int const* p;//等同于 const int* p int *const p = &a; p = &b;//地址不能被修改 *p = 20;//值可以被修改 //这个指针p现在是常量,不能再指向其它内存,但是可以通过指针解引用修改指向的内存的值
情况3:
const int *const p = &a; / return 0; }06 左值引用与右值引用 1.引用和指针的区别?
引用是一种更安全的指针。
1.引用是必须初始化的,指针可以不初始化
2.引用只有一级引用,没有多级引用;指针可以有一级指针,也可以有多级指针
3.定义一个引用变量,和定义一个指针变量,其汇编指令是一模一样的;通过引用
变量修改所引用内存的值,和通过指针解引用修改指针指向的内存的值,其底层
指令也是一模一样的
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
void swap(int &x, int &y)
{
int temp = x;
x = y;
y = temp;
}
int main()
{
int a = 10;
int b = 20;
//swap(&a, &b);
swap(a, b);
cout << "a:" << a << " b:" << b << endl;
//int a = 10;
//int *p = &a;
//int &b = a;
//int &c = 20;
/
const int &d = 20;
return 0;
}
07 const、指针、引用结合
int main()
{
//int a = 10;
//int *p = &a;
//const int *&q = p;
//const int **q = &p; //const int** <= int**
//int a = 10;
//const int *p = &a;
//int *&q = p;
//int **q = &p;
//int** <= const int**
//int a = 10;
//int *const p = &a;
//int *&q = p;
//int **q = &p; // *q =
// 写一句代码,在内存的0x0018ff44处写一个4字节的10
//int *const &p = (int*)0x0018ff44;
//int a = 10;
//int *p = &a;
//const int *&q = p; // typeid(q).name()
// const int* int*
return 0;
}
08 new和delete语法
new和delete
new和malloc的区别是什么?
delete和free的区别是什么?
malloc和free,称作C的库函数
new和delete,称作运算符
new不仅可以做内存开辟,还可以做内存初始化操作
malloc开辟内存失败,是通过返回值和nullptr做比较;
而new开辟内存失败,是通过抛出bad_alloc类型的异常来判断的。
1.new的种类// new有多少种? int *p1 = new int(20); int *p2 = new (nothrow) int; const int *p3 = new const int(40); // 定位new int data = 0; int *p4 = new (&data) int(50); cout << "data:" << data << endl;2.new、delete例子
int main()
{
int *p = (int*)malloc(sizeof(int));
if (p == nullptr)
{
return -1;
}
*p = 20;
free(p);
int *p1 = new int(20);
delete p1;
int *q = (int*)malloc(sizeof(int) * 20);
if (q == nullptr)
{
return -1;
}
free(q);
//int *q1 = new int[20];
int *q1 = new int[20](); // 20个int sizeof(int) * 20
delete[]q1;
return 0;
}



