C++ 控制结构和函数(二) —— 函数I(Functions I)

时间:2022-09-09 12:55:01

通过使用函数(functions)我们可以把我们的程序以更模块化的形式组织起来,从而利用C++所能提供的所有结构化编程的潜力。

一个函数(function)是一个可以从程序其它地方调用执行的语句块。以下是它的格式:

 

type name ( argument1, argument2, ...) statement

 

这里:

  • type 是函数返回的数据的类型
  • name 是函数被调用时使用的名
  • argument 是函数调用需要传入的参量(可以声明任意多个参量)。每个参量(argument)由一个数据类型后面跟一个标识名称组成,就像变量声明中一样(例如,int x)。参量仅在函数范围内有效,可以和函数中的其它变量一样使用, 它们使得函数在被调用时可以传入参数,不同的参数用逗号(comma)隔开.
  • statement 是函数的内容。它可以是一句指令,也可以是一组指令组成的语句块。如果是一组指令,则语句块必须用花括号{}括起来,这也是我们最常见到情况。其实为了使程序的格式更加统一清晰,建议在仅有一条指令的时候也使用花括号,这是一个良好的编程习惯。

下面看一下第一个函数的例子:

// function example
#include <iostream.h>
int addition (int a, int b)
{
    int r;
    r=a+b;
    return (r);
}

int main ()
{
    int z;
    z = addition (5,3);
    cout << "The result is " << z;
    return 0;
}
The result is 8

记得在我们教程开始时说过:一个C++程序总是从main函数开始执行。 因此我们从那里开始。

我们可以看到 main 函数以定义一个整型变量z 开始。紧跟着我们看到调用addition 函数。我们可以看到函数调用的写法和上面函数定义本身十分相似:

C++ 控制结构和函数(二) —— 函数I(Functions I)

参数有明显的对应关系。在main 函数中我们调用addition 函数,并传入两个数值: 5 和3 , 它们对应函数addition 中定义的参数int a 和int b。

当函数在main 中被调用时,程序执行的控制权从main转移到函数addition。调用传递的两个参数的数值 (5 和3) 被复制到函数的本地变量(local variables) int a 和int b 中。

函数addition 中定义了新的变量(int r;),通过表达式r=a+b;, 它把a 加b 的结果赋给r 。因为传过来的参数a 和b 的值分别为5 和3 ,所以结果是8。

下面一行代码:

return (r);

结束函数addition,并把控制权交还给调用它的函数(main) ,从调用addition的地方开始继续向下执行。另外,return 在调用的时候后面跟着变量r (return (r);), 它当时的值为8, 这个值被称为函数的返回值。

C++ 控制结构和函数(二) —— 函数I(Functions I)

函数返回的数值就是函数的计算结果,因此, z 将存储函数addition (5, 3)返回的数值, 即8。用另一种方式解释,你也可以想象成调用函数(addition (5,3)) 被替换成了它的返回值 (8)。

接下来main中的下一行代码是:

cout << "The result is " << z;

它把结果打印在屏幕上。

C++ 控制结构和函数(二) —— 函数I(Functions I)变量的范围(Scope of variables)

你必须考虑到变量的范围只是在定义该变量的函数或指令块内有效,而不能在它的函数或指令块之外使用。 例如,在上面的例子里就不可能在main 中直接使用变量a, b 或 r ,因为它们是函数addition的本地变量(local variable)。在函数addition中也不可能直接使用变量z,因为它是main的本地变量。

因此,本地变量 (local variables)的范围是局限于声明它的嵌套范围之内的。尽管如此,你还可以定义全局变量(global variables),它们可以在代码的任何位置被访问,不管在函数以内还是以外。要定义全局变量,你必须在所有函数或代码块之外定义它们,也就是说,直接在程序体中声明它们。

这里是另一个关于函数的例子:

// function example
#include <iostream.h>
int subtraction (int a, int b)
{
    int r;
    r=a-b;
    return (r);
}

int main ()
{
    int x=5, y=3, z;
    z = subtraction (7,2);
    cout << "The first result is " << z << '\n';
    cout << "The second result is " << subtraction (7,2) << '\n';
    cout << "The third result is " << subtraction (x,y) << '\n';
    z= 4 + subtraction (x,y);
    cout << "The fourth result is " << z << '\n';
    return 0;
}
The first result is 5
The second result is 5
The third result is 2
The fourth result is 6

在这个例子中,我们定义了函数subtraction。这个函数的功能是计算传入的两个参数的差值并将结果返回。

在 main 函数中,函数subtraction被调用了多次。我们用了几种不同的调用方法,因此你可以看到在不同的情况下函数如何被调用。

为了更好的理解这些例子,你需要考虑到被调用的函数其实完全可以由它所返回的值来代替。例如在上面例子中第一种情况下 (这种调用你应该已经知道了,因为我们在前面的例子中已经用过这种形式的调用):

z = subtraction (7,2);
cout << "The first result is " << z;

如果我们把函数调用用它的结果(也就是5)替换,我们将得到:

z = 5;
cout << "The first result is " << z;

同样的

cout << "The second result is " << subtraction (7,2);

与前面的调用有同样的结果,但在这里我们把对函数subtraction 的调用直接用作cout的参数。这可以简单想象成我们写的是:

cout << "The second result is " << 5;

因为5 是subtraction (7,2)的结果。

cout << "The third result is " << subtraction (x,y);

中,与前面的调用唯一的不同之处是这里调用subtraction 时的参数使用的是变量而不是常量。这样用时毫无问题的。在这个例子里,传入函数subtraction 的参数值是变量x 和y中存储的数值,即分别为5 和3,结果为2。

第四种调用也是一样的。只要知道除了

z = 4 + subtraction (x,y);

我们也可以写成:

z = subtraction (x,y) + 4;

它们的结果是完全一样的。注意在整个表达式的结尾写上分号semicolon sign (;)。它并不需要总是跟在函数调用的后面,因为你可以有一次把它们想象成函数被它的结果所替代:

z = 4 + 2;
z = 2 + 4;

没有返回值类型的函数,使用void.

如果你记得函数声明的格式:

type name ( argument1, argument2 ...) statement

就会知道函数声明必须以一个数据类型(type)开头,它是函数由return 语句所返回数据类型。但是如果我们并不打算返回任何数据那该怎么办呢?

假设我们要写一个函数,它的功能是打印在屏幕上打印一些信息。我们不需要它返回任何值,而且我们也不需要它接受任何参数。C语言为这些情况设计了void 类型。让我们看一下下面的例子:

// void 函数示例
#include <iostream>
using namespace std;

void printmessage ()
{
cout << "I'm a function!";
}

int main ()
{
printmessage ();
return 0;
}
I'm a function!

void还可以被用在函数参数位置,表示我们明确希望这个函数在被调用时需要任何参数。例如上面的函数printmessage也可以写为以下形式:

void printmessage (void)
{
cout << "I'm a function!";
}

虽然在C++ 中void可以被省略,我们还是建议写出void,以便明确指出函数不需要参数。

你必须时刻知道的是调用一个函数时要写出它的名字并把参数写在后面的括号内。但如果函数不需要参数,后面的括号并不能省略。因此调用函数 printmessage 的格式是

printmessage();

函数名称后面的括号就明确表示了它是一个函数调用,而不是一个变量名称或其它什么语句。以下调用函数的方式就不对:

printmessage;