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本身已经改变了。

行动是治愈恐惧的良药,而犹豫、拖延将不断滋养恐惧。

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

相关文章:

你感兴趣的文章:

标签云: