《C++ primer》英文第五版阅读笔记(二十五)——函数基本知识

来源:互联网 发布:人工智能期刊 编辑:程序博客网 时间:2024/05/01 18:50

Chapter6.1——Function Basics 函数基本知识


函数是一个有名字的代码块。通过函数调用来执行函数内的代码。一个函数可能有0个或多个参数,但是只有一个返回值。函数可以进行重载,也就意味着同一个函数名可能对应多个函数。

一个函数包含四个部分:
(1)函数名。
(2)参数。写在一对小括号里,有多个时要用逗号隔开。
(3)返回值。
(4)函数体。对应函数具体执行什么动作。

通过调用操作符来执行一个函数,这个操作符是一对小括号。

调用操作符需要一个表达式,这个表达式是一个函数或者指向函数的指针。在括号内的是由逗号分隔开的实参列表。

实参用来初始化函数的形参。调用表达式的类型是函数的返回类型。


一个函数的调用做了两件事情:
(1)用相关的实参初始化了函数的实参。
(2)并把控制权交给被调用的函数。
进行函数调用的函数被暂停,被调用函数开始执行。

一个函数的执行以它的形参的(隐式)定义和初始化开始。也就是说当调用一个函数时,先进行的是形参的创建,然后是初始化。

当函数遇到return的时候执行结束。return语句做了两件事:
(1)在return中返回一个值(如果有值的话)。
(2)将控制权从被调用函数转到调用函数。


形参和实参
1)实参是用来初始化形参的。

第一个实参初始化第一个形参,第二个实参初始化第二个形参,以此类推。

虽然我们知道哪个实参初始化哪个形参,但是我们无法确定具体进行初始化的顺序。

2)实参和形参的类型必须匹配,就像初始化器的类型必须和被初始化的对象类型相同一样。
3)当进行参数传递时,函数有几个形参,就要传几个实参。传的实参不能多也不能少。

由于每一个函数调用时,都能保证传递实参的个数和函数的形参个数相同,所以实参总是能被初始化。

函数的形参列表
1)函数的形参列表可以为空,但是不能省略。通常写一个空的形参列表来定义一个没有形参的函数。
2)在C语言中,通常使用关键字void来表示没有形参。func(void)。
3)形参列表包含了一系列由逗号隔开的形参。每一个形参都像一个单独的声明。

虽然有时两个形参的类型可能相同,但是类型名必须每一个形参对应一个。
4)两个形参不能有相同的名字。
5)在函数最外层的本地变量不能和形参有相同的名字。
6)参数名是可选择的。由于无法对无名参数进行使用,所以通常参数都是有名字的。

如果一个函数中定义了无名参数,那么在进行函数调用时也要给这个参数进行传参,尽管这个参数从来没有被使用过。

函数的返回类型
1)大多数的类型都能作为函数的返回类型。
2)函数的返回类型可以是void,这意味着函数没有返回值。
3)然而,函数的返回类型不能是数组类型,或者一个函数类型。但是,函数可以将一个指针返回给一个数组或者一个函数。

本地变量
在C++中,”名字“有范围,“对象”有生存周期。
(1)一个“名字”的范围是指在程序的一部分范围内这个“名字”是可见的。
(2)一个“对象”的生存周期是指在程序的执行时间内这个“对象”是存在的。
定义在函数体内的变量或形参被称为“本地变量”。它们对于那个函数来讲是属于“本地的”,并且将在范围之外定义的同名变量隐藏起来了。

定义在任何函数之外的对象在整个程序的执行期间都是存在的。这样的变量在程序开始执行时被创建,直到程序结束执行,它们被销毁。
本地变量的生存周期取决于它是如何被定义的。

动态对象
1)仅仅在一个块的执行期间内存在的对象是动态对象。当块结束执行之后,动态对象的值是未知的。
2)形参是动态对象。当函数开始执行时,形参的存储空间被分配。
3)形参是定义在函数体里面的。当函数终止执行时它们被销毁。
4)和形参有关联的动态对象被传递被那个函数的实参进行初始化。
和本地对象相关的动态对象,当它们的定义中有初始化器的时候,它们就被初始化了。否则,它们就会被默认初始化,也就是说内置类型的对象如果未进行初始化,那么它们的值是未定义的。

本地静态对象
1)在对函数不断调用期间,如果有一个变量它一直存在,那将会是很有用的。通过将本地变量定义成static就能得到这样的变量。
2)每一个本地静态变量在第一个执行经过这个对象的定义之前就被初始化了。当函数结束时本地静态变量不会被销毁,当程序终止时它们才会被销毁。
3)如果本地静态变量没有精确地初始化,他就被进行值初始化。也就是说内置类型的本地静态变量被初始化为0。

函数声明
1)和其它名字一样,函数名必须在使用前进行声明。一个函数可能只被定义一次但是可能被声明多次。在今后会介绍一种例外情况,可以只对函数进行声明而不进行定义,只要永远也不使用那个函数。
2)函数的声明和定义类似,只是函数的声明没有函数体,取而代之的是一个;分号。
3)由于函数声明没有函数体,也就不需要形参名字了。
4)函数声明中的形参名字经常被省略。
5)尽管形参名字是不必须的,但是它们可以帮助使用者理解这个函数是干什么的。

函数的接口——函数返回类型,函数名,参数类型。
它们定义了我们需要调用函数的全部信息。
函数声明也被称为函数原型。

在头文件中进行函数声明
1)函数应该在头文件中进行声明,在源文件中进行定义。
2)可以在每个使用函数的文件中对函数进行声明,但是这样做是冗余的,并且容易出错。

如果函数声明发生了改变,那个要在每个声明这个函数的文件中对函数声明进行修改。
3)应在使用了某个函数定义的源文件中将对这个函数进行声明的头文件包含进来。

分开编译
1)当程序变得很复杂时,我们会将不同种类的代码部分存在不同的文件中。
2)为了允许将程序写在不同的逻辑部分中,C++支持“分开编译”。分开编译让我们将我们的程序分开到许多文件中,每一个文件都是能进行独立编译的。
3)对程序进行编译会产生编译文件(.obj(windows),.o(linux))。
4)编译器允许我们将多个编译文件进行连接来建立起一次执行——执行文件。


0 0