目录
1.默认参数(C++):让函数调用更加方便
在函数声明里面给一些参数赋值
float norm(float x, float y, float z);
float norm(float x, float y, float z = 0);//,默认参数只能从尾部开始定义
float norm(float x, float y = 0, float z);//上面定义过z,这里可以直接定义y,且默认参数不可重定义,只能设一次
int main()
{
cout << norm(3.0f) << endl;
cout << norm(3.0f, 4.0f) << endl;
cout << norm(3.0f, 4.0f, 5.0f) << endl;
return 0;
}
float norm(float x, float y, float z)//L2范数
{
return sqrt(x * x + y * y + z * z);
}
2.函数重载(C++)
C99对浮点数四舍五入
<math.h>
double round (double x);
float roundf (float x);
long double roundl (long double x);
C++11
<cmath>
double round (double x);
float round (float x);
long double round (long double x);
函数名一样,参数列表不同
C++里面,相同的函数,函数名和参数列表相同,被认为同一个函数,当函数名相同,参数列表不同,被认为不同函数。
但是返回值不计入
3.函数模板
int sum(int x, int y)
{
cout << "sum(int, int) is called" << endl;
return x + y;
}
float sum(float x, float y)
{
cout << "sum(float, float) is called" << endl;
return x + y;
}
double sum(double x, double y)
{
cout << "sum(double, double) is called" << endl;
return x + y;
}
//函数名相同,参数列表和返回值不同
template<typename T>//定义一个泛型T
T sum(T x, T y)
{
cout << "The input type is " << typeid(T).name() << endl;// typeid(T).name()返回一个字符串,输入T的类型是什么
return x + y;
}
//编译器看到这段代码,不会生成真正可执行代码,他不知道加法操作怎么做(类型不知道)
//显式实例化
// instantiates sum<double>(double, double)
template double sum<double>(double, double);//定义完模板,告诉编译器类型
// instantiates sum<char>(char, char), template argument deduced
template char sum<>(char, char); 可简化
// instantiates sum<int>(int, int), template argument deduced
template int sum(int, int); 简化
//
template<typename T>
T product(T x, T y)
{
cout << "The input type is " << typeid(T).name() << endl;
return x * y;
}
// Implicitly instantiates product<int>(int, int)
cout << "product = " << product<int>(2.2f, 3.0f) << endl;//猜测是int
// Implicitly instantiates product<float>(float, float)
cout << "product = " << product(2.2f, 3.0f) << endl;
4.模板特例化
如果是一个结构体类型的上面的函数模板不知道怎么运算
struct Point
{
int x;
int y;
};
template<>//<>表示特例化
Point sum<Point>(Point pt1, Point pt2)
{
cout << "The input type is " << typeid(pt1).name() << endl;
Point pt;
pt.x = pt1.x + pt2.x;
pt.y = pt1.y + pt2.y;
return pt;
}
5.函数指针
指向指令区地址
float norm_l1(float x, float y);
float norm_l2(float x, float y);
float (*norm_ptr)(float x, float y);
float (*norm_ptr)函数变量是一个指针,指针的名字叫norm_ptr,指向函数的指针,指向的函数要求,指向的函数类型和指针完全匹配,指向的函数有两个参数,都是float,返回值也是float
norm_ptr = norm_l1; //Pointer norm_ptr is pointing to norm_l1
norm_ptr = &norm_l2; //Pointer norm_ptr is pointing to norm_l2
float len1 = norm_ptr(-3.0f, 4.0f); //function invoked
float len2 = (*norm_ptr)(-3.0f, 4.0f); //function invoked上下等价
作用:回调函数(函数指针的调用,即是一个通过函数指针调用的函数)
<stdlib.h>
//快速排序(数组)
//对一下类型排序困难
struct Point
struct Person
void qsort( void *ptr, size_t count, size_t size,
int (*comp)(const void *, const void *) );
int (*comp)(const void *, const void *)//外面自己写的函数用于比较
6.函数引用
float norm_l1(float x, float y); //declaration
float norm_l2(float x, float y); //declaration
float (&norm_ref)(float x, float y) = norm_l1; //norm_ref is a function reference必须初始化
7.递归函数(难):自己调自己
int main()
{
div2(1024.); // call the recursive function
return 0;
}
void div2(double val)
{
cout << "Entering val = " << val << endl;
if (val > 1.0)//停止条件
div2( val / 2); // function calls itself
else
cout << "--------------------------" << endl;
cout << "Leaving val = " << val << endl;
}
优点:
I)算法:对数的遍历,数的操作,用很少的代码写很复杂的代码
缺点:
i)不小心写错容易爆栈
ii)会消耗更多的栈的内存
iii)可能慢
iiii)困难debug