kaishao 发表于 2023-7-18 17:20:15

关于c语言函数指针作为参数的问题

为什么我这代码可以正常打开,但是我输入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-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;
}


修改后的代码应该能够正确运行,允许你输入数学运算式并得到结果。希望对你有所帮助!

isdkz 发表于 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,而不是导致未定义行为。

kaishao 发表于 2023-7-18 17:33:06

补充一下,好像在vscode运行就挺正常的。
但是在vs2019运行就会报错,这是为什么呢?

sfqxx 发表于 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` 或其它有效算式时,你的程序将正常工作。如果你输入一个无效的操作符,你的程序将打印一个错误信息并退出。

求最佳答案{:10_254:}
页: [1]
查看完整版本: 关于c语言函数指针作为参数的问题