Pointers on C——7 Functions.10

7.7 Summary

A function definition specifies both the parameter list and the body of the function, the statements that are executed when the function is called. There are two acceptable forms for writing the parameter list. The K&R style declares the types of the parameters in a separate list that occurs prior to the opening brace of the functionʹs body. The new style, which is preferred, includes the types in the parameter list. A function with no statements in its body, called a stub, is useful in testing incomplete programs.

函数定义同时描述了函数的参数列表和函数体(当函数被调用时所执行的语句) ,参数列表有两种可以接受的形式。K&R 风格用一个单独的列表说明参数的类型,它出现在函数体的左花括号之前。新式风格(也是现在提倡的那种)则直接在参数列表中包含了参数的类型。如果函数体内没有

任何语句,那么该函数就称为存根,它在测试不完整的程序时非常有用。


A function declaration gives limited information about a function, and is used where the function is called. There are two acceptable forms for function declarations. The K&R style, with no parameter list, only declares the type of value returned by the function. The new style, which is preferred, is called a function prototype. It includes declarations of the types of the parameters as well, which allows the compiler to check the types and number of arguments in calls to the function. You can also put parameter names in a function prototype as well. While optional, this practice makes the prototype more useful for other readers because it conveys more information.Prototypes for functions without parameters have just the keyword void as a parameter list. The preferred way to use function prototypes is to put the prototype in a separate file which is then #includeʹd wherever the prototype is needed. This technique minimizes the number of separate copies of the prototype that are needed,which simplifies maintenance.

函数声明给出了和一个函数有关的有限信息,当函数被调用时就会用到这些信息。函数声明也有两种可以接受的形式。K&R 风格没有参数列表,它只是声明了函数返回值的类型。目前所提倡的新风格又称为函数原型,除了返回值类型之外,它还包含了参数类型的声明,这就允许编译器在调用函数时检查参数的数量和类型。你也可以把参数名放在函数的原型中,尽管不是必需,但这样做可以使原型对于其他读者更为有用,因为它传递了更多的信息。对于没有参数的函数,它的原型在参数列表中有一个关键字void。常见的原型使用方法是把原型放在一个单独的文件中,当其他源文件需要这个原型时,就用#include 指令把这个文件包含进来。这个技巧可以使原型必需的拷贝份数降到最低,有助于提高程序的可维护性。


The return statement is used to specify the value to be returned from a function. If no value is given in the return statement, or if a function does not contain any return statements, no value will be returned. Such functions are called in many other languages. In ANSI C, function that do not return a value should be declared as returning the type void.

return 语句用于指定从一个函数返回的值。如果return 语句没有包含返回值,或者函数不包含任何return 语句 ,那么函数就没有返回值。在许多其他语言中,这类函数被称为过程。在ANSI C中,没有返回值的函数的返回类型应该声明为void 。


If a function it is called before any declarations for it have been seen, the compiler assumes that the function returns an integer value. It is important to declare functions that return nonintegral types in order to avoid errors caused by unexpected type conversions. Arguments to functions that are not prototyped under go the default argument promotions: char and short arguments are converted to int, and float arguments are converted to double.

当一个函数被调用时,编译器如果无法看到它的任何声明,那么它就假定函数返回一个整型值。对于那些返回值不是整型的函数,在调用之前对它们进行声明是非常重要的,这可以避免由于不可预测的类型转换而导致的错误。对于那些没有原型的函数,传递给函数的实参将进行缺省参数提升

char 和short 类型的实参被转换为int 类型, float 类型的实参被转换为double 类型。


Arguments to functions are passed call by value, which makes a copy of each argument. A function can therefore modify its parameters (the copies) without affecting the callerʹs arguments. Array names are also passed using call by value, but all that is copied is a pointer to the callerʹs array. When a subscript is used on the array parameter in the function, indirection causes an element in the callerʹs array to be accessed. Thus, modifying an array element in the function actually modifies the callerʹs array. This behavior is named call by reference. You can get call by reference semantics with scalar arguments by passing pointers to the arguments and using indirection in the function to access or modify the values.

