第六章 函数
函数基础
形参和实参:实参是形参的初始值
实参是函数调用时的传入值
形参声明在函数名字后的括号中
每个形参都是一个含有声明符的声明(即使类型一样也必须写出类型)
形参名是可选的,但是我们无法使用未命名的形参
实参应当与形参一一对应(数量和类型)
参数传值
引用传递:引用形参是对应实参的别名
使用引用传参可以避免拷贝
函数只能返回一个值,但是可以利用引用形参间接返回值
但是对于不希望被修改的引用形参,尽量定义为常量
传值形参:修改形参不会影响实参(对象)的值
- 注意指针形参,修改形参本身不会影响实参(指针对象),但是通过解地址符修改指针指向的对象是有效的
const形参
main处理命令行选项
- argc表示参数个数
含有可变形参的函数(形参数量不固定)
如果形参数量未知,但类型统一,可以使用initializer_list
- 传入的实参需要用花括号包起来
省略符形参:该策略继承于C语言,因此那些可变形参的类型应该为C语言中也有的基本类型
https://www.runoob.com/cprogramming/c-variable-arguments.html
返回类型于return语句
返回类型可以是指针和引用,但是不能是函数内局部变量的指针(函数结束后会被释放)
- 返回类型为引用,则返回结果为左值
如何返回值
返回值为数组时,因为数组不能被拷贝,所以应当返回数组的指针或引用
返回数组名,作为数组的地址进行返回,如对一维数组则返回int*
利用using或typedef对数组进行重命名后作为函数返回类型
使用decltype,起到类似重命名的效果,如decltype(arr) *func(int sz)或decltype(arr) &func(int sz)
显式返回数组指针或引用,如int (*func(int sz))[]或int (&func(int sz))[10]
使用尾置返回类型(C++11),如auto func(int sz) → int *
函数重载(overload)
虽然函数名相同,但是形参列表有明显的区别(形参名和顶层const不纳入区别的考量)
- 但是底层const可以作为区分
函数匹配,即重载确定时,编译器会找到一个与实参最佳匹配的函数
- 都不匹配或者多个匹配但没有最佳匹配时,都会报错
重载与作用域:局部函数(甚至变量)不会重载外部函数,而是会导致外部(全局)函数被隐藏
特殊用途语言特性
默认实参:有默认值的形参必须定义在没有默认值的形参之后
- 但是默认实参可以分开声明
- 形参默认值不一定是字面值
inline(内联)函数,可以更高效,一般用于目的明确的小函数
- 但编译器不一定支持内联,即忽略inline关键词
constexpr函数,返回值不一定是常量,也可能和形参有关,但是实参必须是constexpr
inline函数和constexpr函数最好定义在头文件中,若不在头文件中定义,则需要(在用到该函数的地方)进行多次相同的定义
调试帮助:assert预处理宏,用于检查不能发生的情况
assert宏依赖于一个名为NDEBUG的预处理变量,可以#define NDEBUG来关闭assert检查
编译器还定义了一些很有用的预处理变量名
__func__
:当前调试的函数__FILE__
:文件名__LINE__
:当前行号__TIME__
:编译时间__DATE__
:编译日期
函数匹配
- 候选函数:同名,可见
- 可行函数:实参数量符合要求,实参类型匹配或可以转换
- 最佳匹配:有且仅有一条可行函数满足如下要求,否则就会发生二义性错误
- 其中实参到形参的转换分为多个等级
- 应该尽量避免使用这种形参类型相似的函数重载,浮点数尽量用double,整型尽量用int(与字面值的默认类型对应)
函数指针
函数指针指向某种特定类型的函数,类型由函数的返回类型和形参类型相关,与函数名无关
- 函数名与函数指针等价,使用时无需使用取址符和解地址符
对于重载函数的指针,必须是指针类型和函数类型的精确匹配(比最佳匹配更严格,即完美匹配)
函数指针形参
- 使用typedef,using和decltype可以简化函数的声明
- 同理函数返回值也可以是函数指针,但此时需要显式地指明返回类型为指针
- 但是这种写法的可读性很差,建议重命名函数类型(using,typedef)或decltype或使用auto的后缀声明形式
- Title: 第六章 函数
- Author: Huan Lee
- Created at : 2023-08-20 13:06:02
- Updated at : 2024-02-26 04:53:15
- Link: https://www.mirthfullee.com/2023/08/20/notion-第六章 函数-d4dc9909/
- License: This work is licensed under CC BY-NC-SA 4.0.