鱼C论坛

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

[已解决]视频讲解题目,函数指针部分,有一点疑问

[复制链接]
发表于 2020-11-7 23:34:38 | 显示全部楼层 |阅读模式

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

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

x
1.不是说不可以返回局部变量的指针 ,局部变量的作用域只是函数内,下面这个例子就是,报错了,为什么在下下面这个代码里面,
select函数,就是做了同样的操作,返回了函数名,函数名是一个地址(地址不用指针指向它,是不是不算指针),没有报错

2.下面这个注释掉的例子,定义的是指针函数,是一个函数,返回的是一个指针
   下下面这个例子,定义的是函数指针,是一个指针,指向的是函数,返回的是函数的返回值

是不是只有指针函数里面不可以返回局部变量的指针???????????????????

/*
//报错
char *getWord(char);
char *getWord(char c)
{
char str1[] = "apple";
char str2[]  = "banana" ;
char str3[]  = "CAT" ;
char str4[]  = "dog" ;
char str5[]  = "none" ;

    switch(c)
    {
     case 'A':return str1;    ////不可以返回局部变量的指针 ,局部变量的作用域只是函数内
     case 'B':return str2;    //这的字符串就是一个字符指针,返回的是当前指针的首地址,不可以。。。
     case 'C':return str3;
     case 'D':return str4;
     default:return  str5;
}
}

int main ()
{
    char input;
printf("enter  a letter:");
scanf("%c",&input);  

printf("%s\n",getWord(input));
    return 0;
}
*/


  1. #include <stdio.h>
  2. //************函数指针作为返回值*********

  3. int add(int,int);
  4. int sub(int,int);
  5. int calc(int (*fp)(int,int),int,int);
  6. //运算符是有优先级的, 括号的优先级高于取值运算符,从左到右,
  7. //先是定义了一个函数select,参数是一个字符变量,有一个返回值,返回的是一个指针,
  8. //指针指向的是一个返回整型并且带有两个参数的函数
  9. int (*select(char op))(int,int); // 便于理解,(*)(int,int),就是一个函数指针

  10. int add(int num1,int num2)
  11. {
  12.         return num1 + num2;
  13. }

  14. int sub(int num1,int num2)
  15. {
  16.         return num1 - num2;
  17. }

  18. int calc(int (*fp)(int,int),int num1,int num2)
  19. {
  20.         return (*fp)(num1,num2);
  21. }


  22. int (*select(char op))(int,int)
  23. {
  24.         switch(op)
  25.         {
  26.                 case '+':return add;
  27.                 case '-':return sub;
  28.         }
  29. }


  30. int main()
  31. {
  32.         int num1,num2;
  33.         char op;
  34.         int (*fp)(int,int);
  35.        
  36.         printf("enter a function(such as 1+3):") ;
  37.         scanf("%d%c%d",&num1,&op,&num2);
  38.        
  39.         fp = select(op);
  40.         printf("%d %c %d = %d\n",num1,op,num2,calc(fp,num1,num2));
  41.         return 0;
  42. }
复制代码
最佳答案
2020-11-8 08:22:16
首先,函数是可以返回指针(地址)的,这在语法上没有任何问题,比如说,写成这样就没有任何问题。
  1. char *getWord(char c)
  2. {
  3.         char *str1 = "apple";
  4.         char *str2  = "banana" ;
  5.         char *str3  = "CAT" ;
  6.         char *str4  = "dog" ;
  7.         char *str5  = "none" ;
  8.        
  9.     switch(c)
  10.     {
  11.                 case 'A':return str1;   
  12.                 case 'B':return str2;   
  13.                 case 'C':return str3;
  14.                 case 'D':return str4;
  15.                 default:return  str5;
  16.         }
  17. }
复制代码


当然,有些写法是有问题的,比如

  1. int *  fun(int n)
  2. {
  3.        int a = n;
  4.        return &a;
  5. }
复制代码

上面的函数在语法上是对的,但有些编译器会提出警告,有些编译器会报错。
原因是: 局部变量是在栈上分配的内存,当离开函数后,这段内存就被标记为未使用。把这段内存返回出去可能出现把一段内存同时分配给两个变量的情况。
栈的作用有:函数调用传递参数,保存函数调用返回地址,保存寄存器的值,分配局部变量。

