鱼C论坛

 找回密码
 立即注册
查看: 1771|回复: 12

[已解决]指针变量做形参 排序

[复制链接]
发表于 2017-9-26 09:31:14 | 显示全部楼层 |阅读模式

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

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

x

我打算用指针变量为形参,进行三个数从小到大的排序
但是在我调试的时候,发现在swap函数里地址是交换成功的,
可是一回到compare函数里,地址用变回原来的样子了
希望大家给我这个小白一点建议,谢谢

  1. #include "stdio.h"

  2. void main()
  3. {
  4.       int a, b, c;
  5.       int *A, *B, *C;
  6.       void compare(int *x, int *y, int *z);
  7.       
  8.       printf("please input a, b, c\n");
  9.       scanf("%d %d %d", &a, &b, &c);
  10.       A = &a;
  11.       B = &b;
  12.       C = &c;
  13.       compare(A, B, C);
  14. }

  15. void compare(int *x, int *y, int *z)
  16. {
  17.       void swap(int *x, int *y);
  18.       
  19.       if(*x > *y)
  20.       {
  21.             swap(x, y);
  22.       }
  23.       if(*x > *z)
  24.       {
  25.             swap(x, z);
  26.       }
  27.       if(*y > *z)
  28.       {
  29.             swap(y, z);
  30.       }      
  31.       printf("%d < %d < %d\n", *x, *y, *z);
  32. }

  33. void swap(int *x, int *y)
  34. {
  35.       int *temp;
  36.       
  37.       temp = x;
  38.       x = y;
  39.       y = temp;   
  40. }


复制代码
最佳答案
2017-9-26 09:37:36
swap的参数应该是指向指针的指针,因为你要改变指针自身的指向。
把调用这个函数的实参前加个&
  1. void swap(int **x, int **y)
  2. {
  3.       int *temp;
  4.       
  5.       temp = *x;
  6.       *x = *y;
  7.       *y = temp;   
  8. }
复制代码

如如所示

