There is much about functions in C that is similar to functions in other languages,which is why youʹve been able to use them thus far with only an informal discussion.However there are some aspects of functions that are less intuitive, so this chapter formally describes functions in C.
C 的函数和其他语言的函数(或过程、方法)相似之处甚多。所以到现在为止,尽管我们对函数只是进行了一点非正式的讨论,但你己经能够使用它们了。但是,函数的有些方面并不像直觉上应该的那样,所以本章将正式描述C 的函数。
7.1 Function Definition
The definition of a function specifics the function body, the block of statements to be executed when the function is called. In contrast, a function declaration is used where the function is being called. A declaration gives the compiler information about the function so that it can be called correctly. Letʹs look first at definitions.
函数的定义就是函数体的实现。函数体就是一个代码块,它在函数被调用时执行。与函数定义相反,函数声明出现在函数被调用的地方。函数声明向编译器提供该函数的相关信息,用于确保函数被正确地调用。首先让我们来看一下函数的定义。
A function is defined with this syntax:
type name( formal_parameters )
block
Recall that a block is a pair of braces enclosing optional declarations followed by optional statements. The minimal function, therefore, looks like this:
回忆一下,代码块就是一对花括号,里面包含了一些声明和语句(两者都是可选的)。因此,最简单的函数大致如下所示:
function_name()
{
}
When called, this function simply returns. Nevertheless, it serves a useful purpose as a stub, a placeholder for code that has yet to be implemented. Writing stubs, orʺstubbing outʺ code that has not yet been written, lets you compile and test the rest of the program.
当这个函数被调用时,它简单地返回。然而,它可以实现一种有用的存根(stub) 目的,为那些此时尚未实现的代码保留一个位置。编写这类存根,或者说为尚未编写的代码"占好位置",可以保持程序在结构上的完整性,以便于你编译和测试程序的其他部分。
The list of formal parameters includes variable names and their type declarations. The block contains declarations for local variables and the statements that are executed when the function is called. Program 7.1 is an example of a simple function.
形式参数列表包括变量名和它们的类型声明。代码块包含了局部变量的声明和函数调用时需要执行的语句。程序7.1 是一个简单函数的例子。
Writing the function type on a separate line from the function name is a matter of style; it makes it easier to locate the function names when perusing the source code either visually or with some program.
把函数的类型与函数名分写两行纯属风格问题。这种写法可以使我们在使用视觉或某些工具程序追踪源代码时更容易查找函数名。
In K&R C, the types of formal parameters were declared in a separate list that appeared between the parameter list and the opening brace of the function body, like this:
在K&R C 中,形式参数的类型以单独的列表进行声明,并出现在参数列表和函数体的左花括号之间,如下所示:
int *
find_int( key, array, array_len )
int key;
int array[];
int array_len;
{
This declaration form is allowed by the Standard mainly so that older programs can be compiled without modification. The newer declaration style is preferred for two reasons. First, it eliminates the redundancy of die old style. More importantly, it allows for the use of function prototypes, discussed later in this chapter, which improve the compilerʹs error checking of function calls.
这种声明形式现在仍为标准所允许,主要是为了让较老的程序无需修改便可通过编译。但我们提倡新声明风格,理由有二:首先,它消除了旧式风格的冗余。其次,也是更重要的一点,它允许函数原型的使用,提高了编译器在函数调用时检查错误的能力。关于函数原型,我们将在本章后面的内容里讨论。
/*
** Find the place in an array where a particular integer value
** is stored, and return a pointer to that location.
*/
#include <stdio.h>
int *
find_int( int key, int array[], int array_len )
{
int i;
/*
** For each location in the array ...
*/
for( i = 0; i < array_len; i += 1 )
/*
** Check the location for the desired value.
*/
if( array[ i ] == key )
return &array[ i ];
return NULL;
}
Program 7.1 Find an integer in an array
7.1.1 Return Statement
When execution reaches the end of the function definition, the function returns, that is, execution goes back to where the function was called. The return statement allows you to return from anywhere in the function body, not just at its end. Its syntax is shown below.
当执行流到达函数定义的末尾时,函数就将返回(return) ,也就是说,执行流返回到函数被调用的地方。return 语句允许你从函数体的任何位置返回,并不一定要在函数体的末尾。它的语法如下所示:
return expression;
The expression is optional. It is omitted in functions that do not return a value to the calling program, what most other languages call a procedure. Functions that return implicitly by reaching the end of their code also do not return a value. Procedure‐type functions should be declared with the type void.
表达式expression 是可选的。如果函数无需向调用程序返回一个值,它就被省略。这类函数在绝大多数其他语言中被称为过程( procedure )。这些函数执行到函数体末尾时隐式地返回,它们没有返回值。这种没有返回值的函数在声明时应该把函数的类型声明为void 。
A true function is called from within an expression, and must return a value that is used in evaluating the expression. The return statement in these functions must include the expression. Usually, the expression will be of the type that the function was declared to return. An expression of a different type is permitted only if the compiler can convert it to die proper type through the usual arithmetic conversions.
真函数是从表达式内部调用的,它必须返回一个值,用于表达式的求值。这类函数的retum 语句必须包含一个表达式。通常,表达式的类型就是函数声明的返回类型。只有当编译器可以通过寻常算术转换把表达式的类型转换为正确的类型时,才允许返回类型与函数声明的返回类型不同的表达式。
Some programmers prefer to write return statements like this:
有些程序员更喜欢把return 语句写成下面这种样子:
return( x );
The syntax does not require parentheses, but you can use them if you prefer because parentheses are always legal around an expression.
语法并没有要求你加上括号。但如果你喜欢,尽管加上,因为在表达式两端加上括号总是合法的。
In C, both types of subprograms are called functions. It is possible to call a true function (one that returns a value) without using the value in any expression. In this situation, the returned value is just discarded. Calling a procedure‐type function from within an expression is a serious error, though, because an unpredictable (garbage) value is used in evaluating the expression. Fortunately, modern compilers usually catch this error because they are stricter about function return types than were earlier compilers.
在C 中,子程序不论是否存在返回值,均被称为函数。调用一个真函数(即返回一个值的函数)但不在任何表达式中使用这个返回值是完全可能的。在这种情况下,返回值就被丢弃。但是,从表达式内部调用一个过程类型的函数(无返回值〉是一个严重的错误,因为这样一来在表达式的求值过程中会使用一个不可预测的值(垃圾)。幸运的是,现代的编译器通常可以捕捉这类错误,因为它们较之老式编译器在函数的返回类型上更为严格。
上一章 Pointers on C——6 Pointers.15