C语言函数内部改变指针本身

今天发一个C语言基础的小知识点:C语言中函数参数传递方式只有一种:值传递。

 

可能大家在刚开始学习C的时候都被一些教材误导,认为C中有值传递和地址传递两种方式。其实只有值传递一种,无论函数以什么形式进行传递,其实传递的都只是参数的一份拷贝!

 

举个简单的例子,一个改变某个整型变量参数的函数

int change_value(int *pChange, int val)

{

       *pChange = val;

        return *pChange;

}

 

那么pChange所指向地址内容的指改变了吗?确实改变了。

因此一些教材就认为该方式是传址,其实过程应该是这样

比如调用的 时候有如下:

 

int a = 0x55aa;

change_value(&a, 0xaa55);

这样a的值改变了,真正的情况是参数传递后,编译器做了一个参数拷贝过程,比如声明一个整型指针pCopy = &a;

这样,pCopy只是传进来参数&a的一份拷贝,但是他们都指向了a的地址,因此用这种方法可以改变a 的值。

 

那么现在有个问题,通过传递一个指针,可以改变该指针所指向地址的内容,那么如何改变指针本身呢?即如何改变指针的指向?

先看一个错误的例子

void change_ptr(void *ptr, void *dest)

{

      ptr = dest;

}

如果是这样,能达到改变指针本身的目的吗?

 

如果你有迷惑,可以这样看,把类型去掉,把参数ptr传递进去,能改变ptr吗?

显然不能!

那该怎么做才能改变ptr呢?

既然ptr也是一个变量,我要在函数内部改变它,那么就传递一个指向ptr的指针!也就是二级指针!

正确的函数形式如下

void change_ptr(void **ptr, void *dest)

{

     *ptr = dest;

}

 

其实指针也是一个变量,我们如果要改变它,必须找到它在内存中的地址,也就是指针的地址。

当然,也可以通过另一种方式,只不过该方式需要绑定调用者的行为

void *change_ptr(void *ptr, void *dest)

{

     return (ptr = dest);

}

 

 这样在调用的时候必须做如下形式的调用

char *string;

string = change_ptr(string, dest);

否则string本身是不会改变的!但是这样做意义不大,不如直接来个string = dest方便。

能用到在函数内部改变指针指向的地方通常是:一个函数完成某项功能后,得到一个指针,需要把这个指针以参数的 形式返回。

比如: foo(..., type **value);

在使用的时候通常这样:

type *val = NULL;

foo(..., &val);

这样之后,val指针就指向了正确的位置。

这里申明一点,想去改变一个变量本身的地址是不可能的,无论你怎么做,在声明(定义)变量的时候,它的地址就由编译器决定好了。

比如这里,你能修改val本身的地址吗?这就如同你能修改常量吗?

 

 

 另外,如果我们想改变结构体中某个变量,需要传递一个指向该结构体的指针!

这样,不管你想改变的是结构体中的成员是一个普通变量还是一个指针,都是可以改变的,因为通过该结构体指针,可以获得该结构体(也是该结构体中第一个成员)的地址,进而也就知道了结构体中任一成员的地址,因此对于结构体内容,想怎么改变就怎么改变!

比如

typedef struct xxx {

    int *head;

}xxx_t;

 

xxx_t my_struct;

 

void change(xxx_t *dst, void *src)

{

   dst->head = str; //dst->head已经改变!

}

 

调用时

change(&my_struct, src);

 

这时my_struct.head本身已经改变了。

 

  • 15
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值