码迷,mamicode.com
首页 > 编程语言 > 详细

C++ Primer 第四版读书笔记(六)之函数

时间:2015-01-03 21:06:54      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:

内联函数、类成员函数和重载函数以及函数指针。

函数可以看作程序员定义的操作。与内置操作符相同的是,每个函数都会实现一系列的计算,然后(大多数时候)生成一个结算结果。但与操作符不同的是,函数有自己的函数名,而且操作数没有数量限制。与操作符一样,函数可以重载,这意味着同样的函数名可以对应对个不同的函数。

一、函数的定义

函数由函数名以及一组操作数类型唯一地表示。函数的操作数,也即形参(parameter),在一对圆括号中声明,形参与形参之间以逗号分隔。函数执行的计算在一个称为函数体(functionbody)的块语句中定义。每一个函数都有一个相关联的返回类型(return type)。

1.1 函数的调用

C++语言使用调用操作符(即一对圆括号)实现函数的调用。调用操作符的操作数是函数名和一组(有可能是空的)由逗号分隔的实参。函数调用的结果类型就是函数返回值的类型,该运算的结果本身就是函数的返回值。

函数调用做了两件事:用对应的实参初始化函数的形参,并将控制权转移给被调用函数,主调函数的执行被挂起,被调函数开始执行。函数的运行以形参的(隐式)定义和初始化。

1.2 函数体是一个作用域

函数体是一个语句块,定义了函数的具体操作。通常,这个块语句包含在一对花括号中,形成了一个新的作用域。和其他的块语句一样,在函数体中可以定义标量。在函数体内定义的变量只在该函数中才可以访问。这种变量称为局部变量,她们相对于定义它们的函数而言是“局部的”,其名字只能在该函数的作用域中可见。这种变量只在函数运行时存在。

1.3 形参和实参

类似于局部变量,函数的形参为函数提供了已命名的局部存储空间。它们之间的差别在于形参是在函数的形参表中定义的,并由调用函数时传递给函数的实参初始化。

实参则是一个表达式。它可以是标量或者是字面常量值,甚至是包含一个或几个操作符的表达式。在调用函数时,所传递的实参个数必须和函数的形参个数完全相同。与初始化式的类型必须与被初始化对象的类型匹配一样,实参的类型也必须与其对应的形参的类型完全匹配:实参必须具有与形参类型相同、或者能隐式转换为形参类型的数据类型。

1.4 函数返回类型

函数的返回类型可以是内置类型(如int或者double)、类类型或复合类型(如int&或string*),还可以是void类型,表示该函数不返回任何值。

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

二、参数传递

每次调用函数时,都会重新创建该函数所有的形参,此时传递的实参将会初始化对应的形参。

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

2.1  非引用形参

普通的非饮用类型的参数通过复制对应的实参实现初始化。当用实参副本初始化形参时,函数并没有没有访问调用所传递的实参本身,因此不会修改实参的值。

非饮用形参表示对应的实参的局部副本。对这类形参的修改仅仅改变了局部副本的值。一旦函数执行结束,这些局部变量的值也就没有了。

2.1.1 指针形参

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

事实上被复制的指针只影响对指针的赋值。如果函数形参是非const类型的指针,则函数可以通过指针实现赋值,修改指针所指向对象的值。

可以将指向const对象的指针初始化为指向非const对象,但不可让指向非const对象的指针指向const对象。

2.1.2 const形参

在调用函数时,如果该函数使用非饮用的非const形参,则既可给该函数传递const实参也可以传递非const实参。

2.1.3 复制实参的局部性

复制实参并不是在所有的情况下都适合,不适宜复制实参的情况包括:

1、当需要在函数中修改实参的值时。

2、当需要以大型对象作为实参传递时。对实际的应用而言,复制对象所付出的时间和存储空间代价往往过大。

3、当没有办法实现对象的复制时。

2.2 引用形参

应该将不需要修改的引用形参定义为const引用。普通的非const引用形参在使用时不太灵活。这样的形参既不能用const对象初始化,也不能用字面值或产生右值的表达式实参初始化。

三、 vector和其他容器类型的形参

通常,函数不应该有vector或其他标准库容器类型的形参。调用含有普通的非引用vector形参的函数将会复制vector的每一个元素。

四、数组形参

数组有两个特殊的性质,影响我们定义和使用作用在数组上的函数:一是不能复制数组;二是使用数组名字时,数组名会自动转化为指向其第一个元素的指针。因为数组不能复制,所以无法编写使用数组类型形参的函数。因为数组会被自动转化为指针,所以处理数组的函数通常通过操纵指向数组中的元素的指针来处理数组。

4.1 数组形参的定义

如果要编写一个函数,输出int型数组的内容,可用下面三种方式指定数组形参:

void printValue(int *){}

void printValue(int []){}

void printValue(int [10]){}

虽然不能直接传递数组,但是函数的形参可以写成数组的形式。

通常,将数组形参直接定义为指针要比使用数组语法定义更好。这样就明确地表示,函数操纵的是指向数组元素的指针,而不是数组本身。由于忽略了数组长度,形参定义中如果包含了数组长度则特别引起误解。

当编译器检查数组形参关联的实参时,它只会检查实参是不是指针、指针的类型和数组元素的类型是否匹配,而不会检查数组的长度。

4.2 数组实参

和其他类型一样,数组形参可定义为引用或非引用类型。大部分情况下,数组以普通的非引用类型传递,此时数组会悄悄地转换为指针。一般来说,非引用类型的形参会初始化为其相应实参的副本。而在传递数组时,实参是指向数组第一个元素的指针,形参复制的是这个指针的值,而不是数组元素本身。函数操纵的是指针的副本,因此不会修改实参指针的值。然而,函数可通过该指针改变它所指向的数组元素的值。通过指针形参做的任何改变都在修改数组元素本身。

C++ Primer 第四版读书笔记(六)之函数

标签:

原文地址:http://blog.csdn.net/y601500359/article/details/42361567

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!