而函数
int (*select(char op))(int,int)
他返回的是一个函数的地址,这个地址是你的程序被系统载入内存时就已分配好的(你可以理解为跟全局变量一样),而不是在栈上,是不会被破坏的。
所以将它返回出去不存在任何问题。


小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-11-7 23:55:45 | 显示全部楼层

回帖奖励 +1 鱼币

在论坛来说,你已经不算是新手了,为什么连论坛的规则都还没而已嘛清楚?

论坛的大侠们回答你的问题,不是为了你的几个鱼币,而是系统的奖励:鱼币+3,荣誉+2,技术+1;;鱼币买个会员,就没有什么用了,因为论坛对会员来说,是畅通的,课后的练习也不需要再用鱼币来购买,即使不是会员(就像我这样,在论坛这么久了,我缺少鱼币吗?)所以说,那些大侠们真正缺少的是技术值,这个技术是是购买不来的,也不是你能给予的,唯一获得的途径就是,回答问题被选为最佳答案。

就你现在这个问题,那可是四个最佳答案呀,你不给他们机会,他们有这个必要来回答吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-8 08:22:16 | 显示全部楼层    本楼为最佳答案   

回帖奖励 +1 鱼币

首先,函数是可以返回指针(地址)的,这在语法上没有任何问题,比如说,写成这样就没有任何问题。
  1. char *getWord(char c)
  2. {
  3.         char *str1 = "apple";
  4.         char *str2  = "banana" ;
  5.         char *str3  = "CAT" ;
  6.         char *str4  = "dog" ;
  7.         char *str5  = "none" ;
  8.        
  9.     switch(c)
  10.     {
  11.                 case 'A':return str1;   
  12.                 case 'B':return str2;   
  13.                 case 'C':return str3;
  14.                 case 'D':return str4;
  15.                 default:return  str5;
  16.         }
  17. }
复制代码


当然,有些写法是有问题的,比如

  1. int *  fun(int n)
  2. {
  3.        int a = n;
  4.        return &a;
  5. }
复制代码

上面的函数在语法上是对的,但有些编译器会提出警告,有些编译器会报错。
原因是: 局部变量是在栈上分配的内存,当离开函数后,这段内存就被标记为未使用。把这段内存返回出去可能出现把一段内存同时分配给两个变量的情况。
栈的作用有:函数调用传递参数,保存函数调用返回地址,保存寄存器的值,分配局部变量。

而函数
int (*select(char op))(int,int)
他返回的是一个函数的地址,这个地址是你的程序被系统载入内存时就已分配好的(你可以理解为跟全局变量一样),而不是在栈上,是不会被破坏的。
所以将它返回出去不存在任何问题。


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

使用道具 举报

 楼主| 发表于 2020-11-8 09:23:35 | 显示全部楼层
风过无痕1989 发表于 2020-11-7 23:55
在论坛来说,你已经不算是新手了,为什么连论坛的规则都还没而已嘛清楚?

论坛的大侠们回答你的问题,不 ...

不缺渔币我明白了,什么叫四个最佳,啥意思
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-8 09:31:15 | 显示全部楼层
本帖最后由 猪猪虾 于 2020-11-8 09:33 编辑
xieglt 发表于 2020-11-8 08:22
首先,函数是可以返回指针(地址)的,这在语法上没有任何问题,比如说,写成这样就没有任何问题。


char *str2 = "banana"; 和 char str[] = "banana" 应该没有区别吧,本身存储的就是字符串,字符数组名就是首地址,就是一个指针
我试了一下,确实没有报错了。。。
为啥
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2020-11-8 09:37:14 | 显示全部楼层
猪猪虾 发表于 2020-11-8 09:31
char *str2 = "banana"; 和 char str[] = "banana" 应该没有区别吧,本身存储的就是字符串,字符数组名 ...

找本书看一下吧,这两种区别可大了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-11-9 16:26:14 | 显示全部楼层
猪猪虾 发表于 2020-11-8 09:23
不缺渔币我明白了,什么叫四个最佳,啥意思

你这一题是四个问题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-9 20:05

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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