鱼C论坛

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

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

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

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

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

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

  2. int add(int, int);
  3. int sub(int, int);
  4. int calc(int (*p)(int, int), int, int);
  5. int (*chose(char op))(int, int);

  6. int add(int a, int b) {
  7.         return a + b;
  8. }
  9. int sub(int a, int b) {
  10.         return a - b;
  11. }

  12. int calc(int(*p)(int, int), int a, int b) {
  13.         return (*p)(a, b);
  14. }

  15. int (*chose(char op))(int, int) {
  16.         switch (op)
  17.         {
  18.         case '+':return add;
  19.         case '-':return sub;
  20.         default:
  21.                 break;
  22.         }
  23. }




  24. int main() {
  25.         int a, b;
  26.         char c;
  27.         int (*fuhao)(int, int);
  28.         printf("请输入数学运算式:");
  29.         scanf_s("%d%c%d", &a, &c, &b);
  30.         fuhao = chose(c);
  31.         printf("%d %c %d = %d", a, c, b, calc(fuhao, a, b));


  32.         return 0;
  33. }
复制代码

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

在你的代码中,第14行scanf_s函数的参数&c应该改成sizeof(c),以指定c变量允许接受的最大字符数为1。另外,第10行的函数声明中,可以省略参数名。修改后的代码如下所示:
  1. #include <stdio.h>
  2. int add(int, int);
  3. int sub(int, int);
  4. int calc(int (*)(int, int), int, int);
  5. int (*chose(char op))(int, int);
  6. int add(int a, int b)
  7. {
  8.   return a + b;
  9. }
  10. int sub(int a, int b)
  11. {
  12.   return a - b;
  13. }
  14. int calc(int (*p)(int, int), int a, int b)
  15. {
  16.   return (*p)(a, b);
  17. }
  18. int (*chose(char op))(int, int)
  19. {
  20.   switch (op)
  21.   {
  22.     case '+':
  23.       return add;
  24.     case '-':
  25.       return sub;
  26.     default:
  27.       break;
  28.   }
  29. }
  30. int main()
  31. {
  32.   int a, b;
  33.   char c;
  34.   int (*fuhao)(int, int);
  35.   printf("请输入数学运算式:");
  36.   scanf_s("%d%c%d", &a, &c,sizeof(c));
  37.   fuhao = chose(c);
  38.   printf("%d %c %d = %d", a, c, b, calc(fuhao, a, b));
  39.   return 0;
  40. }
复制代码

修改后的代码应该能够正确运行,允许你输入数学运算式并得到结果。希望对你有所帮助!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

在你的代码中,第14行scanf_s函数的参数&c应该改成sizeof(c),以指定c变量允许接受的最大字符数为1。另外,第10行的函数声明中,可以省略参数名。修改后的代码如下所示:
  1. #include <stdio.h>
  2. int add(int, int);
  3. int sub(int, int);
  4. int calc(int (*)(int, int), int, int);
  5. int (*chose(char op))(int, int);
  6. int add(int a, int b)
  7. {
  8.   return a + b;
  9. }
  10. int sub(int a, int b)
  11. {
  12.   return a - b;
  13. }
  14. int calc(int (*p)(int, int), int a, int b)
  15. {
  16.   return (*p)(a, b);
  17. }
  18. int (*chose(char op))(int, int)
  19. {
  20.   switch (op)
  21.   {
  22.     case '+':
  23.       return add;
  24.     case '-':
  25.       return sub;
  26.     default:
  27.       break;
  28.   }
  29. }
  30. int main()
  31. {
  32.   int a, b;
  33.   char c;
  34.   int (*fuhao)(int, int);
  35.   printf("请输入数学运算式:");
  36.   scanf_s("%d%c%d", &a, &c,sizeof(c));
  37.   fuhao = chose(c);
  38.   printf("%d %c %d = %d", a, c, b, calc(fuhao, a, b));
  39.   return 0;
  40. }
复制代码

修改后的代码应该能够正确运行,允许你输入数学运算式并得到结果。希望对你有所帮助!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

一种解决方案是在 chose 函数的 default 分支中返回一个有效的函数指针,或者返回 NULL ,然后在使用这个函数指针之前进行检查。下面是代码的修订版本:
  1. #include <stdio.h>
  2. int add(int, int);
  3. int sub(int, int);
  4. int calc(int (*p)(int, int), int, int);
  5. int (*chose(char op))(int, int);
  6. int add(int a, int b) {
  7.     return a + b;
  8. }
  9. int sub(int a, int b) {
  10.     return a - b;
  11. }
  12. int calc(int(*p)(int, int), int a, int b) {
  13.     return (*p)(a, b);
  14. }
  15. int (*chose(char op))(int, int) {
  16.     switch (op)
  17.     {
  18.     case '+':return add;
  19.     case '-':return sub;
  20.     default:
  21.         return NULL;  // 返回NULL
  22.     }
  23. }
  24. int main() {
  25.     int a, b;
  26.     char c;
  27.     int (*fuhao)(int, int);
  28.     printf("请输入数学运算式:");
  29.     scanf_s("%d%c%d", &a, &c, &b);
  30.     fuhao = chose(c);
  31.     if (fuhao == NULL) {  // 检查fuhao是否为NULL
  32.         printf("无效的运算符:%c\n", c);
  33.         return 1;
  34.     }
  35.     printf("%d %c %d = %d", a, c, b, calc(fuhao, a, b));
  36.     return 0;
  37. }
复制代码

这个版本的代码在接收到无效的运算符时将输出错误信息并返回1,而不是导致未定义行为。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

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

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int add(int, int);
  4. int sub(int, int);
  5. int calc(int (*p)(int, int), int, int);
  6. int (*chose(char op))(int, int);

  7. int add(int a, int b) {
  8.         return a + b;
  9. }
  10. int sub(int a, int b) {
  11.         return a - b;
  12. }

  13. int calc(int(*p)(int, int), int a, int b) {
  14.         return (*p)(a, b);
  15. }

  16. int (*chose(char op))(int, int) {
  17.         switch (op)
  18.         {
  19.         case '+':return add;
  20.         case '-':return sub;
  21.         default:
  22.                 return NULL; // 如果 op 既不是 '+' 也不是 '-',则返回 NULL
  23.         }
  24. }

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

  37.         return 0;
  38. }
复制代码



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

求最佳答案
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-10 12:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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