鱼C论坛

 找回密码
 立即注册
查看: 592|回复: 6

[已解决]C++第6节课后作业疑问

[复制链接]
发表于 2023-6-10 00:06:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
小甲鱼老师要求写一个calc的函数
当传入1个参数的时候,返回它的平方
2个的时候,返回它俩相乘
3个的时候,返回它们3个相加

然后我写的代码如下:
#include <iostream>
#include <math.h>

double calc(double a1, double a2, double a3);

int main(int argc, const char *argv[], const char *envp[])
{
    double a1, a2, a3;
    int judge;
    double answer;

    std::cout << "请问要输入几个数? " << std::endl;
    std::cin >> judge;

    switch(judge)
    {
        case 1:
        {
            std::cin >> a1;
            answer = calc(a1);
            break;
        }
        case 2:
        {
            std::cin >> a1 >> a2;
            answer = calc(a1, a2);
            break;
        }
        case 3:
        {
            std::cin >> a1 >> a2 >> a3;
            answer = calc(a1, a2, a3);
            break;
        }
        default :
        {
            std::cout << "输入错误, 请重试! " << std::endl;
            break;
        }
    }

    std::cout << "计算后的值为: " << answer << std::endl;

    system("pause");
    return 0;
}

double calc(double a1)
{
    return pow(a1, 2);
}

double calc(double a1, double a2)
{
    return a1 * a2;
}

double calc(double a1, double a2, double a3)
{
    return a1 + a2 + a3;
}

编译的时候报错
test02.cpp: In function 'int main(int, const char**, const char**)':
test02.cpp:28:26: error: too few arguments to function 'double calc(double, double, double)'
   28 |             answer = calc(a1);
      |                      ~~~~^~~~
test02.cpp:12:8: note: declared here
   12 | double calc(double a1, double a2, double a3);
      |        ^~~~
test02.cpp:34:26: error: too few arguments to function 'double calc(double, double, double)'
   34 |             answer = calc(a1, a2);
      |                      ~~~~^~~~~~~~
test02.cpp:12:8: note: declared here
   12 | double calc(double a1, double a2, double a3);
      |        ^~~~

它的意思是说我声明函数的时候是3个参数,然后前两次调用都是1个,2个参数,不够。但是小甲鱼老师有讲说,可以根据参数的数量、类型进行重载,所以是可以根据1~3个参数来重载的呀。搞不懂了,百度说什么的都有,问问各位大神了。
最佳答案
2023-6-10 00:08:05
你的代码在大致上的逻辑是正确的,但是有一个小错误导致你不能正确编译。在你的代码中,你提前声明了  calc  函数是带有三个参数的,然后在后面你实现了三个参数的版本,但是你没有为只有一个或者两个参数的情况提前声明函数。

你需要在你的代码开始处声明所有的重载版本,而不仅仅是三个参数的版本,这样你的代码就能正确编译了。

修改后的代码如下:
#include <iostream>
#include <math.h>

double calc(double a1);                   // 声明只有一个参数的版本
double calc(double a1, double a2);        // 声明有两个参数的版本
double calc(double a1, double a2, double a3);   // 声明有三个参数的版本

int main(int argc, const char *argv[], const char *envp[])
{
    double a1, a2, a3;
    int judge;
    double answer;

    std::cout << "请问要输入几个数? " << std::endl;
    std::cin >> judge;

    switch(judge)
    {
        case 1:
        {
            std::cin >> a1;
            answer = calc(a1);
            break;
        }
        case 2:
        {
            std::cin >> a1 >> a2;
            answer = calc(a1, a2);
            break;
        }
        case 3:
        {
            std::cin >> a1 >> a2 >> a3;
            answer = calc(a1, a2, a3);
            break;
        }
        default :
        {
            std::cout << "输入错误, 请重试! " << std::endl;
            break;
        }
    }

    std::cout << "计算后的值为: " << answer << std::endl;

    system("pause");
    return 0;
}

double calc(double a1)
{
    return pow(a1, 2);
}

double calc(double a1, double a2)
{
    return a1 * a2;
}

double calc(double a1, double a2, double a3)
{
    return a1 + a2 + a3;
}
这样你的函数重载就可以正确工作了。函数重载就是让同一个函数名称有多个实现版本,每个版本根据它的参数类型和数量的不同来区分。在你的代码中,你只声明了一个版本,这就是你的问题所在。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-6-10 00:07:39 | 显示全部楼层
根据您提供的代码,您的重载函数声明和定义是正确的。然而,编译器报错说在main函数中调用该函数时缺少参数。这是因为您重载的函数需要在调用时告诉编译器使用哪个函数,但在case 1和case 2中只使用了一个或两个参数来调用函数,而没有告诉编译器应该使用哪个函数。

为解决此问题,您可以在case 1和case 2中使用具有相同名称的不同函数,例如:
double calc(double a1);
double calc(double a1, double a2);
double calc(double a1, double a2, double a3);

double calc(double a1)
{
    return pow(a1, 2);
}

double calc(double a1, double a2)
{
    return a1 * a2;
}

