【C++学习】基础知识:函数

【C++学习】基础知识:函数,第1张

C++函数

【C++学习】以w3cschool的教程为框架,记录总结C++Primer第五版的学习内容。

定义函数
return_type function_name( parameter list )
{
    body of the function
}
  • 自动对象(automatic object):只存在于块执行期间的对象,形参是自动对象。

  • 局部静态对象(local static object):在第一次执行经过对象定义前进行了初始化,函数结束时不会被销毁,在程序终止时被销毁,通过将局部变量定义为 static 来获得此类对象。

函数声明
  • 函数声明会告诉编译器函数名称及如何调用函数,函数的实际主体可以单独定义;

    return_type function_name( parameter list );
    
    • 函数只能定义一次,但可以声明多次;
    • 建议在头文件中声明,在源文件中定义,含有函数声明的的头文件应该被包含到定义函数的源文件中;
参数传递
  • **传值参数:**将实参的值拷贝给形参;

    • 指针形参:执行指针拷贝 *** 作时,拷贝的是指针的值,拷贝后两个指针是不同的指针;
    • 建议使用引用类型的形参代替指针,这样就不需要return。
  • 传引用参数:将形参绑定到对应的实参上;

    • 使用引用避免拷贝,如果函数无需改变引用形参的值,建议将其声明为常量引用。
    • 使用引用形参返回额外信息,引用参数为函数返回多个结果提供了有效途径。
  • const形参和实参:

    • 尽量使用常量引用;

    • 当用实参初始化形参时会忽略掉顶层const,即当形参有顶层const时,传给形参常量对象或非常量对象都可以;

    • 可以使用非常量初始化一个底层const对象,反之则不行。

  • 数组形参:

    • 不允许拷贝数组,所以无法以值传递的方式使用数组形参;
    • 使用数组时通常会被转换成指针,所以当向函数传递一个数组时,实际上传递的是指向数组第一个元素的指针。
返回类型和return语句
  • 返回值用于在调用点上初始化一个临时变量,该临时变量是函数调用的结果;

  • 不要返回局部对象的引用或指针;

  • 调用一个返回引用的函数得到的是左值,其他返回类型得到右值;

  • 主函数 main 的返回值

    • 如果函数的返回类型不是 void,那么它必须返回一个值,(例外:main 函数允许没有 return 语句直接结束);

    • 如果控制到达 main 函数的结尾处而没有 return 语句,编译器隐式插入 return 0;

    • main 函数不能调用它自己。

  • 因为数组不能被拷贝,所以函数不能返回数组,但可以返回数组的指针或引用;

  • 使用尾置返回类型:这种方式对于具有复杂返回类型的函数最有用,比如指向数组的指针或引用;

    auto func(int i) -> int(*)[10];//该函数返回一个指针,指向含有十个整数的数组
    
  • 使用 decltype: decltype 不会自动将数组转换为其相应的指针类型,其返回类型是数组,必须添加 * 以表明 arrPtr 返回一个指针。

函数重载
  • 重载(overloaded):在同一作用域内,函数有相同的名字,但有不同的形参列表,main 函数不能重载。

  • 重载和 const 形参

    • 顶层 const 不影响传入函数的对象,一个有顶层 const 的形参无法与没有顶层 const 的形参区分;

    • 如果形参是某种类型的指针或引用,则可以通过底层const 区分是否重载;

    • const 不能转换为非const,但非const 能转换为 const。

特殊用途语言特性
  • 可以为一个或多个形参定义默认值,但如果一个形参具有默认实参,则其后的所有形参也必须具有默认实参。

  • 内联函数:inline 函数避免函数调用的开销,通常旨在优化规模较小、流程直接、调用频繁的函数;

  • constexpr函数:可用于常量表达式的函数,return 类型和每个形参的类型必须是字面值类型,且函数主体必须有且只有一条 return 语句;

  • inline 函数和 constexpr 函数通常定义在头文件中。

函数匹配
  • 确定候选函数和可行函数,如果有可行函数,找到最佳匹配;

  • 实参类型转换:为了确定最佳匹配,编译器对每个实参类型到其对应形参类型的转换进行排名;

    1. 精确匹配,包括:
      实参类型和形参类型相同。
      实参从数组类型或函数类型转换成对应的指针类型。
      向实参添加顶层 const 或从实参中删除顶层 const。

    2. 通过 const 转换实现的匹配。

    3. 通过类型提升实现的匹配。

      • 小整型总是提升到 int 类型或更大的整数类型;
      void ff(int);
      void ff(short);
      ff('a');   // char promotes to int; calls f(int) 
      
    4. 通过算术类型转换或指针转换实现的匹配。

      • 所有算数类型转换的级别都一样。
    5. 通过类类型转换实现的匹配。

函数指针
  • 函数指针指向的是函数而不是对象:

    // pf 指向一个函数,该函数的参数是两个const类型的引用,返回值是bool类型
    //该函数的类型是 bool(const string&, const string&)。声明指向函数的指针,用指针替换函数名:
    bool (*pf)(const string &, const string &);  // 未初始化
    
  • 使用函数指针

    • 当使用函数名作为一个值时,函数自动转换为指针:

      cpf = lengthCompare;  // pf指向名为lengthCompare的函数
      pf = &lengthCompare; // 等价的赋值语句,取地址符是可选的
      
    • 可以直接使用指向函数的指针调用该函数,无需解引用指针:

    bool b1 = pf("hello", "goodbye");    // 调用lengthCompare 函数
    bool b2 = (*pf)("hello", "goodbye"); // 等价调用
    bool b3 = lengthCompare("hello", "goodbye"); // 等价调用
    
    • 在指向不同函数类型的指针之间不存在转换;

    • 指向重载函数的指针

      void ff(int*); 
      void ff(unsigned int); 
      void (*pf1)(unsigned int) = ff;  // pf1 指向 ff(unsigned)
      

      编译器使用指针类型确定使用的是哪个重载函数。指针类型必须与重载函数中的某一个精确匹配:

      void (*pf2)(int) = ff;    // error: 没有任何一个ff与该形参列表匹配
      double (*pf3)(int*) = ff; // error: 返回类型不匹配
      
    • 函数指针形参:不能定义函数类型形参,但形参可以是指向函数的指针,当传入函数作为实参时,它将自动转换为指针。

      • decltype 返回函数类型,不会自动转换成指针。要想返回指针,必须加上 *
    • 返回指向函数的指针:

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

      • 与函数类型的形参不同,返回类型不会自动转换为指针,必须显式地将返回类型指定为指针类型;

      • 也可以使用尾置返回的方式简化返回指向函数的指针。

        auto f1(int) -> int (*)(int*, int);
        

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/868039.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存