/
...
/
/
五. 函数
Search
Try Notion
五. 函数
一.函数格式
函数定义:提供了函数的编译代码
函数头
函数体
函数原型:使得编译器知道函数的返回值和参数列表,有两种方法为文件提供原型
源文件中手动输入
头文件包含
可变参数原型需要明示如void function(...) ANSI C中可变参数的原型可以写成void funtion()void参数一样
作用:告诉参数列表,告诉返回值(接口)
也只需要函数接口信息—-故可以省略参数名称
void function(int , double) 合法
🤔:为何不从函数定义中获取这些信息
效率不高:搜索时暂停编译
可能位于其他文件中:编译时可能无权访问,在链接的时候才能凑出完整程序
函数默认值
通过原型告诉,而非定义
若要为某个形参指定默认值,其右边形参也必须指定
传递参数时,实参要从左到右依次键入,不可中间跳跃,有默认值的可省略
编译指令using
二.参数传递
xing
形参列表:/-简单变量/-数组形参/-指针形参/-结构形参
简单变量
按值传递,强制转换
流程:先新建一个自动变量—-拷贝值—-退出函数后销毁
数组
传递的是指针而非数组名
int a[3] = {1, 2, 3} ; void fun1 (int b[]) { b[1] == 1 ; //可以像正常数组使用 sizeof(b) == 4 ; //sizeof结果是指针的大小为4 而非sizeof(a) == 12 }
Copy
C++
const int a[] 等价于 const int *a
结构体
按值传递
由于类对象基于结构体,故模板类(vector array)也是按值传递,string类也是
const返回比较
常规
引用
在cout示例中,返回自身可以写出串联表达式
const 引用
减少开销,如果有引用传入,此项最佳,常规按值返回的的量也为不可修改的值
但是不能返回临时变量(会被销毁)
const 常规
为避免写出epr1 + epr2 = var1
epr1+epr2会返回的临时对象,理应不可修改,故加const
函数指针
|-简单函数指针-|-函数指针数组-|
//简单定义初始化 int fun1( int a ) {...} ; int (*pf1)(int) = fun1 //简单声明加初始化 //区别函数调用和函数地址 函数调用为fun1(...) //指针调用 pf1(4) ; //或 (*pf)(4) ;
Copy
C++
简单声明调用:如上
函数指针(指针返回值)—-函数指针数组:如下
//先定义一个指针返回函数 double *fun2 (double a, double b) {...} ; //则对应函数指针 double *(*pf2) (double, double) = fun2; //将标识符替换成(*pf2)即可 //函数指针数组 double *(*pf2[3]) (double, double) = fun2; //[3]先结合说明是数组,其余部分说明类型 //还可新建指向函数指针数组的指针 auto pf3 = & pf2 //或者手写 //同样将标识符替换 double *(*(*pf3)[3]) (double, double) = & pf2 ;
Copy
C++
内联
无跨文件访问,只能单一文件访问(每个文件都必须定义)
所以一般放置于头文件中
在原来原型声明的地方完成定义(类似小函数的写法)
三.函数重载
根据函数的特征标(形参)进行重载
不区分const和非const 不区分引用和原始
返回值可以不同,但特征标也必须不同
重载解析过程
创建候选列表—-同名的函数或模板及其重载
创建可行参数列表—-完全匹配>提升匹配(int→long)>标准匹配(int→char/long→double)
确定是否有可行函数
对于完全匹配也可有某些无关紧要的匹配
无关紧要匹配列表
实参—|—形参 Type <--> Type & Type --> const Type Type --> volatile Type Type[] --> Type *
Copy
C++
若完全匹配,则非模板>模板
若完全匹配均为模板函数,则较为具体的优先(显式具体>隐式实例)
多参数则跟脚麻烦此处不赘述
decltype
//例一 int x ; decltype( x ) ; //为int //例二 int a ; decltype( (a) ) ; //为int&
Copy
C++
语法decltype( expression )
若为无括号标识符则和标识符类型相同
若为函数调用,则和返回值相同
左值,则为其引用—→带括号标识符,则为引用
前面都不满足,则为expression的类型
模板函数是占位声明
由于模板,可能存在无法判断返回值的类型
可用auto占位,后置类型声明
template<typename Type1, typename Type2> auto fun1 (Type1 var1,Type2 var2) -> decltype(var1+var2) { ... }
Copy
C++
四.函数模板
简单模板的定义声明调用
template <typename AnyType> void Swap( AnyType &a, AnyType &b ) //原型 int main() { int i = 1 , j = 2 ; Swap(i,j) ; //隐式实例化 } template <typename AnyType> void Swap( AnyType &a, AnyType &b ) //定义 { AnyType temp ; temp = a ; a = b ; b = temp ; return ; }
Copy
C++
重载模板函数
可以混用未定义类和已知类,仍然通过特征标区别
template <typename AnyType> void Swap(AnyType &a, AnyType &b, int n){...};
Copy
C++
显示具体化—-显示实例化
//具体化(重写模板) template <> void Swap (int &a, int &b) ; //原型 //或---<job>可选 template <> void Swap<job> (int &a, int &b) ; //原型 //实例化(区别隐式实例化) template void Swap<job> (int &a, int &b) ; //原型
Copy
C++