鱼C论坛

 找回密码
 立即注册
查看: 931|回复: 8

[已解决]C语言址传递

[复制链接]
发表于 2020-9-6 19:50:42 | 显示全部楼层 |阅读模式

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

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

x
小白来请教啦?我想问的是swap函数内不是经过了地址交换了吗?为什么main函数里面第二个printf函数的输出结果还是和第一个printf函数输出一样呢,这里第二个printf函数的变量为*p1,*p2。。(为了图方便,我这里设定a=4,b=5)!

代码如下:

#include <stdio.h>

int main()
{
        void swap(int *p1,int *p2);
        int *p1,*p2,a,b;
         a = 4;b = 5;   
         p1 = &a;
         p2 = &b;
         if(a<b)
         {
                swap(p1,p2);
         }
         printf("a=%d,b=%d\n",a,b);
         printf("max = %d,min = %d",*p1,*p2);
         return 0;
}

void swap(int *p1,int *p2)
{
        int *p; p = p1; p1 = p2;p2 = p;
}

运行结果如下:
a=4,b=5
max = 4,min = 5
(我用的是devc++编译器!)
最佳答案
2020-9-7 09:59:30
#include <stdio.h>

int main()
{
    void swap(int* p1, int* p2);
    int* p1, * p2, a, b;
    a = 4; b = 5;
    p1 = &a;
    p2 = &b;
    if (a < b)
    {
        swap(&p1, &p2);
    }
    printf("a=%d,b=%d\n", a, b);
    printf("max = %d,min = %d", *p1, *p2);
    return 0;
}

void swap(int** p1, int** p2)
{
    int* p; p = *p1; *p1 = *p2; *p2 = p;
}

建议从函数调用栈的角度解释
程序运行时,假定产生一个函数调用栈。
在主函数中执行另一函数时,会想堆栈中压入一个数据备份。
当这个备份执行完毕后,备份出栈,返回主函数。

你的主函数里面传入的参数是 :int *p1, * p2
到了堆栈里面函数得到的参数是:int *m=&a, int *n = &b,它们也指向对应数据;
此时函数内所有的操作只针对指针m,n进行,不会修改主函数传入的参数,这一部分也可以解释作用域的问题。

如果传入的是二级指针,堆栈得到的参数是:int** m = &p1,** n = &p2;
通过对二级指针解引用:*m = p1 = &a,*n  = p2 = &b 获得主函数中指针p1,p2所指向的地址,进而利用临时一级指针变量修改主函数中一级指针指向的地址。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-6 19:59:56 | 显示全部楼层
你这样交换的是两个数的值,在swap后就被释放了
如果想进行地址传递
void swap(int *p1,int *p2)
{
                int p; 
                p = *p1; 
                *p1 = *p2;
                *p2 = p;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-6 20:45:11 | 显示全部楼层
巴巴鲁 发表于 2020-9-6 19:59
你这样交换的是两个数的值,在swap后就被释放了
如果想进行地址传递

你这种方法我知道呀,就是你看我的swap函数,里面确实是地址之间的赋值呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-6 21:01:26 | 显示全部楼层
悠幽我心 发表于 2020-9-6 20:45
你这种方法我知道呀,就是你看我的swap函数,里面确实是地址之间的赋值呀

你的是值传递,*p可以看成取地址,即为一个数,所以你的程序是两个数交换了一下
我也不太知道怎么解释,表达不出来看看这篇文章,希望对你有帮助:https://blog.csdn.net/ThereIsNoCode/article/details/77996799
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-6 22:27:12 | 显示全部楼层
比较正确的swap方法是这样子的
void swap(int *a,int *b)
{
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;
}
这个如何形象的理解,a房子里面有一个大数,b房子里面有一个小数,你是通过a房子的门牌号找到了a然后打开门取出了大数,然后通过b房子的门牌号(指针的意思)找到了b然后打开门取了小数,同时把大数放进了b,关门,去了a房子,把小数放进去,然后再关门。这时候,a房子里面是小数,而b房子是大数,实现了交换
再看你的代码
void swap(int *p1,int *p2)
{
        int *p; p = p1; p1 = p2;p2 = p;
}
你考虑过函数的参数是如何作用的呢?
你这个代码与
void swap1(int a,int b)
{
    int temp;
    temp=a;
    a=b;
    b=temp;
}
有啥区别?其实没区别
你在函数里面修改的值,作用域仅在函数范围内,要跳出这个范围,你要么是全局变量,要么就是修改变量的地址
设想下,你现在传递一个一级指针作为参数,再函数里面进行操作,那么你要改变这个指针,是不是得修改指针的地址,那是啥,那就是二级指针
因此
按照你这个思路,
你要写成这样子才行
void swap(int **p1, int **p2)
{
        int *p; p = *p1; *p1 = *p2; *p2 = p;
}

void test5(){

                int *p1, *p2, a, b;
                a = 4; b = 5;
                p1 = &a;
                p2 = &b;
                if (a < b)
                {
                        swap(&p1, &p2);
                }
                printf("a=%d,b=%d\n", a, b);
                printf("max = %d,min = %d", *p1, *p2);

}

int main(void)
{
        test5();
        getchar();
        return 0;
}

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

使用道具 举报

发表于 2020-9-7 09:59:30 | 显示全部楼层    本楼为最佳答案   
#include <stdio.h>

int main()
{
    void swap(int* p1, int* p2);
    int* p1, * p2, a, b;
    a = 4; b = 5;
    p1 = &a;
    p2 = &b;
    if (a < b)
    {
        swap(&p1, &p2);
    }
    printf("a=%d,b=%d\n", a, b);
    printf("max = %d,min = %d", *p1, *p2);
    return 0;
}

void swap(int** p1, int** p2)
{
    int* p; p = *p1; *p1 = *p2; *p2 = p;
}

建议从函数调用栈的角度解释
程序运行时,假定产生一个函数调用栈。
在主函数中执行另一函数时,会想堆栈中压入一个数据备份。
当这个备份执行完毕后,备份出栈,返回主函数。

你的主函数里面传入的参数是 :int *p1, * p2
到了堆栈里面函数得到的参数是:int *m=&a, int *n = &b,它们也指向对应数据;
此时函数内所有的操作只针对指针m,n进行,不会修改主函数传入的参数,这一部分也可以解释作用域的问题。

如果传入的是二级指针,堆栈得到的参数是:int** m = &p1,** n = &p2;
通过对二级指针解引用:*m = p1 = &a,*n  = p2 = &b 获得主函数中指针p1,p2所指向的地址,进而利用临时一级指针变量修改主函数中一级指针指向的地址。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-8 01:11:58 | 显示全部楼层
兄弟,你只要记住,“变量有全局变量和局部变量之分,局部变量出了作用域就消毁了,不存在了” 就行了,其他的暂时弄不懂的暂时放过,留出时间来多做做练习,多看看其他的例题,慢慢地就会理解了,也就会懂了。我当时对这个问题就是通过比较弄懂的,下图就是我自己做的比较,希望对你的理解有所帮助:

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

使用道具 举报

 楼主| 发表于 2020-9-9 11:01:09 | 显示全部楼层
风过无痕1989 发表于 2020-9-8 01:11
兄弟,你只要记住,“变量有全局变量和局部变量之分,局部变量出了作用域就消毁了,不存在了” 就行了,其 ...

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

使用道具 举报

 楼主| 发表于 2020-9-9 11:01:40 | 显示全部楼层
冷回清风暖 发表于 2020-9-7 09:59
建议从函数调用栈的角度解释
程序运行时,假定产生一个函数调用栈。
在主函数中执行另一函数时,会想 ...

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-13 03:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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