函数

118 阅读2分钟

返回值和return

return

终止正在执行的函数,并将控制权交给调用这个函数的地方.

值是如何被返回的

有返回值的函数中,最后返回的时候,创建了一个临时变量,然后用返回的值初始化它.(有的编译器可能优化这个过程)

函数重载

函数名相同,形参列表不相同,称为函数重载(overloaded)

匹配优先级

  1. 精确匹配
  2. 常量版本匹配
  3. 变量提升
  4. 算术/指针转换
  5. 类类型转换

常量版本匹配

常量版本不是上层,如const int 和int(这种编译器直接报错),而是指底层const,如const int *int *. 下面的例子中,注释掉第二个函数,则fun(b)调用第一个版本

void fun( const int * a)
{
    cout << 1 << endl ;
}

void fun( int  *a)
{
    cout << 2 <<endl ;
}

int main()
{
    int num = 4;
    const int *a = &num;
    int *b = &num;
    fun(a);  // 1
    fun(b); // 2
    return 0;
}

变量提升

  1. short,unsigned short,char,unsigned char -> int
  2. float->double

类型转换

调用时可能出现二义性导致出错. 如定义单个参数的float和double版本,传入int类型参数,这个时候int是转换为float还是double呢?编译器无法决断\Rightarrow 二义性

函数指针

指向函数地址的指针. 类似下列定义方式:

int (*fun)(int a,int b)

注意*fun两边的()必不可少,否则含义变了,直接变为函数名为fun,返回类型为int*的函数了.

可变个数参数

若实现无法预知传递几个参数, 可采用两种方法处理:

传递initializer_list的标准库类型

这里先不讨论参数类型不一致的问题,先解决参数个数可以传递1,2,3...的问题.

void err_msg(initializer_list<int>x){
    for(auto &t:x){
        cout<<t<<" ";
    }
    cout<<endl;
}

省略符形参

可以全省

#include<iostream>
#include<cstdarg>
using namespace std;

int add_nums(int count,...)
{
    int result = 0;

    va_list args;
    va_start(args, count);
    for(int i=0; i<count; ++i)
        result += va_arg(args, int);
    va_end(args);
    return result;
}

int main()
{
    cout << add_nums(4, 25, 25, 50, 50) << endl;
    return 0;
}