函数的调用形式

一、函数调用前的声明要求

函数在调用之前需要先声明。函数的定义本身就是一种声明,因此如果在调用点之前已经定义了函数,就可以直接调用。

如果需要在函数定义之前调用它,则必须在调用之前添加该函数的函数原型声明。

函数原型声明格式:

类型说明符 函数名(形参表);

注意:声明中的形参表可以只写类型,省略形参名,但建议保留形参名以提高可读性。

二、函数调用的语法形式

函数名(实参列表);

实参列表中应给出与函数原型中形参个数相同、类型相符的实参。每个实参都是一个表达式(可以是常量、变量、运算式或函数调用)。

三、函数调用的执行过程

  1. 计算实参表达式的值。
  2. 将实参的值按位置依次传递给形参(值传递)。
  3. 程序流程跳转到被调函数的函数体开始执行。
  4. 被调函数执行到 return 语句或函数体结束时,返回主调函数,如果有返回值则将返回值带回。

四、值传递的特点

C++ 中默认的参数传递方式是值传递。实参的值被复制给形参,形参是函数内部的局部变量。形参的改变不会影响实参。

void fun(int a);
int main()
{
    int b = 2;
    fun(b);      // 把 b 的值(2)复制给形参 a
    return 0;
}
void fun(int a)
{
    a += 1;      // 只修改了局部变量 a,b 的值不变
}Code language: JavaScript (javascript)

五、代码示例

以下代码演示了函数声明、定义和调用的完整过程:

#include <iostream>
using namespace std;

// 函数原型声明(在 main 之前)
void fun(int a);
int power(int x, int n);

int main()
{
    int b = 2;
    fun(b);                     // 调用 fun,实参为变量 b
    cout << "b = " << b << endl; // b 的值仍然是 2

    int n = 3;
    cout << b << " 的 " << n << " 次方 = " << power(b, n) << endl;

    // 实参可以是表达式
    cout << "2 的 5 次方 = " << power(2, 5) << endl;
    cout << "3+1 的 4 次方 = " << power(3 + 1, 4) << endl;

    return 0;
}

// 函数定义(在 main 之后)
void fun(int a)
{
    a += 1;
    if (true)
    {
        return;     // 提前结束函数
    }
    // 下面的代码不会执行
    a += 100;
}

// 求 x 的 n 次方
int power(int x, int n)
{
    int r = 1;
    while (n-- != 0)
    {
        r *= x;
    }
    return r;
}Code language: PHP (php)

六、函数调用的多种形式

根据函数是否有返回值、是否在表达式中使用,函数调用有以下几种形式:

1. 作为独立语句(忽略返回值)
printHello();          // void 函数调用
fun(10);               // 有返回值但忽略Code language: JavaScript (javascript)
2. 作为表达式的一部分
int result = power(2, 3) + 1;   // 参与运算
cout << power(5, 2);            // 作为输出内容Code language: JavaScript (javascript)
3. 作为其他函数的实参
int x = power(power(2, 2), 3);  // power(2,2) 的返回值作为实参Code language: JavaScript (javascript)
4. 在条件或循环语句中
if (isPrime(17)) { ... }
while (getValue() > 0) { ... }Code language: JavaScript (javascript)

七、注意事项

  • 函数调用时实参个数必须与形参个数一致,类型应兼容(编译器会尝试隐式转换)。
  • 函数原型声明中的形参名可以与定义中的形参名不同,编译器只检查类型。
  • 值传递方式下,形参和实参占用不同的内存空间,修改形参不影响实参。
  • 如果需要在函数中修改实参的值,需要使用引用传递或指针传递(后续章节介绍)。
  • 函数可以调用自身,称为递归调用,但需设置终止条件。
  • main 函数不需要声明,由操作系统自动调用。

八、常见错误

1. 调用前未声明也未定义
int main()
{
    foo(3);     // 错误:foo 未声明
    return 0;
}
void foo(int x) { }Code language: JavaScript (javascript)

解决:在 main 之前添加 void foo(int); 或将 foo 定义移到 main 之前。

2. 实参类型不匹配
void print(int x);
print(3.14);    // 警告:double 到 int 截断Code language: PHP (php)
3. 实参个数不匹配
int add(int a, int b);
add(1);         // 错误:参数个数不足
add(1, 2, 3);   // 错误:参数个数过多Code language: JavaScript (javascript)
4. 忘记写函数调用的括号
power;          // 错误:这不是函数调用,而是函数指针
power(2, 3);    // 正确Code language: JavaScript (javascript)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注