awk 函数参数

awk 函数参数

我无法理解 gawk 函数参数的使用。通常,参数定义函数的局部变量。

但是参数可以用作函数可以使用的输入吗?

已经看到它的使用return实际上可以通过调用返回一个值

val=myfunc()

当您仍然可以访问全局变量时,将全局值作为输入参数传递给函数有什么好处?

答案1

你的问题是基于一个错误的前提。

通常,参数定义函数的局部变量。

不会。通常,参数为传递到函数的值定义变量名称。

awk没有能力声明局部范围的变量。但由于所有函数参数都是可选的,因此使用变量重载函数参数列表被认为是可接受的做法,这些变量除了可以在函数中本地使用之外没有其他用途。

因此,您的问题的答案是“是”:变量可用于将值传递给函数。

例如,

awk '
    function factorial(n) { return n>1 ? n*factorial(n-1) : 1 }
    BEGIN { print factorial(5) }
'

此处,该函数每次使用不同的值调用自身(前 5 个,然后递减值 4、3、2)。尝试为此使用全局变量将非常困难。

答案2

另请注意,函数的标量参数是按值传递的,但数组参数是按引用传递的。因此,该函数可以将调用代码中声明的数组值更改为该函数,从而返回多个值。

这包括在数组参数中创建新元素的能力,即使它最初是作为空数组传入的。

假设我想要一个接受两个数字的函数,并且想要输出两个变量值,一个包含总和,另一个包含平均值。一个人能做什么呢?

人们可以做到这一点:它证明了同名数组存在全局和局部作用域,它们可以具有不同的长度并包含不同的数据,并且数组是通过引用传递的并且可以返回多个值。

#! /bin/bash

Awk='
#.. Define and fill an array X at global scope.
BEGIN { X[1] = 45; X[2] = 98; }
#.. Function that fills in a result array (passed by reference).
function Math (X, v1, v2) {
    X[1] = v1 + v2; X[2] = (v1 + v2) / 2; X[3] = v1 * v2;
}
#.. Function that declares an array X at local scope, and reports it.
function Wrapper (a, b,      X, j) {
    Math( X, a, b);
    for (j = 1; j in X; ++j) printf ("Local X[%d] is %f\n", j, X[j]);
}
{ 
    Wrapper( $1, $2);
    #.. Prove that the Global X is unaffected, in length or content.
    for (j = 1; j in X; ++j) printf ("Global X[%d] is %f\n", j, X[j]);
}
'   
    echo 3.5 2.7 | awk "${Awk}"
$ ./Heime.awk
Local X[1] is 6.200000
Local X[2] is 3.100000
Local X[3] is 9.450000
Global X[1] is 45.000000
Global X[2] is 98.000000 

GNU Awk 运行得很好——它在第一次访问 X 时决定 X 的类型。nawk(Solaris Awk) 似乎在它被传入时做出了这个决定(并且可能会导致 SegViol)。

为了确保nawk通过引用将 X 传递到函数中,您可能需要在传递之前将其显式创建为零长度数组,方法是使用零长度模式拆分零长度字符串:

    split ("", X, ""); Math( X, a, b);

答案3

当您仍然可以访问全局变量时,将全局值作为输入参数传递给函数有什么好处?

与任何编程语言中的任何函数相同:您每次都可以传递不同的(全局)变量,并且该函数不需要知道完成其工作不需要的事情。

举一个简单的例子:

function sum(a,b) { return a+b; }

{ partial = sum($2, $3); }
$1 == 0 { print sum(partial, $4); }
$1 != 0 { print sum(partial, $5); }

想象一个更复杂的函数来代替sum(),这样在两个分支中复制它就不再有意义了。

相关内容