|
User-defined Functions
Complicated
Syntax of Function Definitions
Definitions of functions can appear anywhere between the rules of the
The definition of a function named name looks like this:
function name (parameter-list) { body-of-function } name is the name of the function to be defined. A valid function name is like a valid variable name: a sequence of letters, digits and underscores, not starting with a digit. Functions share the same pool of names as variables and arrays. parameter-list is a list of the function's arguments and local variable names, separated by commas. When the function is called, the argument names are used to hold the argument values given in the call. The local variables are initialized to the null string.
The body-of-function consists of Argument names are not distinguished syntactically from local variable names; instead, the number of arguments supplied when the function is called determines how many argument variables there are. Thus, if three argument values are given, the first three names in parameter-list are arguments, and the rest are local variables. It follows that if the number of arguments is not the same in all calls to the function, some of the names in parameter-list may be arguments on some occasions and local variables on others. Another way to think of this is that omitted arguments default to the null string. Usually when you write a function you know how many names you intend to use for arguments and how many you intend to use as locals. By convention, you should write an extra space between the arguments and the locals, so other people can follow how your function is supposed to be used.
During execution of the function body, the arguments and local variable
values hide or shadow any variables of the same names used in the
rest of the program. The shadowed variables are not accessible in the
function definition, because there is no way to name them while their
names have been taken away for the local variables. All other variables
used in the The arguments and local variables last only as long as the function body is executing. Once the body finishes, the shadowed variables come back. The function body can contain expressions which call functions. They can even call this function, either directly or by way of another function. When this happens, we say the function is recursive.
There is no need in
In many
func foo() { a = sqrt($1) ; print a }
Instead it defines a rule that, for each record, concatenates the value
of the variable func with the return value of the function foo,
and based on the truth value of the result, executes the corresponding action.
This is probably not what was desired. (
Function Definition Example
Here is an example of a user-defined function, called
function myprint(num) { printf "%6.3g\n", num }
To illustrate, here is an
$3 > 0 { myprint($3) }
This program prints, in our special format, all the third fields that contain a positive number in our input. Therefore, when given:
1.2 3.4 5.6 7.8 9.10 11.12 -13.14 15.16 17.18 19.20 21.22 23.24 this program, using our function to format the results, prints:
5.6 21.2 Here is a rather contrived example of a recursive function. It prints a string backwards:
function rev (str, len) { if (len == 0) { printf "\n" return } printf "%c", substr(str, len, 1) rev(str, len - 1) }
Calling User-defined FunctionsCalling a function means causing the function to run and do its job. A function call is an expression, and its value is the value returned by the function.
A function call consists of the function name followed by the arguments
in parentheses. What you write in the call for the arguments are
foo(x y, "lose", 4 * z)
Caution: whitespace characters (spaces and tabs) are not allowed
between the function name and the open-parenthesis of the argument list.
If you write whitespace by mistake,
When a function is called, it is given a copy of the values of its arguments. This is called call by value. The caller may use a variable as the expression for the argument, but the called function does not know this: it only knows what value the argument had. For example, if you write this code:
foo = "bar" z = myfunc(foo)
then you should not think of the argument to
If the function
function myfunc (win) { print win win = "zzz" print win }
to change its first argument variable However, when arrays are the parameters to functions, they are not copied. Instead, the array itself is made available for direct manipulation by the function. This is usually called call by reference. Changes made to an array parameter inside the body of a function are visible outside that function. This can be very dangerous if you do not watch what you are doing. For example:
function changeit (array, ind, nvalue) { array[ind] = nvalue }
prints a[1] = 1, a[2] = two, a[3] = 3, because calling
The
|