结构体成员变量指针与普通数据类型指针比较

9 篇文章 0 订阅

写这篇文章的原因是,我很好奇链表的结点删除算法为啥修改了指针域的值就可以。
还是用代码来说事吧,简单的写一个测试案例:

#include<stdio.h>

typedef struct{
    int* p;
}*pstru;

void ChangeIntPointerOne(int* p, int *q){ p = q;}

void ChangeIntPointerTwo(int** p, int *q){ *p = q;}

void ChangeStructmemberPointer(pstru mystru, int *q){
    mystru->p = q;
}

int main(int argc, char* argv[])
{
    int a = 10;
    int *p1 = NULL;
    pstru p2;
    p2->p = NULL;

    printf("a addr = %p\n\n", &a);
    //测试普通数据类型指针
    printf("initial p1 = %p\n", p1);
    ChangeIntPointerOne(p1, &a);
    printf("one p1 = %p\n\n", p1);

    p1 = NULL;
    printf("initial p1 = %p\n", p1);
    ChangeIntPointerTwo(&p1, &a);
    printf("two p1 = %p\n\n", p1);

    //测试结构体成员变量指针
    printf("p2 = %p\n", p2);
    printf("initial p2->p = %p\n", p2->p);
    ChangeStructmemberPointer(p2, &a);
    printf("change p2->p = %p\n", p2->p);

    return 0;
}

输出结果:
在这里插入图片描述
结论:根据调用普通指针的两个函数的结果得到,修改普通数据类型的指针的值传递参数时必须是二级指针,而结构体成员变量指针可以直接修改。
我们来解析下为什么是这样的:
1.在最初的时候在这里插入图片描述
2.开始调用第一个函数调用

 ChangeIntPointerOne(p1, &a);
void ChangeIntPointerOne(int* p, int *q){ p = q;}

这里只是简单的把形参q的值赋值给形参p,他们都是栈上的开辟的新内存,和main里的实参不是同一块内存,当该函数执行结束后,p,q的内存就被回收了,所以这里对实参内存里的数据没有任何修改,所以p1的值还是NULL。
3.开始第二个函数调用

ChangeIntPointerTwo(&p1, &a);
void ChangeIntPointerTwo(int** p, int *q){ *p = q;}

这里传递的实参是main里的p1的地址,p就指向p1所在的内存单元,当执行p=q时,就是向p所指向的内存,也就是p1所在内存单元写入q,即p就等于p1,所以这里把p1修改了,当你在main里使用printf()打印p1时,就是读取p1所在内存单元的数据,该数据已经被重新写入了。
在这里插入图片描述
4.开始第三个函数调用

ChangeStructmemberPointer(p2, &a);
void ChangeStructmemberPointer(pstru mystru, int *q){
    mystru->p = q;
}

这里执行函数里面的语句时,mystru->p是读取结构体指针mystru指向的内存单元(也就是p2指向的内存单元)的p所在的内存,之后赋值q,就是把q写入该内存,所以p2->p就被修改了,不过p2没有被修改,要修改p2得传递二级结构体指针。
在这里插入图片描述
总结:以上就可以解释当删除链表的某个结点时,只需要传递结构体指针就可以了,因为我们不需要修改结构体指针本身的值(即结构体指针的指向),而只是结构体指针指向的内存单元里的数据。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值