@
GeruzoniAnsasu 还有一个无视历史行程的流毒甚广的基本理解偏差单独挑出来说。
形式参数的“形式”跟“类型”无关。使用显式类型的语言才在函数的类型声明顺带形式参数的声明,因为决定函数类型的类型构造器(→)要求已知参数类型,不在函数声明中提供,还是要在其它位置明确,才可能允许函数类型检查。
这个节点里照日常使用,姑且都能算是这样的语言,但严格讲,C 就不强制——函数原型声明是可选的,不要求总是具有函数参数类型:
比如 int main() ,你拿 GCC 去调用 main(什么乱七八糟) 可能都过得去,Clang 倒是仍然会检查,但也不同于 int main(void) ;
其它用法参见 K&R C 古董代码。
不使用显式类型的语言里函数的绑定变量一般意义下也叫做形式参数,只不过“参数(parameter)”在某些情况有其它含义( Lisp 方言使用参数作为动态作用域的变量,纯函数式语言使用参数表示类似 C++的模板类型参数的参数多态的类型变量),所以不怎么单独提出来说而已。这样的函数形式参数的所谓类型,可能是不需要明确把类型写出来而确定的(如 Haskell 这样默认就鼓励使用类型推断(type inference) 确定的语言),也可能因为变量不存在确定的类型而根本不存在(如 Scheme 这样使用清单类型(manifest typing) 的语言)。
最后回答 LZ 的问题。一般地,使用实际参数(actual argument) 初始化函数的形式参数(formal parameter) ,在函数被调用——带有作为操作符的函数以及函数的实际参数的后置表达式被求值时——发生。
对这个节点讨论的语言,函数这个特性(排除宏这种更一般意义上的“函数”)对实际参数的求值总是使用原始的应用序(applicative order) ,即函数的实际参数先于函数体被求值(但注意,不同实际参数之间没有“最左”的保证),因此(借用 C++11 和 C11 照抄 C++11 的概念)初始化总是后序于(sequenced after) 函数调用的实际参数求值之后。
一般地,函数的形式参数(formal parameter) 在