03-定义函数
7.1.1 定义函数
可以将函数分成两类:没有返回值的函数和有返回值的函数。没有返回值的函数被称为void函数,其通用格式如下:
void functionName(parameterList)
{
statement(s)
return; // optional
}
其中,parameterList指定了传递给函数的参数类型和数量,本章后面将更详细地介绍该列表。可选的返回语句标记了函数的结尾;否则,函数将在右花括号处结束。void函数相当于Pascal中的过程、FORTRAN中的子程序和现代BASIC中的子程序过程。通常,可以用void函数来执行某种操作。例如,将Cheers!打印指定次数(n)的函数如下:
void cheers(int n) // no return value
{
for (int i = 0; i < n; i++)
std::cout << "Cheers! ";
std::cout << std::endl;
}
参数列表int n意味着调用函数cheers()时,应将一个int值作为参数传递给它。
有返回值的函数将生成一个值,并将它返回给调用函数。换句话来说,如果函数返回9.0的平方根(sqrt(9.0)),则该函数调用的值为3.0。这种函数的类型被声明为返回值的类型,其通用格式如下:
typeName functionName(parameterList)
{
statements
return value; // value is type cast to type typeName
}
对于有返回值的函数,必须使用返回语句,以便将值返回给调用函数。值本身可以是常量、变量,也可以是表达式,只是其结果的类型必须为typeName类型或可以被转换为typeName(例如,如果声明的返回类型为double,而函数返回一个int表达式,则该int值将被强制转换为double类型)。然后,函数将最终的值返回给调用函数。C++对于返回值的类型有一定的限制:不能是数组,但可以是其他任何类型——整数、浮点数、指针,甚至可以是结构和对象!(有趣的是,虽然C++函数不能直接返回数组,但可以将数组作为结构或对象组成部分来返回。)
作为一名程序员,并不需要知道函数是如何返回值的,但是对这个问题有所了解将有助于澄清概念(另外,还有助于与朋友和家人交换意见)。通常,函数通过将返回值复制到指定的CPU寄存器或内存单元中将其返回。随后,调用程序将查看该内存单元。返回函数和调用函数必须就该内存单元中存储的数据的类型达成一致。函数原型将返回值类型告知调用程序,而函数定义命令被调用函数应返回什么类型的数据(参见图7.1)。在原型中提供与定义中相同的信息似乎有些多余,但这样做确实有道理。要让信差从办公室的办公桌上取走一些物品,则向信差和办公室中的同事交代自己的意图,将提高信差顺利完成这项工作的概率。
函数在执行返回语句后结束。如果函数包含多条返回语句(例如,它们位于不同的if else选项中),则函数在执行遇到的第一条返回语句后结束。例如,在下面的例子中,else并不是必需的,但可帮助马虎的读者理解程序员的意图:
int bigger(int a, int b)
{
if (a > b )
return a; // if a > b, function terminates here
else
return b; // otherwise, function terminates here
}
如果函数包含多条返回语句,通常认为它会令人迷惑,有些编译器将针对这一点发出警告。然而,这里的代码很简单,很容易理解。
有返回值的函数与Pascal、FORTRAN和BASIC中的函数相似,它们向调用程序返回一个值,然后调用程序可以将其赋给变量、显示或将其用于别的用途。下面是一个简单的例子,函数返回double值的立方:
double cube(double x) // x times x times x
{
return x * x * x; // a type double value
}
例如,函数调用cube(1.2)将返回1.728。请注意,上述返回语句使用了一个表达式,函数将计算该表达式的值(这里为1.728),并将其返回。