C++ 基础(八)定义函数

2021/7/30 1:05:43

本文主要是介绍C++ 基础(八)定义函数,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1. 程序的分解

  • 在内存中哪些地方进行了函数调用,返回时从哪个地方继续执行,这些信息都自动保存在栈中。
  • 类中也有函数,比如string类的length()和find()函数,等。

 

2. 定义函数

  • 要素:返回类型,函数名,参数列表。
  • 函数的签名:函数名和参数列表的组合。
  • 实参顺序应对应于形参的顺序,flaot转为double 不会丢失数据,因为double表示的数字范围是float的两倍。
  • double->float时也会隐式转换,这是缩窄转换。转换时丢失精度。

 

3. 给函数传递实参

  • 实参对应于函数声明中的类型和顺序。
  • 按值传递:直接修改实参会失败。
    • 给函数传递指针:解引用,修改地址中的内容。
    • 函数传递数组:传递数组的首地址,而非数组中的元素值,数组表示法和指针表示法是完全相同的。
    • const指针参数:只访问数组元素的值,不需要修改它们,最好的方式是把参数类型指定为cosnt:double avreage(const double *array, size_t count);  
    • 多维数组传给函数:double beans [3][4] {};  double yield (double  beans [][4], size_t count);   一般函数的参数需要指定第二维度的大小。
  • 按引用传递:
    • 引用只是另一个变量的别名。
    • 按值传递需要复制对象,而按引用传递则不会进行复制。
    • 对比引用和指针:
      • 实际上,编译器会按照和编译指针相同的方式编译引用。
      • 使用原则:
        • 想允许使用nullptr实参,就不能使用引用。
        • 引用的语法优雅,使函数是否修改值这一点不容易被看出来。
        • 编码时,传递非const值的对象,不建议传递引用参数,而建议传递指针参数。
    • 对比输入和输出参数
      • 不修改实参的函数中使用引用const值的参数尤为重要。
    • 按引用传递数组
      • 声明:double average10 (const double (&array)[10]);
    • 引用和隐式转换
      • 形参是引用,实参比引用类型小,可能引起内存越界的访问。
  • 字符串视图:新的const string 引用
    • 使用cosnt string & 有众多的优点,可以防止string被复制。但当实参是字符串字面量时,由于隐式转换的原因,还是会被复制。
    • 新的C++17提供了string_view类型,具有固定的常量特性,初始化和复制string_view的开销很低。
    • 这样为输入参数总是使用string_view,而不是const std::string &,也不需要string_view &。
    • 禁止将std::string_view隐式转为std::string类型。
    • 不能直接使用加法运算符连接string_view对象。

 

4. 默认参数值

  • 原型中指定默认实参,且不在函数定义中指定。
  • 使用时可以不用指定实参。
  • 多个默认实参值,默认值都放在参数列表的最后。

 

5. main()函数的实参

  • int main(int argc, char * argv[]);

 

6. 从函数中返回值

  • 返回指针,不能返回栈上的地址指针。
  • 返回引用,不返回自动局部变量的引用。返回引用是在赋值运算符左侧调用函数的唯一方式。
  • 返回推断类型:
    • 返回类型很复杂时,可以使用auto。
    • 指定函数模板的返回类型,也很实用。
    • 返回类型推断和引用: auto不会推断为一个引用类型,总是推断为一个值类型。若指定auto &,这时返回一个引用。指定为const auto时,返回一个const类型。
  • 使用可选值
    • C++17提供可选的参数。
    • optional<int> find_last_in_string(string_view string, char to_find, optional<int> start_index);
    • std::nullopt,特殊常量,初始化还没有为T赋值的optional<T>值。
    • optional<> 有has_value()成员,也可以自动转为bool。

 

7. 静态变量

  • 变量前加上static,定义之后一直会存在,直到程序结束。

 

8. 内联函数

  • 在函数的定义使用inline关键字。

 

9. 函数重载

  • 用多个函数完成相同的任务,但参数类型不同。
  • 编译器用函数签名来区分函数,函数签名是函数名与参数列表的组合。
  • 函数返回类型不是函数签名的一部分,声明了两个函数,函数名相同,参数列表相同,只是返回值类型不同,会报错。
  • 重载和指针参数:指向不同类型的指针对于重载函数时不同的。
  • 重载和引用重载:参数若只是引用和非引用的区别,则可能调用任何一个。
  • 编译器不会使用临时地址初始化对非const值的引用。在函数调用时做参数类型转换有时不奏效,除非原型上定义着const。
  • 重载和const参数
    • 函数声明中,只有参数类型const的区别时,函数原型没有区别。
    • 实参传递时:
      • 函数原型中把参数定义为const是没有意义的。
      • 声明中可以没有定义中使用const确是有意义的。
    • 重载和const指针参数:
      • type * 和 const type *是不同的。
      • type * 和 const type * const 是相同的。
    • 重载和const引用参数:
      • T&和const T &总是不同的。
    • 重载和默认实参值:
      • 可以为函数指定默认参数,对于重载函数,默认参数会影响编译器区分函数调用的能力。

 

10. 递归

  • 函数包含自身调用时,该函数就称为递归函数。
  • 基础的递归,斐波那契数列。
  • 递归算法。


这篇关于C++ 基础(八)定义函数的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程