C++基础笔记7
函数
基本概念
1 | /*返回类型 函数名(参数列表){ |
返回类型
返回类型代表函数运算后返回的结果类型
函数名
函数的标识符
参数列表
调用函数时需要的数据以及类型
函数体
在函数内部通过传入的数据来得出结果的计算过程
在调用函数时输入的参数称为实际参数(即实参),函数定义时的参数成为形式参数(即形参)
关键字==return
==作用:
- 返回值
- 结束函数
函数类型为void
时没有返回值,代表空,正常执行时不需要return
参数的引用
1 | void swap(int &x, int &y){ |
若不加&符号,不会对实参进行改变.因此只有加上引用符号后才能对传递进来的实参进行修改
特殊类型
对于vector
,string
这类复合数据类型,如果按数值来传递,相当于新建了一个同样大小的数据,同时将形参的数据赋值给函数的形参,性能低效
因此尽可能用引用来传递非基础类型(因为指向同一个内存并不会发生数据的拷贝)
同样如果传递数组不带引用符号的话,数组会发生隐式转换变成指针类型
(typeid
函数可获取数据类型)
1 | void forward(auto &arr);//使用auto是比较危险的行为但可做题小范围使用 |
main
函数
Lambda 函数
Lambda 函数(也称为匿名函数或 lambda 表达式)是 C++11 及以后版本中引入的一种方便的语法结构,它允许你在不定义传统函数的情况下创建函数对象。Lambda 函数通常用于简短的、一次性的函数,或者作为参数传递给算法,如 std::sort
、std::for_each
等。
Lambda 函数的基本语法如下:
1 | [capture](parameters) -> return_type { function_body } |
其中各个部分的含义如下:
- 捕获子句(capture clause)
[capture]
:- 指定了 lambda 函数从封闭作用域(通常是包含它的函数)中捕获哪些变量。
- 可以捕获变量的值
[=]
或引用[&]
,也可以通过名称[a, &b]
指定特定的变量捕获。 - 如果不需要捕获任何变量,可以省略捕获子句。
- 参数列表(parameter list)
(parameters)
:- 指定了 lambda 函数的参数,类似于传统函数的参数列表。
- 如果没有参数,可以省略参数列表,或者使用空括号
()
。
- 返回类型(return type)
-> return_type
:- 指定了 lambda 函数的返回类型。
- 如果 lambda 函数的返回类型可以由编译器推断,可以省略返回类型。
- 函数体(function body)
{ function_body }
:- 包含了 lambda 函数的执行代码,类似于传统函数的函数体。
以下是一些 lambda 函数的例子:
例子 1:无参数,无返回值
1 | []() { std::cout << "Hello, World!" << std::endl; }; |
例子 2:有参数,无返回值
1 | [](int x, int y) { std::cout << "Sum: " << x + y << std::endl; }; |
例子 3:有参数,有返回值
1 | [](int x, int y) -> int { return x + y; }; |
例子 4:捕获外部变量
1 | int a = 10; |
例子 5:捕获外部变量并修改
1 | int a = 10; |
Lambda 函数可以被存储在变量中,作为参数传递给函数,或者直接在需要的地方使用。它们是现代 C++ 编程中非常灵活和强大的工具。
匿名函数
sort
void sort(Iterator first, Iterator last, Function comparer);
1 | bool comparer(int a, int b){ |
find_if
作用:查找范围内第一个满足条件的元素
返回值为迭代器或者地址
Iterator find_if(Iterator first, Iterator last, Function matcher);
1 | bool matcher(int x) { |
[]
的意义是捕获,代表捕获一些变量使得可以在函数内正常访问
[]
捕获
1 | int x, y ,z; |
判断依据:
- 如果想在函数内改变变量 使用引用捕获
- vector string 等建议使用引用捕获
==mutable
==可改变的,加上mutable关键字之后可以改变捕获的值(只在函数内部生效,和引用捕获不同) 加在括号和花括号之间
1 | auto swap = [](int &a, int &b) { };//花括号内写函数具体内容 |
匿名函数的递归调用
1 | auto fib = [](auto& self, int x) { |
递归
基础概念
递归,即调用函数自身。本质上是将问题拆解成更小规模的相同问题。
简单优化思路(==记忆化搜索==):如果有重复计算,将结果保存下来
递归方法:
- 确定问题
- 解决基准问题
- 拆解问题
示例
斐波那契数列(Fibonacci)
1 | int fib(int n){ |
当出现重复问题时数据会成指数型增长,子问题会被重复计算多次.
可以在计算时将计算过的保存下来,并在计算时再判断是否计算过,用来优化性能
1 | vector<int> saved(n,-1); |
汉诺塔(honai)
1 | void hanoi(int n, char F, char A, char T){ |