函数简介
本节阅读量:上一章中,我们将函数定义为按顺序执行的语句集合。虽然这个定义是正确的,但它没有揭示函数为什么有用。让我们更新一下函数的定义:函数是一个可重用的语句序列,旨在完成特定的工作。
每个可执行程序都必须有一个名为main的函数(程序运行时从这里开始执行)。然而,随着程序变得越来越长,将所有代码放在主函数中会变得难以管理。函数提供了一种方法,可以将程序划分为较小的模块,这些模块更易于组织、测试和使用。C++标准库附带了许多已编写好的函数供使用——当然,编写自己的函数也很常见。自己编写的函数称为用户定义函数。
考虑一个现实生活中的场景:你正在读书时,需要打个电话。你在书中放了一个书签,打完电话后,回到书签的位置,继续读书。
C++程序以相同的方式工作。函数内的语句按顺序执行。函数调用是一个表达式,告诉CPU中断当前函数并执行另一个函数。CPU在当前执行点”放置书签”,然后调用(执行)被调用的函数。当被调用的函数结束时,CPU返回到之前标记的点,继续执行。
发起函数调用的函数是调用者,而被调用的函数是被调用者或被调用函数。
用户定义函数的示例
首先,从定义函数的基本语法开始。接下来几节课中,所有用户定义函数将采用以下形式:
|
|
第一行称为函数头,它告诉编译器函数的存在、函数的名称以及将在后续课程中介绍的一些其他信息(如返回类型和参数类型)。
- 本课中,返回值类型使用int(对于函数main())或void。下一课中将更多讨论返回类型和返回值,现在可以先忽略这些。
- 就像变量有名称一样,用户定义函数也有名称。「函数名」是用户定义函数的名称(标识符)。
- 标识符后面的括号告诉编译器在定义函数。
中间的花括号和语句称为函数体,其中包含决定函数执行什么操作的语句。
下面的示例程序展示了如何定义和调用新函数:
|
|
该程序产生以下输出:
|
|
程序从函数main开始执行,第一行打印Starting main()。
main中的第二行是对函数doPrint的函数调用。通过在函数名后附加一对括号来调用函数doPrint,如:doPrint()。注意,如果忘记括号,程序将无法编译。
由于进行了函数调用,main中语句的执行被挂起,执行跳转到被调用函数doPrint的顶部。doPrint中的第一行(也是唯一一行)打印In doPrint()。当doPrint终止时,执行返回给调用方(main函数),并从中断的位置恢复。因此,main中执行的下一条语句打印Ending main()。
警告
当进行函数调用时,不要忘记在函数名后包含括号()。
多次调用函数
函数的一个好处是可被多次调用。演示如下:
|
|
该程序输出:
|
|
由于main调用了doPrint两次,所以doPrint执行了两次,In doPrint() 也打印了两次(每次调用一次)。
被调用的函数,再调用函数
函数main可以调用另一个函数(例如上面例子中的函数doPrint)。实际上,任何函数都可以调用任何其他函数。如下程序中,函数main调用函数doA,而doA又调用函数doB:
|
|
该程序产生以下输出:
|
|
不支持嵌套函数定义
与一些编程语言不同,C++中,函数不能在其他函数中定义。以下程序不合法:
|
|
正确方法是:
|
|
注
“foo”是一个无意义的词,当名称不重要时,常用”foo”作为函数或变量的占位符名称。这样的词被称为元语法变量(在日常用语中,通常被称为”占位符名称”,因为没有人能记住”元语法变量”这个术语)。C++中其他常见的元语法变量包括”bar”、”baz”以及以”oo”结尾的三个字母的单词,如”goo”、”moo”和”boo”。