鱼C论坛

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

[已解决]输出同一个指针变量,地址相同,但值却不相同,这是为什么??

[复制链接]
发表于 2020-3-14 01:33:49 | 显示全部楼层 |阅读模式

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

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

x
#include<stdio.h>
        int *p1,*p2,*p;
int main(){
        int a,b;
        int select();

        scanf("%d%d",&a,&b);
        select(a,b);
        printf("%d\n",*p1);/*第一个P1,为什么这里的p1和后面两个的输出不同??*/
        printf("%d>>%d\n",a,b);
        printf("%d>>%d\n",*p1,*p2);        /*第二个P1,这里的输出为什么突然变了??*/
        printf("%d\n",*p1);/*第三个P1,这里的输出为什么突然变了??*/
        return 0;
}

/*要是输出三个p1指针中的地址,却又相同、正确,,是什么情况??*/

int select(int a,int b){
        p1=&a;
        p2=&b;

        if(a<b){
                p=p1;
                p1=p2;
                p2=p;
        }       

        return 0;

}
最佳答案
2020-3-14 16:58:27
战斗机械 发表于 2020-3-14 15:11
1、但如果输入a>b时,他的输出又会正确输出。
2、如果输入a

不太明白你的意思。你是说a>b输出结果正确,a<b输出结果不正确?
另外我没说p1和p2释放掉,是形参被释放掉了,两个指针依然指向该地址,只是地址的内容可能被修改了。
你用值传递的方式,就会造成函数执行结束后,两个指针所指向的单元不受控制。很可能就不是原来的值了。
下图是一个示意图,进入select函数时p1和p2分别指向形参a和b对应的地址单元,select函数执行结束后,p1指向a和b较大的那个数的单元。但是该地址是否还是通过实参传递过来的值就不一定了。这受很多因素的影响,如:编译器,你的电脑内存使用情况等等
1.jpg
你可以看一下函数执行前后p1和p2的地址,看一下a>b和a<b两种情况下地址的变化。
#include<stdio.h>
        int *p1,*p2,*p;

int main(){
        int a,b;
        int select(int a,int b);

        scanf("%d%d",&a,&b);
        select(a,b);
        printf("%d\n",*p1);/*第一个P1,为什么这里的p1和后面两个的输出不同??*/
        printf("%d>>%d\n",a,b);
        printf("p1->%d,p2->%d\n",p1,p2); 
        printf("%d--%d\n",*p1,*p2);
        return 0;
}

/*要是输出三个p1指针中的地址,却又相同、正确,,是什么情况??*/

int select(int a,int b){
        p1=&a;
        p2=&b;
                printf("p1->%d,p2->%d\n",p1,p2);
        if(a<b){
                p=p1;
                p1=p2;
                p2=p;
        }        

        return 0;

}

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2020-3-14 02:39:29 | 显示全部楼层
因为你的select()函数是值传递而不是地址传递。虽然两个指针是全局指针,但是在函数中给p1和p2赋值,p1和p2的值只在函数调用期间有效,一旦函数调用结束,函数形参a和b两个变量空间被释放,p1和p2两个指针则再次没有任何指向。所以每次输出p1都可能会变化。
注:第一次输出p1时,距离select()函数调用比较近,不同的系统时间消耗不一样,形参可能还没有释放掉,也许还能读到对应的值。但是第二次的时候基本上就肯定读不到函数调用期间的形参值了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-3-14 10:25:16 | 显示全部楼层
本帖最后由 sunrise085 于 2020-3-14 16:29 编辑

接着昨晚回答的继续说。你若想让他们一样,就需要将select函数改为地址传递的形式。
我帮你改了一下,但是不知道这样还是不是你需要的
#include<stdio.h>
        int *p1,*p2,*p;

int main(){
        int a,b;
        int select(int *a,int *b);

        scanf("%d%d",&a,&b);
        select(&a,&b);
        printf("%d\n",*p1);/*第一个P1,为什么这里的p1和后面两个的输出不同??*/
        printf("%d>>%d\n",a,b);
        printf("%d>>%d\n",*p1,*p2);        /*第二个P1,这里的输出为什么突然变了??*/
        printf("%d\n",*p1);/*第三个P1,这里的输出为什么突然变了??*/
        return 0;
}

/*要是输出三个p1指针中的地址,却又相同、正确,,是什么情况??*/

int select(int *a,int *b){
        p1=a;
        p2=b;

        if(*a<*b){
                p=p1;
                p1=p2;
                p2=p;
        }        

        return 0;

}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-3-14 15:11:22 | 显示全部楼层
本帖最后由 战斗机械 于 2020-3-14 15:14 编辑
sunrise085 发表于 2020-3-14 02:39
因为你的select()函数是值传递而不是地址传递。虽然两个指针是全局指针,但是在函数中给p1和p2赋值,p1和p2 ...


1、但如果输入a>b时,他的输出又会正确输出。
2、如果输入a<b时,第二和第三个输出p1,也并非任意的输出,他总是输出小的那个值;
而且p1,p2如果直接输出地址,则又正确。
说明p1,p2并没有释放,且函数select()也正确执行;但输入a<b时,为什么会输出不同,又为什么是输出小的值??
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-14 16:58:27 | 显示全部楼层    本楼为最佳答案   
战斗机械 发表于 2020-3-14 15:11
1、但如果输入a>b时,他的输出又会正确输出。
2、如果输入a

不太明白你的意思。你是说a>b输出结果正确,a<b输出结果不正确?
另外我没说p1和p2释放掉,是形参被释放掉了,两个指针依然指向该地址,只是地址的内容可能被修改了。
你用值传递的方式,就会造成函数执行结束后,两个指针所指向的单元不受控制。很可能就不是原来的值了。
下图是一个示意图,进入select函数时p1和p2分别指向形参a和b对应的地址单元,select函数执行结束后,p1指向a和b较大的那个数的单元。但是该地址是否还是通过实参传递过来的值就不一定了。这受很多因素的影响,如:编译器,你的电脑内存使用情况等等
1.jpg
你可以看一下函数执行前后p1和p2的地址,看一下a>b和a<b两种情况下地址的变化。
#include<stdio.h>
        int *p1,*p2,*p;

int main(){
        int a,b;
        int select(int a,int b);

        scanf("%d%d",&a,&b);
        select(a,b);
        printf("%d\n",*p1);/*第一个P1,为什么这里的p1和后面两个的输出不同??*/
        printf("%d>>%d\n",a,b);
        printf("p1->%d,p2->%d\n",p1,p2); 
        printf("%d--%d\n",*p1,*p2);
        return 0;
}

/*要是输出三个p1指针中的地址,却又相同、正确,,是什么情况??*/

int select(int a,int b){
        p1=&a;
        p2=&b;
                printf("p1->%d,p2->%d\n",p1,p2);
        if(a<b){
                p=p1;
                p1=p2;
                p2=p;
        }        

        return 0;

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-22 13:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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