目录
函数与结构体:
#include <iostream>
#include <string.h>
using namespace std;
#define MAX 64 // 数组最大长度
typedef struct INFO
{
char name[MAX];
int age;
public:
INFO() // 结构体默认构造函数
{
//char* temp = "hefei"; // invaild "hefei" -> const char* temp -> char*
//name = "hefei"; // invaild "hefei" -> const char* name -> 字符数组
//string str_name = "hefei"; // vaild "hefei" -> const char* string -> C++类(运算符重载) !!反过来不行
strcpy_s(name, MAX, "hefei"); // 第二个参数写成 (strlen("hefei") + 1) 也可以,但记住加一,因为 C 的字符串有一个 '\0'结束符
age = 21;
}
}_Info;
_Info update()
{
_Info temp;
strcpy_s(temp.name, MAX, "coliy");
temp.age += 1;
return temp;
}
int main()
{
INFO info = update();
cout << "info.name = " << info.name << endl;//coliy
cout << "info.name = " << info.age << endl; //22
return 0;
}
函数与string:
#include <iostream>
using namespace std;
void display(string* arr)
{
for (int i = 0; i < arr->size(); ++i)
cout << arr[i] << endl;
}
int main()
{
string arr[2] =
{
"hefei",
"coliy"
};
display(arr);
return 0;
}
函数与array对象:
#include <iostream>
#include <array> // 包含头文件
using namespace std;
void update(array<string, 2>* _arr)
{
_arr->at(0) = "hefei"; // 相对于 (*_arr)[0]
_arr->at(1) = "coliy"; // 相对于 (*_arr)[1]
}
int main()
{
array<string, 2> arr1 =
{
"name1",
"name2"
};
//array<string, 2> arr2 = arr1; // 模板类赋值是 -> 深拷贝
//arr2[1] = "coliy";
//cout << arr1[1]; // name1
update(&arr1);
for (int i = 0; i < arr1.size(); ++i)
cout << arr1[i] << endl; // arr1[0] = hefei // arr11] = coliy
return 0;
}
递归函数:
注意:使用递归一定要确定结束条件,否则就是一个死循环
递归结束退出:退到调用它的函数的下一条语句,一次类推
CODE:
#include <iostream>
using namespace std;
void find(int _year)
{
cout << "find wife" << endl;
if (_year == 2025)
{
cout << _year <<"find it" << endl;
return;
}
find(++_year);
cout << "not find wife" << endl;
}
int main()
{
int year = 2022;
find(year);
return 0;
}
函数指针:
函数也有地址,存储在代码区; 一个指向函数的指针
CODE:
#include <iostream>
using namespace std;
// 圆的面积
double area(int _radius)
{
return 3.14 * _radius * _radius;
}
// 圆的周长
double perimeter(int _radius)
{
return 2 * 3.14 * _radius;
}
// 计算
void count(int _radius, double (*pf)(int))
{
cout << (*pf)(_radius) << endl; // vaild
//cout << pf(_radius) << endl; // vaild
}
int main()
{
/*************************************************************************
* double (*pf)(int)
* double: 返回类型 (返回类型必须与指向的函数的返回类型相同)
* pf: 函数指针
* int: 参数列表 (参数列表必须与指向函数的参数列表一致)
* 注意: 声明时必须将括号将 *fun 括起来 (运算符优先级)
* 如果写成: double* fun(int) -> 意味着 fun() 是一个返回指向double类型的指针
*************************************************************************/
count(3, area); //面积 -> 28.26
count(3, perimeter);//周长 -> 18.84
return 0;
}
函数指针数组:
#include <iostream>
using namespace std;
// 圆的面积
double* area(int _radius, double* _size)
{
*_size = 3.14 * _radius * _radius;
return _size;
}
// 圆的周长
double* perimeter(int _radius, double* _size)
{
*_size = 2 * 3.14 * _radius;
return _size;
}
int main()
{
/*************************************************************************
* double* (*pa[2])(int, double*)
* double*: 返回类型 (返回类型必须与指向的函数的返回类型相同)
* pa: 是一个数组
* int, double* 参数列表 (参数列表必须与指向函数的参数列表一致)
* 拆分理解 一: 运算符优先级规则, pa 先与 [2] 结合, 所以 pa代表一个数组
* 二: 数组 pa 再与 * 结合, 代表指针数组, 指向数组的第一个元素
*************************************************************************/
double* (*pa[2])(int, double*) =
{
area,
perimeter
};
double size = 0;
cout << *pa[0](3, &size) << endl; //28.26
cout << *pa[1](3, &size) << endl; //18.84
return 0;
}
typedef简单用法:
#include <iostream>
using namespace std;
typedef double* (*pa)(int, double*);
// 圆的面积
double* area(int _radius, double* _size)
{
*_size = 3.14 * _radius * _radius;
return _size;
}
// 圆的周长
double* perimeter(int _radius, double* _size)
{
*_size = 2 * 3.14 * _radius;
return _size;
}
void test(int (*a)[2])
{
cout << *(*(a)) << endl; // 10
cout << *(*(a + 1)) << endl; // 30
cout << *((*a + 3)) << endl; // 40
}
int main()
{
/*************************************************************************
* double* (*pa[2])(int, double*)
* double*: 返回类型 (返回类型必须与指向的函数的返回类型相同)
* pa: 是一个数组
* int, double* 参数列表 (参数列表必须与指向函数的参数列表一致)
* 拆分理解 一: 运算符优先级规则, pa 先与 [2] 结合, 所以 pa代表一个数组
* 二: 数组 pa 再与 * 结合, 代表指针数组, 指向数组的第一个元素
*************************************************************************/
int a[2][2] = { {10, 20},{30, 40}};
test(a);
pa p[2] = { area, perimeter};
double size = 0;
cout << *p[0](3, &size) << endl; //28.26
cout << *p[1](3, &size) << endl; //18.84
return 0;
}
内联函数(inline):
(一)、函数调用是有时间和空间开销的。程序在执行一个函数之前需要做一些准备工作,要将实参、局部变量、返回地址以及若干寄存器都压入栈中,然后才能执行函数体中的代码;函数体中的代码执行完毕后还要清理现场,将之前压入栈中的数据都出栈,才能接着执行函数调用位置以后的代码。
(二)、如果函数体代码比较多,需要较长的执行时间,那么函数调用机制占用的时间可以忽略;如果函数只有一两条语句,那么大部分的时间都会花费在函数调用机制上,这种时间开销就就不容忽视。
解决方案:函数调用处直接嵌入函数体的函数称为内联函数,,即在编译时将函数调用处用函数体替换
使用场景: 短小、频繁调用的函数可以声明为内联函数
不宜场景: 如果函数体内代码比较长,使用内联将导致可执行代码膨胀过大。
如果函数体内出现循环或者其他复杂的控制结构,那么执行函数体内代码的时间将比函数调用的开销大得多。
#include <iostream>
using namespace std;
#define sum(X) X * X; //宏代替只是简单的代替
inline int add(int a, int b) //注意, 在函数定义前添加inline关键字, 在声明添加无效
{
return a + b;
}
int main(void)
{
int a = 5, b = 5;
int c = sum(5 + 5); // a + b * b + a
cout << c << endl; // 35
int value = sum(a, b); // 10
cout << value << endl;
return cin.get();
}
函数的默认参数:
(一)、参数的值也可以是表达式
(二)、如果某个参数是表达式,那么它后面的参数必须都是默认参数
(三)、默认参数可以放在函数声明或者定义中,但只能放在两者之一(一般放在函数声明)
(四)、函数重载时谨慎使用默认参数值
#include <iostream>
using namespace std;
/*函数重载的时候谨慎使用, 有多个匹配的选项, 编译器不知道调用哪一个, 所以报错*/
//void test(int a)
//{
// cout << "Hello World" << endl;
//}
int fun()
{
return 1;
}
void test(int a, int b = 500, int c = fun())
{
cout << "b" << b << endl;
cout << "c" << c << endl;
}
int main(void)
{
int a = 5;
int b = 50;
test(a);
return cin.get();
}
函数重载:
- 函数名称必须相同。
- 参数列表必须不同(个数不同、类型不同、参数排列顺序不同等必须有一个不同)。
- 函数的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不足以成为函数的重载。
- 作用: 减少了函数名的数量,避免了名字空间的污染
#include<Windows.h>
#include<iostream>
using namespace std;
// 仅返回类型不行,参数列表必须有一个不同
//void Add(int a, int b)
//{
// return a + b;
//}
int Add(int a, int b)
{
return a + b;
}
double Add(double a, double b)
{
return a + b;
}
float Add(float a, float b)
{
return a + b;
}
int main()
{
cout << Add(1, 2) << endl;
cout << Add(3.5, 4.5) << endl;
cout << Add(2.22, 3.33) << endl;
return 0;
}
函数模板
函数模板的写法如下:
template <typename 类型参数1, typename 类型参数2, ...> // typename 也可以写成 class
返回值类型 模板名(形参表)
{
函数体
}
简单用法:
编译器由模板自动生成函数的过程叫模板的实例化。由模板实例化而得到的函数称为模板函数。
模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。
可以去参考这博客,函数模板,没有写类模板:
https://blog.csdn.net/weixin_45738899/article/details/120687055
using namespace std;
template<typename T1, typename T2>
T2 Swap(T1& x, T2& y)
{
cout << x << " " << y << endl;
return x + y;
}
int main()
{
int n = 1;
double m = 2.5;
cout << Swap(n, m) << endl; //3.5
return cin.get();
}
总结: 对着我的目录去找别人写的博客, 他们写的更细