如如所示
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-26 09:37:36 | 显示全部楼层    本楼为最佳答案   
swap的参数应该是指向指针的指针,因为你要改变指针自身的指向。
把调用这个函数的实参前加个&
  1. void swap(int **x, int **y)
  2. {
  3.       int *temp;
  4.       
  5.       temp = *x;
  6.       *x = *y;
  7.       *y = temp;   
  8. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-26 12:31:09 | 显示全部楼层
丶忘却的年少o 发表于 2017-9-26 09:37
swap的参数应该是指向指针的指针,因为你要改变指针自身的指向。
把调用这个函数的实参前加个&

谢谢大神, 不过我实参前面没加“&”也可以啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-26 12:47:27 | 显示全部楼层
boot 发表于 2017-9-26 12:31
谢谢大神, 不过我实参前面没加“&”也可以啊

可以是可以,但是你后面swap函数里就是交换值,就是a b c对应的值交换了。要是实参前加了就是交换指针指向,不改变值。你可以在main最后加一条          printf("a = %d  b = %d  c = %d\n", a, b, c); 看看,值应该是换掉了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-26 12:52:35 | 显示全部楼层
丶忘却的年少o 发表于 2017-9-26 12:47
可以是可以,但是你后面swap函数里就是交换值,就是a b c对应的值交换了。要是实参前加了就是交换指针指 ...

对对对,谢谢你了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-26 12:59:24 | 显示全部楼层
boot 发表于 2017-9-26 12:52
对对对,谢谢你了

不客气,忘记说了,传过去的参数是有代码段作用域,只在那个函数里变化有用,返回到调用函数里失效了,这就是为什么你的swap里变化了返回后没变化,用指针就不会。
指针是个比较复杂麻烦的东西,懂了后就很好用,慢慢学,加油
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-26 13:09:08 | 显示全部楼层
丶忘却的年少o 发表于 2017-9-26 12:59
不客气,忘记说了,传过去的参数是有代码段作用域,只在那个函数里变化有用,返回到调用函数里失效了,这 ...

好的,我会加油的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-27 13:06:41 | 显示全部楼层
丶忘却的年少o 发表于 2017-9-26 12:59
不客气,忘记说了,传过去的参数是有代码段作用域,只在那个函数里变化有用,返回到调用函数里失效了,这 ...

大神,你能讲解一下这个过程原理是如何进行的,指针的地址变换了为什么指针指向的值也变了?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-27 13:26:05 | 显示全部楼层
boot 发表于 2017-9-27 13:06
大神,你能讲解一下这个过程原理是如何进行的,指针的地址变换了为什么指针指向的值也变了?

不是指针的地址变了,是指针存放的地址(指向的地址)变了,指针指向的值当然是变了。
先说下你一开始的程序,你的理解是对的,但是参数只有代码段作用域,你要是在swap里printf变化后的值肯定是对的,就是你要的。但是没返回呀,在这个函数里的东西就会随着函数的结束都释放了,回到调用函数就是调用函数本身应该有的值。所以要把指针的地址传过去,让被调用的函数改变这个指针存放的地址,就是改变指针指向的地址,让它指向一个你要的数的地址。不懂没关系,看下面↓
本来*p指向a,*p1指向b,指针*p、*p1存的是a、b的地址。那我用指向指针的指针**p2、**p3分别指向*p、*p1,为了方便你理解,我们把*p、*p1看成一个数,不是指针,等价的*p2、*p3分别指向p、p1,我要改变p、p1的值是不是改变*p2、*p3(这里的*是取值的意思)就可以实现,用一个临时变量,让他们互换,是不是p、p1就互换了值。好,现在扔掉**p2、**p3,我们来看*p、*p1,现在对他们取值是不是也互换了,因为他们指向的地址互换了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-27 20:21:34 | 显示全部楼层
丶忘却的年少o 发表于 2017-9-27 13:26
不是指针的地址变了,是指针存放的地址(指向的地址)变了,指针指向的值当然是变了。
先说下你一开始的 ...

谢谢啦,看了你的分析我懂了一点。但还是有几个地方还是有点不明白。
按照你说的(不清楚对不对哈):
p = &a;       p1 = &b; (*p指向a,*p1指向b)
p2 = &p;     p3 = &p1; (指向指针的指针**p2、**p3分别指向*p、*p1)
我们把*p、*p1看成一个数,不是指针”你的意思是p、p1存放的地址看作是数,对吧?
然后你说“等价的*p2、*p3分别指向p、p1”,这里的p1、p是什么???(你说*p、*p1是指针,这里p、p1没有“*”
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-27 20:45:09 | 显示全部楼层
boot 发表于 2017-9-27 20:21
谢谢啦,看了你的分析我懂了一点。但还是有几个地方还是有点不明白。
按照你说的(不清楚对不对哈{:10_28 ...

对呀,你要把那两句连起来看嘛,你理解的没错的,p、p1存放的地址看作是数,就是p = (a的地址),p1 = (b的地址)。就是分别降一级指针,指针变成常数,指向指针的指针变成指针就好了(这个按照指针原理来是不科学的,我这么说是为了让你理解,你要是理解了就忘记了吧)。那p2、p3就是指针,而p、p1就是常数,既然是常数,就不要*了,然后接着我说的,接下去看,用临时变量来当中间值互换指针p2、p3的值那是不是就相当于p、p1的互换(别考虑别的因素,因为二次指针自己有限制的,就跟着这个思路走)。然后还原p、p1指针,指向的就是指向的a、b了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-27 20:56:10 | 显示全部楼层
如果还是要考虑指针等价后的因素问题,我换一种说法(比较符合原理):
**p2 = *p = &a,   **p3= *p1 = &b
对**p2和 **p3进行指向操作:*p2 = p, *p3 = p1
temp = *p2, *p2 = *p3, *p3 = temp  等价于
temp = p, p = p1, p1 = temp  此时的p和p1结果就是
**p2 = *p = &b,   **p3= *p1 = &a
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-27 21:13:19 | 显示全部楼层
哦哦,太感谢了,明白了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-3-29 08:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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