函数调用
函数调用 是一个用于将控制权和参数(如果有)传递给函数的表达式,格式如下:
expression (expression-listopt)
其中 expression 是一个函数名称或者其计算结果为函数地址,而 expression-list 是表达式的列表(以逗号分隔)。 后面这些表达式的值是传递给函数的自变量。 如果函数未返回值,则将其声明为返回 void
的函数。
如果在函数调用之前存在声明,但未提供任何与参数有关的信息,则任何未声明的参数只需进行常用算术转换。
注意
函数参数列表中的表达式可以任何顺序进行计算,因此其值可能受其他参数的副作用而更改的参数具有未定义的值。 函数调用运算符定义的序列点仅保证在将控制权传递给所调用函数之前计算参数列表中的所有副作用。 (请注意,在堆栈上推送自变量的顺序是另一回事。)有关详细信息,请参阅序列点。
所有函数调用中的唯一要求是,括号前的表达式的计算结果必须是函数地址。 这意味着可通过任何函数指针表达式调用函数。
示例
此示例说明了通过 switch
语句调用的函数调用:
int main()
{
/* Function prototypes */
long lift( int ), step( int ), drop( int );
void work( int number, long (*function)(int i) );
int select, count;
.
.
.
select = 1;
switch( select )
{
case 1: work( count, lift );
break;
case 2: work( count, step );
break;
case 3: work( count, drop );
/* Fall through to next case */
default:
break;
}
}
/* Function definition */
void work( int number, long (*function)(int i) )
{
int i;
long j;
for ( i = j = 0; i < number; i++ )
j += ( *function )( i );
}
在此示例中,main
中的函数调用
work( count, lift );
将整数变量 count
和函数 lift
的地址传递给函数 work
。 请注意,由于函数标识符的计算结果是一个针表达式,因此通过提供函数标识符即可传入函数地址。 若要通过此方式使用函数标识符,必须在使用标识符前先声明或定义函数;否则,将不会识别标识符。 在此示例中,work
的原型在 main
函数的开头处提供。
work
中的参数 function
被声明为指向函数的指针,此函数采用一个 int
参数,并返回 long
值。 参数名称两边的括号是必需的;如果没有括号,声明会指定函数,此函数返回指向 long
值的指针。
函数 work
使用以下函数调用从 for
循环内部调用所选函数:
( *function )( i );
一个参数 i
将传递给所调用的参数。