第六章-函数基础

函数相关

函数基础

  • 形参与实参
    实参类型要与形参类型匹配
    实参可以发生隐式转换
    引用传递和值传递

  • 函数的返回类型
    函数的返回类型不能是数组或函数,但可以返回指向数组或函数的指针

  • 局部静态对象
    定义在函数内部的局部静态对象,函数执行结束也不会销毁

    int test()
    {
        static int i = 10; //调用结束后依然有效
        return i++;
    }
    
    int main()
    {
        for (int i = 0; i < 10; i++)
        {
            cout << test() << endl; //由于静态对象一直有效,结果为 11-19
        }
        return 0;
    }
    

传参

  • 传引用参数

    1. 可以避免拷贝

    2. 利用引用传递返回额外信息

    3. const 形参
      由于传参的时候会忽略顶层 const,所以函数重载可能会受到影响
      形参尽量使用常量引用
      常见错误

      func(string &s);//非常量引用无法接收字面值,除非加const
      func("hello");
      
  • 数组形参
    数组两个特性:不允许拷贝数组;使用数组时会转换为首元素的指针
    实参会自动转换为指向数组首元素的指针,形参定义为底层 const 指针

    void print(const int *);
    void print(const int[]);
    void print(const int[10]);//10并不是真实维度,相当于注释
    

    由于数组是以指针形式传递给函数的,所以不知道数组的维度,必须由调用者提供额外信息
    解决方法:

    1. 使用标记指定数组长度
      C 风格的字符串(字符数组),空字符结尾
    2. 使用标准库规范
      传递指向数组首元素和尾后元素的指针(迭代器的做法)
    3. 显式传递一个表示数组大小的形参
  • 数组引用形参
    数组虽然不能拷贝,但是可以传递引用,f(int (&arr)[10])

  • 多维数组传参
    形参传递指向数组的指针,f(int (*arr)[10])

返回

  • 值返回细节

    1. 返回的值用于初始化调用点的临时量
    2. 不要返回局部对象的引用或指针
    3. 引用返回可以成为左值,返回非常量引用的函数可以进行赋值操作
  • 返回数组指针
    由于数组不能拷贝,所以函数不能返回数组

    1. 定义返回数组指针的函数
      int (*f(int i))[10]

      (*f(int i))表示函数返回指针

      int [10]表示函数返回的指针指向含有10整型对象的数组

    2. 尾置返回类型
      auto func(int i) -> int(*)[10]

重载

  • 重载与 const 形参
    拥有顶层的 const 形参无法与没有顶层const的形参区分,因此不能作为重载条件

    void test(int i);
    void test(const int i);//重复声明
    

    引用或指针的底层const可以作为重载条件

    int j = 0;
    void test(int &i)
    {
      cout << "int i" << endl;
    }
    void test(const int &i)
    {
      cout << "const int i" << endl;
    }
    test(j);//j是非常量,非常量可以初始化常量,因此两个版本都能调用,但优先调用非常量引用版本
    
  • 重载与作用域
    一旦在内层作用域声明函数,它将隐藏外层作用域所有版本的函数

    通常来说,在内层作用域声明函数是不好的习惯

  • 函数匹配

    1. 候选函数
      与被调用的函数同名;
      声明在调用点可见
    2. 可行函数
      形参数量与本次调用的实参数量相同;
      形参与实参的类型相同,或者实参可以转换为形参的类型
    3. 最佳匹配
      精确匹配比类型转换匹配更好
      有且仅有一个最佳匹配,否则编译器因为二义性二拒绝请求
  • 函数指针
    函数的类型:由其返回类型和其形参类型共同决定
    举个例子:

    函数定义,int func(int value)
    函数类型,int (int value)
    函数指针,int (*p)(int value),p 函数指针未初始化,只是定义了一个返回类型为int,形参为一个int类型参数的函数指针
    当函数作为一个值使用时,该函数自动转换成指针p = func;等价于p = &func;
    使用函数指针调用时可以不解引用,p(1)等价于(*p)(1)

    int func(int value)
    {
        return value;
    }
    
    int main()
    {
        int (*p)(int) = func;//定义一个函数指针并赋值为func
        cout << func(1) << endl;
        return 0;
    }
    
  • 函数指针形参

    1. 形参可以是指向函数的指针,传递函数类型时,会自动转换成函数的指针
      void test(int func(int value))等价于void test(int (*p)(int value))
    2. 实参可以直接传递函数名,它会自动转换为指针
      test(func)
  • 返回函数指针
    int (*f1(int))(int *, int);
    f1(int) 是函数类型
    *f1(int) 表示返回指针
    *f1 还包含后面的参数列表,说明返回的指针指向函数类型,类型为int (int *, int)

特殊语言特性

  • 默认实参
    默认实参作为形参的初始值
    一旦某个形参被赋予了默认值,则它之后的所有形参都必须有默认值
    函数调用时,只能省略尾部实参,因此要合理设计形参的顺序

  • 内联函数
    关键字:inline
    作用:编译器将小函数在调用点展开,达到优化的效果

    但最终取决于编译器的处理,inline关键字只是给编译器一个建议

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值