double calc(double a1, double a2, double a3)
{
    return a1 + a2 + a3;
}

int main(int argc, const char *argv[], const char *envp[])
{
    double a1, a2, a3;
    int judge;
    double answer;

    std::cout << "请问要输入几个数? " << std::endl;
    std::cin >> judge;

    switch(judge)
    {
        case 1:
        {
            std::cin >> a1;
            answer = calc(a1);
            break;
        }
        case 2:
        {
            std::cin >> a1 >> a2;
            answer = calc(a1, a2);
            break;
        }
        case 3:
        {
            std::cin >> a1 >> a2 >> a3;
            answer = calc(a1, a2, a3);
            break;
        }
        default :
        {
            std::cout << "输入错误, 请重试! " << std::endl;
            break;
        }
    }

    std::cout << "计算后的值为: " << answer << std::endl;

    system("pause");
    return 0;
}
这样可以确保具有正确参数数量和类型的函数被调用。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-10 00:08:05 | 显示全部楼层    本楼为最佳答案   
你的代码在大致上的逻辑是正确的,但是有一个小错误导致你不能正确编译。在你的代码中,你提前声明了  calc  函数是带有三个参数的,然后在后面你实现了三个参数的版本,但是你没有为只有一个或者两个参数的情况提前声明函数。

你需要在你的代码开始处声明所有的重载版本,而不仅仅是三个参数的版本,这样你的代码就能正确编译了。

修改后的代码如下:
#include <iostream>
#include <math.h>

double calc(double a1);                   // 声明只有一个参数的版本
double calc(double a1, double a2);        // 声明有两个参数的版本
double calc(double a1, double a2, double a3);   // 声明有三个参数的版本

int main(int argc, const char *argv[], const char *envp[])
{
    double a1, a2, a3;
    int judge;
    double answer;

    std::cout << "请问要输入几个数? " << std::endl;
    std::cin >> judge;

    switch(judge)
    {
        case 1:
        {
            std::cin >> a1;
            answer = calc(a1);
            break;
        }
        case 2:
        {
            std::cin >> a1 >> a2;
            answer = calc(a1, a2);
            break;
        }
        case 3:
        {
            std::cin >> a1 >> a2 >> a3;
            answer = calc(a1, a2, a3);
            break;
        }
        default :
        {
            std::cout << "输入错误, 请重试! " << std::endl;
            break;
        }
    }

    std::cout << "计算后的值为: " << answer << std::endl;

    system("pause");
    return 0;
}

double calc(double a1)
{
    return pow(a1, 2);
}

double calc(double a1, double a2)
{
    return a1 * a2;
}

double calc(double a1, double a2, double a3)
{
    return a1 + a2 + a3;
}
这样你的函数重载就可以正确工作了。函数重载就是让同一个函数名称有多个实现版本,每个版本根据它的参数类型和数量的不同来区分。在你的代码中,你只声明了一个版本,这就是你的问题所在。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-10 00:09:44 | 显示全部楼层
isdkz 发表于 2023-6-10 00:08
你的代码在大致上的逻辑是正确的,但是有一个小错误导致你不能正确编译。在你的代码中,你提前声明了  calc ...

课堂演示中,两个参数在声明的时候都是double类型,重载的时候将其中一个改成了int,编译没报错,但是是不是都要重新声明一下会比较好?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-10 00:11:01 | 显示全部楼层
铭凡 发表于 2023-6-10 00:09
课堂演示中,两个参数在声明的时候都是double类型,重载的时候将其中一个改成了int,编译没报错,但是是 ...

在C++中,函数重载的关键是函数的参数类型和/或参数数量不同,函数的返回类型并不影响函数重载的判断。你可以定义两个参数类型或数量不同的函数,即使它们的返回类型相同,编译器也会将它们视为两个不同的函数。

但是,如果你要更改已经声明的函数的参数类型,你必须重新声明这个函数。如果你不重新声明,那么当你在调用这个函数时,编译器将会使用最初的声明,这可能会导致错误。

例如,如果你已经声明了这样的一个函数:
void func(double a, double b);

然后你在实现这个函数时更改了一个参数的类型:
void func(double a, int b) {
  // ...
}

那么当你在代码中调用  func(1.0, 2)  时,编译器会报错,因为它在寻找两个参数都是  double  类型的函数,而你给出的函数是一个  double  类型和一个  int  类型的参数。

所以,如果你要更改已经声明的函数的参数类型或数量,你应该重新声明这个函数,这样编译器才能正确的找到你实现的函数。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-10 00:13:02 | 显示全部楼层
isdkz 发表于 2023-6-10 00:11
在C++中,函数重载的关键是函数的参数类型和/或参数数量不同,函数的返回类型并不影响函数重载的判断。你 ...

明白啦。两次都是老哥解决的问题,非常感谢!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-10 00:13:32 | 显示全部楼层
铭凡 发表于 2023-6-10 00:13
明白啦。两次都是老哥解决的问题,非常感谢!!!

不客气
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-28 01:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表