什么是形式参数?

30

在C++编译时,我经常会遇到涉及“形式参数”的错误消息,例如:

error C2719: 'b': formal parameter with __declspec(align('16')) won't be aligned

我了解错误,以及b是我定义的一个函数的参数。
然而,参数“形式”的含义是什么?是否也可以有“非正式”的参数?
我注意到术语“形式参数”在其他语言中也出现过,因此我认为它是一个更通用的术语,不一定特定于C系列语言?一些子集语言是否支持非正式参数?
阅读答案后,最后一个问题:这些名称“形式参数”和“实参”来自哪里?它起源于C标准,还是由于在某些抽象语言演算中称之为如此而产生的影响?

在这种情况下,它意味着您正在尝试向函数传递超过三个SSE参数,并且您被困在Visual Studio和WIN32 ABI中。;-) - Paul R
@Paul R:在这种情况下,我传递的是一个对齐参数,而不是const& - CygnusX1
3
关于名称的来源:在数学中,“正式”并不是“非正式”的相反词。“正式”源于“形式”,即“正式”意味着定义明确。例如,正式逻辑并不是非正式逻辑的相反,而是基于定义明确规则的逻辑。因此,形式参数指的是定义函数形式的参数。实际参数则显而易见。 - Shahbaz
但是相反的是什么呢?“没有明确定义”吗?我猜这会把讨论转移到语言方面,所以...算了! - CygnusX1
3个回答

45

形式参数和实际参数:

void foo(int arg); //arg is a formal parameter

int main()
{
    int val = 1;
    foo(val);  //val is an actual parameter
}

来自C++标准:

1.3.1 形式参数 (parameter)

在函数声明或定义中作为一部分声明的对象或引用,或者在异常处理程序的catch子句中声明的对象或引用,在进入函数或处理程序时获得值。 在类似函数的宏定义中,是紧随宏名称后面的括号内由逗号分隔的列表中的标识符;或者是模板参数。 参数也称为形式参数或形参。

1.3.10 实际参数 (argument)

函数调用表达式中由括号界定的逗号分隔列表中的表达式,在类似函数的宏调用中由括号界定的逗号分隔的预处理符号序列,throw 的操作数,或者在由尖括号界定的逗号分隔列表中的表达式、类型id或模板名中的一个。实际参数也称为实参或实际参数。


18
需要注意的是,C标准已经弃用了“形式参数”和“实际参数”这些术语。正确的术语应该是“参数”和“参数值”。 - R.. GitHub STOP HELPING ICE
@R.. 但我相信它们在其他语言中仍然可以使用?这是什么来源? - CygnusX1
源自C标准,C99中的3.3和3.15。 - R.. GitHub STOP HELPING ICE
我的意思是,这个命名在标准中使用的来源和原因是什么。似乎C标准的作者并没有发明这个命名,而是在此之前就已经存在了。他们只是明确地重新定义了它以供C使用。 - CygnusX1

17

形式参数是在函数定义时已知的参数。实际参数是在调用函数时传递给函数的参数(因此得名“实际”)。

void foo( int a ); // a is a formal parameter

foo(10); // 10 is the actual parameter

1
我认为传递给函数的东西是“参数”,而函数拥有的东西是“形参”? - CygnusX1

9

这只是术语上的一点小小的追求,但非常有用:形式参数就是你所想的函数参数:

int foo(bool a, float b);

这里的ab是形式参数。关键在于,在函数体中,您在“正式”地引用这些参数,而实际上并不知道它们的值。只有当您实际评估函数调用表达式时,形式函数参数才会绑定到函数调用参数:

int result = foo(false, 1.5);

在此调用表达式中,第一个参数的值false绑定到形参a,第二个参数类似。
对于语言设计师和编译器编写者来说,参数和参数的区别可能更为重要,但在C++中,作为示例,当您试图遵循模板参数推断规则时,了解这一点可以非常有帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接