C++ primer学习笔记 第六章 函数

目录

函数基础

参数传递

返回类型和return语句

函数重载

特殊用途语言特性

函数匹配

函数指针

函数声明(Function Declarations)


函数基础

  • 函数定义:包括返回类型、函数名字和0个或者多个形参(parameter)组成的列表和函数体。
  • 调用运算符:调用运算符的形式是一对圆括号 (),作用于一个表达式,该表达式是函数或者指向函数的指针; 圆括号内是用逗号隔开的实参(argument)列表。
  • 形参和实参:形参和实参的个数和类型必须匹配上
  • 返回类型: void表示函数不返回任何值。函数的返回类型不能是数组类型或者函数类型,但可以是指向数组或者函数的指针。
  • 名字:名字的作用于是程序文本的一部分,名字在其中可见。
  • 生命周期:对象的生命周期是程序执行过程中该对象存在的一段时间。
  • 局部变量(local variable):形参和函数体内部定义的变量统称为局部变量。它对函数而言是局部的,对函数外部而言是隐藏的。
  • 自动对象:只存在于块执行期间的对象。当块的执行结束后,它的值就变成未定义的了。
  • 局部静态对象: static类型的局部变量,生命周期贯穿函数调用前后。
  • 函数声明:函数的声明和定义唯一的区别是声明无需函数体,用一个分号替代。函数声明主要用于描述函数的接口,也称函数原型。
  • 在头文件中进行函数声明:建议变量在头文件中声明;在源文件中定义。
  • 分离编译: CC a.cc b.cc直接编译生成可执行文件;CC -c a.cc b.cc编译生成对象代码a.o b.o; CC a.o b.o编译生成可执行文件。

参数传递

  • 引用传递(passed by reference):又称传引用调用(called by reference),指形参是引用类型,引用形参是它对应的实参的别名。
    • 引用形参直接关联到绑定的对象,而非对象的副本。
    • 使用引用形参可以用于返回额外的信息
    • 经常用const引用来避免不必要的复制。
    • void swap(int &v1, int &v2)
  • 值传递(passed by value):又称传值调用(called by value),指实参的值是通过拷贝传递给形参。
  • 指针形参:常用在C中,C++建议使用引用类型的形参代替指针。
  • const形参
    • 形参的顶层const被忽略。
    • 我们可以使用非常量初始化一个底层const对象,但是反过来不行。
    • 在函数中,不能改变实参的局部副本
    • 尽量使用常量引用。
  • 数组形参
    • 当我们为函数传递一个数组时,实际上传递的是指向数组首元素的指针。
    • 要注意数组的实际长度,不能越界。
  • main处理命令行选项
    • int main(int argc, char *argv[]){...}
    • 第一个形参代表参数的个数;第二个形参是参数C风格字符串数组。
  • 可变形参
    • 所有实参类型相同,可以使用 initializer_list的标准库类型。
    • 实参类型不同,可以使用可变参数模板
    • 省略形参符: ...,便于C++访问某些C代码,这些C代码使用了 varargs的C标准功能。

返回类型和return语句

  • 无返回值函数:没有返回值的 return语句只能用在返回类型是 void的函数中,返回 void的函数不要求非得有 return语句。
  • 有返回值函数return语句的返回值的类型必须和函数的返回类型相同,或者能够隐式地转换成函数的返回类型。
  • 不要返回局部对象的引用或指针
  • 引用返回左值:函数的返回类型决定函数调用是否是左值。调用一个返回引用的函数得到左值;其他返回类型得到右值。
  • 列表初始化返回值:函数可以返回花括号包围的值的列表。(C++11)
  • 返回数组指针
    • Type (*function (parameter_list))[dimension]
    • 使用类型别名: typedef int arrT[10]; 或者 using arrT = int[10;],然后 arrT* func() {...}
    • 使用 decltype: decltype(odd) *arrPtr(int i) {...}
    • 尾置返回类型: 在形参列表后面以一个->开始:auto func(int i) -> int(*)[10](C++11)

函数重载

  • 重载:如果同一作用域内几个函数名字相同但形参列表不同,我们称之为重载(overload)函数。
  • 重载和const形参
    • 一个有顶层const的形参和没有它的函数无法区分。 Record lookup(Phone* const)和 Record lookup(Phone*)无法区分。
    • 相反,是否有某个底层const(指针指向的对象或者内置类型不变)形参可以区分。 Record lookup(Account*)和 Record lookup(const Account*)可以区分。
  • 重载和作用域:若在内层作用域中声明名字,它将隐藏外层作用域中声明的同名实体,在不同的作用域中无法重载函数名。

特殊用途语言特性

  • 默认实参
    • string screen(sz ht = 24, sz wid = 80, char backgrnd = ' ');
    • 一旦某个形参被赋予了默认值,那么它之后的形参都必须要有默认值。
  • 内联(inline)函数
    • 普通函数的缺点:调用函数比求解等价表达式要慢得多。
    • inline函数可以避免函数调用的开销,可以让编译器在编译时内联地展开该函数。
    • inline函数应该在头文件中定义。
  • constexpr函数
    • 指能用于常量表达式的函数。
    • constexpr int new_sz() {return 42;}
    • 函数的返回类型及所有形参类型都要是字面值类型。
    • constexpr函数应该在头文件中定义。

函数匹配

  • 重载函数匹配的三个步骤:1.候选函数;2.可行函数;3.寻找最佳匹配。
  • 候选函数:选定本次调用对应的重载函数集,集合中的函数称为候选函数(candidate function)。
  • 可行函数:考察本次调用提供的实参,选出可以被这组实参调用的函数,新选出的函数称为可行函数(viable function)。
  • 寻找最佳匹配:基本思想:实参类型和形参类型越接近,它们匹配地越好。

函数指针

  • 函数指针:是指向函数的指针。
  • bool (*pf)(const string &, const string &); 注:两端的括号不可少。
  • 函数指针形参
    • 形参中使用函数定义或者函数指针定义效果一样。
    • 使用类型别名或者decltype
  • 返回指向函数的指针:1.类型别名;2.尾置返回类型。

函数声明(Function Declarations)

和变量类似,函数只能定义一次,但可以声明多次。函数声明也叫做函数原型(function prototype)。

函数应该在头文件中声明,在源文件中定义。定义函数的源文件应该包含含有函数声明的头文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值