鱼C论坛

 找回密码
 立即注册
查看: 918|回复: 4

[已解决]关于c语言函数指针作为参数的问题

[复制链接]
发表于 2023-7-18 17:20:15 | 显示全部楼层 |阅读模式

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

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

x
为什么我这代码可以正常打开,但是我输入5+1或者其他算式时,就立即报错?
#include <stdio.h>

int add(int, int);
int sub(int, int);
int calc(int (*p)(int, int), int, int);
int (*chose(char op))(int, int);

int add(int a, int b) {
        return a + b;
}
int sub(int a, int b) {
        return a - b;
}

int calc(int(*p)(int, int), int a, int b) {
        return (*p)(a, b);
}

int (*chose(char op))(int, int) {
        switch (op)
        {
        case '+':return add;
        case '-':return sub;
        default:
                break;
        }
}




int main() {
        int a, b;
        char c;
        int (*fuhao)(int, int);
        printf("请输入数学运算式:");
        scanf_s("%d%c%d", &a, &c, &b);
        fuhao = chose(c);
        printf("%d %c %d = %d", a, c, b, calc(fuhao, a, b));


        return 0;
}
屏幕截图 2023-07-18 171843.png
最佳答案
2023-7-18 17:20:34
你的代码出现错误的原因是在使用scanf_s函数时没有正确的传递参数。scanf_s函数用于读取用户输入,并且需要指定每个输入变量的最大接受字符数。

在你的代码中,第14行scanf_s函数的参数&c应该改成sizeof(c),以指定c变量允许接受的最大字符数为1。另外,第10行的函数声明中,可以省略参数名。修改后的代码如下所示:
#include <stdio.h>int add(int, int);int sub(int, int);int calc(int (*)(int, int), int, int);int (*chose(char op))(int, int);int add(int a, int b){  return a + b;}int sub(int a, int b){  return a - b;}int calc(int (*p)(int, int), int a, int b){  return (*p)(a, b);}int (*chose(char op))(int, int){  switch (op)  {    case '+':      return add;    case '-':      return sub;    default:      break;  }}int main(){  int a, b;  char c;  int (*fuhao)(int, int);  printf("请输入数学运算式:");  scanf_s("%d%c%d", &a, &c,sizeof(c));  fuhao = chose(c);  printf("%d %c %d = %d", a, c, b, calc(fuhao, a, b));  return 0;}
修改后的代码应该能够正确运行,允许你输入数学运算式并得到结果。希望对你有所帮助!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-7-18 17:20:34 | 显示全部楼层    本楼为最佳答案   
你的代码出现错误的原因是在使用scanf_s函数时没有正确的传递参数。scanf_s函数用于读取用户输入,并且需要指定每个输入变量的最大接受字符数。

在你的代码中,第14行scanf_s函数的参数&c应该改成sizeof(c),以指定c变量允许接受的最大字符数为1。另外,第10行的函数声明中,可以省略参数名。修改后的代码如下所示:
#include <stdio.h>int add(int, int);int sub(int, int);int calc(int (*)(int, int), int, int);int (*chose(char op))(int, int);int add(int a, int b){  return a + b;}int sub(int a, int b){  return a - b;}int calc(int (*p)(int, int), int a, int b){  return (*p)(a, b);}int (*chose(char op))(int, int){  switch (op)  {    case '+':      return add;    case '-':      return sub;    default:      break;  }}int main(){  int a, b;  char c;  int (*fuhao)(int, int);  printf("请输入数学运算式:");  scanf_s("%d%c%d", &a, &c,sizeof(c));  fuhao = chose(c);  printf("%d %c %d = %d", a, c, b, calc(fuhao, a, b));  return 0;}
修改后的代码应该能够正确运行,允许你输入数学运算式并得到结果。希望对你有所帮助!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-18 17:20:50 | 显示全部楼层
这个问题在于 chose 函数在不匹配'+'或者'-'时并没有返回一个有效的函数指针,这会导致调用 calc 函数时产生未定义行为。当你输入'5+1'或者其他合法的算式时, chose 函数会正常返回,但是如果输入不合法的运算符,比如输入'5x1', chose 函数就会在不返回任何值的情况下结束,从而引发错误。

一种解决方案是在 chose 函数的 default 分支中返回一个有效的函数指针,或者返回 NULL ,然后在使用这个函数指针之前进行检查。下面是代码的修订版本:
#include <stdio.h>int add(int, int);int sub(int, int);int calc(int (*p)(int, int), int, int);int (*chose(char op))(int, int);int add(int a, int b) {    return a + b;}int sub(int a, int b) {    return a - b;}int calc(int(*p)(int, int), int a, int b) {    return (*p)(a, b);}int (*chose(char op))(int, int) {    switch (op)    {    case '+':return add;    case '-':return sub;    default:        return NULL;  // 返回NULL    }}int main() {    int a, b;    char c;    int (*fuhao)(int, int);    printf("请输入数学运算式:");    scanf_s("%d%c%d", &a, &c, &b);    fuhao = chose(c);    if (fuhao == NULL) {  // 检查fuhao是否为NULL        printf("无效的运算符:%c\n", c);        return 1;    }    printf("%d %c %d = %d", a, c, b, calc(fuhao, a, b));    return 0;}
这个版本的代码在接收到无效的运算符时将输出错误信息并返回1,而不是导致未定义行为。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-18 17:33:06 | 显示全部楼层
补充一下,好像在vscode运行就挺正常的。
但是在vs2019运行就会报错,这是为什么呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-18 17:33:06 | 显示全部楼层
你的代码主要问题在于 `chose` 函数中的 `default` 情况。当用户输入的符号既不是 `+` 也不是 `-` 时,你的 `chose` 函数没有返回一个函数指针,这将导致未定义行为。

默认情况下,你可以选择返回一个函数指针,或者在用户输入无效的操作符时打印错误信息并退出程序。在下面的代码中,我选择在 `default` 情况下返回 `NULL`,并在 `main` 函数中检查 `fuhao` 是否为 `NULL`。
#include <stdio.h>
#include <stdlib.h>

int add(int, int);
int sub(int, int);
int calc(int (*p)(int, int), int, int);
int (*chose(char op))(int, int);

int add(int a, int b) {
        return a + b;
}
int sub(int a, int b) {
        return a - b;
}

int calc(int(*p)(int, int), int a, int b) {
        return (*p)(a, b);
}

int (*chose(char op))(int, int) {
        switch (op)
        {
        case '+':return add;
        case '-':return sub;
        default:
                return NULL; // 如果 op 既不是 '+' 也不是 '-',则返回 NULL
        }
}

int main() {
        int a, b;
        char c;
        int (*fuhao)(int, int);
        printf("请输入数学运算式:");
        scanf_s("%d%c%d", &a, &c, &b);
        fuhao = chose(c);
        if (fuhao == NULL) { // 如果 fuhao 是 NULL,表示用户输入的操作符无效
                printf("无效的操作符:'%c'\n", c);
                return 1; // 返回非零值表示出错
        }
        printf("%d %c %d = %d", a, c, b, calc(fuhao, a, b));

        return 0;
}


这样,当你输入 `5+1` 或其它有效算式时,你的程序将正常工作。如果你输入一个无效的操作符,你的程序将打印一个错误信息并退出。

求最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-24 08:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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