函数的参数是通过传值方式进行传递的,它实际所传递的是实参的一份拷贝。因此,函数可以修改它的形参(也就是实参的拷贝),而不会修改调用程序实际传递的参数。数组名也是通过传值方式传递的,但它传给函数的是一个指向该数组的指针的拷贝。在函数中,如果在数组形参中使用了下标引用操作,就会引发间接访问操作,它实际所访问的是调用程序的数组元素。因此,在函数中修改参数数组的元素实际上修改的是调用程序的数组。这个行为被称为传址调用。如果你希望在传递标量参数时也具有传址调用的语义,你可以向函数传递指向参数的指针,并在函数中使用间接访

问来访问或修改这些值。


An abstract data type, or black box, consists of an interface and an implementation. The interface, which is public, specifies how a client uses the functionality provided by the ADT. The implementation, which is private, is where the work is actually done. Keeping the implementation private prevents clients from making their programs dependent on details of the implementation. The implementation can then be changed when necessary without affecting the clientsʹcode.

抽象数据类型,或称黑盒,由接口和实现两部分组成。接口是公有的,它说明客户如何使用ADT所提供的功能。实现是私有的,是实际执行任务的部分。将实现部分声明为私有可以访止客户程序依赖于模块的实现细节。这样,当需要的时候,我们可以对实现进行修改,这样做并不会影响客户程序的代码。


A recursive function is one that calls itself, either directly or indirectly. For recursion to work, each invocation of the function must make some progress toward a goal. When the goal is reached, no more recursive calls are made. To read a recursive function, do not get hung up on tracing each recursive call. It is easier to understand what is happening if you simply assume that the recursive call performs the work that it claims to do.

递归函数直接或间接地调用自身。为了使递归能顺利进行,函数的每次调用必须获得一些进展,进一步靠近目标。当达到目标时,递归函数就不再调用自身。在阅读递归函数时,不必纠缠于递归调用的内部细节。你只要简单地认为递归函数将会执行它的预定任务即可。


Some functions that are described recursively, such as factorial and Fibonacci numbers, can be implemented more efficiently iteratively. When a recursive call is the last thing that is done in a function, it is called tail recursion. Tail recursion can easily be converted to a loop, which is usually more efficient.

有些函数是以递归形式进行描述的,如阶乘和菲波那契数列,但它们如果使用迭代方式来实现,效率会更高一些。如果一个递归函数内部所执行的最后一条语句就是调用自身时,那么它就被称为尾部递归。尾部递归可以很容易地改写为循环的形式,它的效率通常更高一些。


Functions with argument lists containing variable numbers and types of arguments can be implemented using the macros defined in the stdarg.h header. The varying portion of the parameter list, which follows one or more ordinary (named)parameters, is indicated with an elipsis in the function prototype. The named parameter(s) must somehow indicate the number of arguments passed in the varying part and, if not known in advance, their types. The arguments in the varying portion of the list undergo the default argument promotions when they are passed, and they can only be accessed in order from first to last.

有些函数的参数列表包含可变的参数数量和类型,它们可以使用stdarg.h 头文件所定义的宏来实现。参数列表的可变部分位于一个或多个普通参数(命名参数)的后面,它在函数原型中以一个省略号表示。命名参数必须以某种形式提示可变部分实际所传递的参数数量,而且如果预先知道的话,也可以提供参数的类型信息。当参数列表中可变部分的参数实际传递给函数时,它们将经历缺省参数提升。可变部分的参数只能从第1 个到最后1 个依次进行访问。

上一章 Pointers on C——7 Functions.9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Chapter 1 Chapter 2 Chapter 3 Chapter 4 Chapter 5 Chapter 6 Chapter 7 Chapter 8 Chapter 9 Chapter 10 Chapter 11 Chapter 12 Chapter 13 Chapter 14 Chapter 15 Chapter 16 Chapter 17 Chapter 18 Contents A Quick Start ........................................................................................................ 1 Basic Concepts ...................................................................................................... 7 Data ....................................................................................................................... 11 Statements ............................................................................................................. 15 Operators and Expressions .................................................................................... 23 Pointers .................................................................................................................. 29 Functions ............................................................................................................... 37 Arrays .................................................................................................................... 43 Strings, Characters, and Bytes .............................................................................. 55 Structures and Unions ........................................................................................... 69 Dynamic Memory Allocation ................................................................................ 75 Using Structures and Pointers ............................................................................... 79 Advanced Pointer Topics ...................................................................................... 87 The Preprocessor ................................................................................................... 93 Input/Output Functions .......................................................................................... 95 Standard Library .................................................................................................... 119 Classic Abstract Data Types ................................................................................. 129 Runtime Environment ........................................................................................... 145

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值