Skip to content

Latest commit

 

History

History
200 lines (109 loc) · 5.87 KB

函数.md

File metadata and controls

200 lines (109 loc) · 5.87 KB

Table of Contents generated with DocToc

与操作符相比,函数也会通过一系列的计算,产生结果,但是函数有自己的名字,操作数没有数量限制,两者都可以重载。

函数的定义

函数体就是一个作用域。

函数的形参为函数提供了已命名的局部存储空间。

实参必须具有与形参类型相同、或能隐式转换为形参类型的数据类型。

函数不能返回另一函数或者内置数组类型,但可以返回函数的指针,或指向数组元素的指针的指针。

没有显式指定返回类型的函数定义或声明是不合法的。

形参可为空,但不能省略。

如果两个参数具有相同的类型,其类型必须重复声明,不允许这样的声明void fun(int a, b);

参数传递

形参的初始化与变量一样,如果形参具有非引用类型,则复制实参的值;如果为引用类型,则它只是实参的别名。

函数的形参可以是指针,此时将复制实参指针。该类形参的任何改变也仅仅作用于局部副本。如果函数将新指针赋给形参,主调函数使用的实参指针的值没有任何改变。

尽管函数的形参是const,但编译器却将其视为形参被声明为普通的类型。

void fcn(const int i){}

void fcn(int i){}// ERROR, Redefine function

不适宜复制实参的情况包括:

  1. 当需要在函数中修改实参的值时。
  2. 需要以大型对象作为实参传递时。
  3. 没有办法实现对象的复制时。

解决办法就是将形参定义为引用或指针。

如果使用引用形参的唯一目的是避免复制实参,那就利用const引用。

非const引用实参只能和完全同类型的非const对象关联。

int incr(int&val) {return ++val;}

int main()

{

  short v1 = 0;

  const int v2 = 32;

  int v3 = incr(v1); //ERROR

  v3 = incr(v2); //ERROR

  v3 = incr(0); //ERROR

  v3 = incr(v1 + v2); //ERROR

  int v4 = incr(v3); //OK

}

C++倾向于传递指向容器中需要处理的元素的迭代器来传递容器。

将数组形参直接定义为指针要比使用数组语法定义更好,这就明确表明了函数操纵的是指向数组元素的指针。

编译器忽略任何数组形参指定的长度,不会去检测数组的长度。

void pintArray(int[])void pintArray(int[10])等同

通过引用传递数组: 

void printArray(int (&arr)[]){}

int *arr[10]; //array of 10 points

int (*arr)[10]; //pointer to an array of 10 elements

怎样确保函数的操作不超出数组实参的边界:

  1. 在数组本身存放一个标志位
  2. 传递指向数组第一个和最后一个元素的下一个位置的指针
  3. 将第二个形参定义为数组的大小

含有可变形参的函数

void foo(parm_list, …);

void foo(…); 

return

返回类型为void的函数中,return不是必须,有隐藏的return在最后一条语句完成时。

返回非引用:函数的返回值用于在初始化在调用函数处创建的临时对象。

返回引用:返回的是对象本身。

千万不要返回局部对象的引用或指针!!!

函数可以返回引用,作为一个左值。

主函数main不能调用自身。 

函数声明

函数与变量类似的是:先声明后使用,定义一次,声明多次。

默认实参只能替换函数调用缺少的尾部实参,因为函数调用时,实参是从左向右赋给形参的。

一个文件中,只能为一个形参指定默认实参一次。

如果函数定义的形参表中提供默认实参,则只有在包含该函数定义的源文件中调用该函数时,默认实参才有效。

局部对象

自动对象:至于当定义它的函数被调用时才存在的对象,比如形参。

静态局部对象:位于函数作用域内,生命期跨越了这个函数的多次调用。 

内联函数

避免函数调用的开销。

内联只是对编译器的一个建议,编译器可以忽略!

把内联函数放入头文件,这样修改要重新编译所有的源文件。 

类的成员函数

函数原型必须在类中定义,函数体可以在类外。

编译器隐式地将类内定义的成员函数当作内联函数。

成员函数含有额外的、隐含的形参,即类对象本身this。

重载函数

任何程序只有一个main函数,main函数不可重载!

每一个版本的重载函数都应该在同一作用域中声明。

重载确定的三个步骤:

1) 候选函数,同名

2) 选择可行函数,形参与实参个数相同,每一个实参的类型与对应的形参匹配

3) 寻找最佳匹配

4) 含有多个形参的重载确定

​ a) 每个实参的匹配都不劣于其它

​ b) 至少一个实参的匹配优于其它

指向函数的指针

允许将形参定义为函数类型,但函数的返回类型必须是指向函数的指针,而不是函数。

导航

目录

上一章:[5. 表达式](5. 表达式.md)

下一章:8. 标准IO库