目录
一、函数重载overload
- 查看反汇编
#include <iostream>
using namespace std;
int test(int n)
{
return n;
}
int test(double d)
{
return (int)d;
}
int test(int n, double d)
{
return n + d;
}
int main()
{
int result = test(1);
result = test(2.0);
result = test(1, 2.0);
return 0;
}
二、C++ Name Mangling
- C++函数签名:使用undname工具查看
- ①.打开项目下的.obj文件,我的路径:C:\DevelopProject\TestProject\ConsoleApplication1\ConsoleApplication1\Debug\ConsoleApplication1.obj
- ②.搜索“test”,将内容复制出来
- ③.打开工具路径,我的路径是:C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x86
- ④.使用cmd命令查看:undname XXX
?test@@YAHH@Z
?test@@YAHN@Z
?test@@YAHHN@Z
三、函数指针
- 什么是函数指针:每一个函数都占用一段内存单元,它们有一个起始地址,指向函数入口地址的指针称为函数指针
- 函数指针的一般形式:
数据类型(*指针变量名)(参数表);
——int(*p)(int);
- 返回指针的函数:
int* p(int);
,这个是函数,返回的值是一个指针 - 示例:函数指针
int MaxValue(int x, int y)
{
return (x > y) ? x : y;
}
int MinValue(int x, int y)
{
return (x < y) ? x : y;
}
int Add(int x, int y)
{
return x + y;
}
bool ProcessNum(int x, int y, int(*p)(int a, int b)) // 这个也称为回调函数
{
cout << p(x, y) << endl;
return true;
}
int main()
{
int x = 10, y = 20;
cout << ProcessNum(x, y, MaxValue) << endl;
cout << ProcessNum(x, y, MinValue) << endl;
cout << ProcessNum(x, y, Add) << endl;
return 0;
}
四、命名空间
- 命名空间概念:命名空间这个概念,可作为附加信息来区分不同库中相同名称的函数、类、变量等;命名空间即定义了上下文;本质上命名空间就是定义了一个范围
- 命名空间关键字:using和namespace
//命名空间声明
namespace quickzhao
{
int test(int a);
}
//命名空间定义
namespace quickzhao
{
int test(int a)
{
return a+1;
}
}
//调用
int main()
{
int result;
result = quickzhao::test(1);
return 0;
}
五、内联(inline)函数
- 内联函数概念:如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方
- 引入内联函数的目的:为了解决程序中函数调用的效率问题;注意 —— 内联函数内部不能有太复杂的逻辑,编译器有时会有自己的优化策略,所以内联不一定起作用
#include <iostream>
using namespace std;
inline int MaxValue(int a, int b)
{
return (a > b) ? a : b;
}
int main()
{
int x = 3, y = 4;
MaxValue(x, y);
return 0;
}
六、递归
1 - 递归的基本法则
- 递归的四个基本法则
- 基准情形:无须递归就能解出
- 不断推进:每一次递归调用都必须使用求解状况朝接近基准情形的方向推进
- 设计法则:假设所有的递归调用都能运行
- 合成效益法则(compound interest rule):求解一个问题的同一实例时,切勿才不同的递归调用中做重复性的工作
- 递归实现 —— 斐波那契数列:由递归的四个基本法则来看,使用递归来计算诸如斐波那契数列并不是一个好主意
2 - 递归的缺陷与优化
- 递归是一种重要的编程思想
- 很多重要的算法都包含递归的思想
- 递归最大的缺陷
- 空间上需要开辟大量的栈空间
- 时间上可能需要有大量重复运算
- 递归的三种优化方案
- a)尾递归:所有递归形式的调用都出现在函数的末尾
- b)使用循环替代
- c)使用动态规划,空间换时间
3 - 递归实现—斐波那契数列
- 递归实现—斐波那契数列
#include <iostream>
#include <cassert>
using namespace std;
// 斐波那契数列的实现
// 方法一:递归
int Fib(int n)
{
if (n == 0)
{
return 0;
}
else if (n == 1)
{
return 1;
}
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
int main()
{
assert(Fib(10) == 55);
return 0;
}
- 循环实现—斐波那契数列
#include <iostream>
#include <cassert>
using namespace std;
// 循环
int Fib3(int n)
{
if (n < 2)
{
return n;
}
int n0 = 0, n1 = 1;
int temp;
for (int i = 2; i <= n; i++)
{
temp = n0;
n0 = n1;
n1 = temp + n1;
}
return n1;
}
int main()
{
assert(Fib3(10) == 55);
return 0;
}
- 尾递归实现—斐波那契数列
// 尾递归
int Fib2(int n, int ret0, int ret1)
{
if (n == 0)
{
return ret0;
}
else if (n == 1)
{
return ret1;
}
return Fib2(n - 1, ret1, ret0 + ret1);
}
- 动态规划实现—斐波那契数列
int g_a[1000]; // 全局的数组,记录斐波那契数列的前1000个值
// 动态规划
int Fib4(int n)
{
//assert(n >= 0);
g_a[0] = 0;
g_a[1] = 1;
for (int i = 2; i <= n; i++)
{
if (g_a[i] == 0)
{
g_a[i] = g_a[i - 1] + g_a[i - 2];
}
}
return g_a[n];
}