题目

编写程序,设计带多个参数的计算函数。严格遵循 C++ 标准规则:默认参数必须从右至左连续给出;演示函数声明(Declaration)与函数定义(Definition)分离时,默认参数只能且必须写在声明中,若在定义中重复指定默认实参将引发编译器重复定义报错。

输入格式:无需外部输入。

输出格式:输出使用全部默认参、部分默认参及全传参的调用结果。

数据范围与约定:函数声明规范与编译器符号解析。

思路与算法

1. 靠右连续性规则
一旦某个形参指定了默认值,其右侧的所有形参都必须带有默认实参,否则调用时实参与形参无法进行歧义消除匹配。

2. 声明与定义分离
在头文件/前置声明中指定默认值后,.cpp 源码或后续定义处不可再次赋予默认值。因为编译器在调用点仅根据声明进行语法检查并补全实参代码。

3. 虚函数默认参数陷阱
若在面向对象中重写带默认参数的虚函数,默认参数是由静态类型(声明类型)决定的,而非动态运行时类型,这是 C++ 的经典认知陷阱之一。

完整程序

#include <iostream>

// 1. 函数前置声明:默认实参在此处统一定义
int calcVolume(int length, int width = 5, int height = 2);

// 2. 函数实际实现:切勿在形参列表中重复写入 "= 5" 或 "= 2"
int calcVolume(int length, int width, int height) {
    return length * width * height;
}

int main() {
    // 调用 1:全使用默认参数(只传必要参数 length=10)
    int v1 = calcVolume(10);
    std::cout << "calcVolume(10) [宽高取默认 5, 2]: " << v1 << "\n";

    // 调用 2:覆盖 width,height 保持默认
    int v2 = calcVolume(10, 8);
    std::cout << "calcVolume(10, 8) [高取默认 2]: " << v2 << "\n";

    // 调用 3:完全显式传参
    int v3 = calcVolume(10, 8, 4);
    std::cout << "calcVolume(10, 8, 4) [全指定]: " << v3 << "\n";

    return 0;
}

运行示例

输出:

calcVolume(10) [宽高取默认 5, 2]: 100
calcVolume(10, 8) [高取默认 2]: 160
calcVolume(10, 8, 4) [全指定]: 320