C语言函数内部改变指针本身
2012-10-25 23:11
309 查看
今天发一个C语言基础的小知识点:C语言中函数参数传递方式只有一种:值传递。
可能大家在刚开始学习C的时候都被一些教材误导,认为C中有值传递和地址传递两种方式。其实只有值传递一种,无论函数以什么形式进行传递,其实传递的都只是参数的一份拷贝!
举个简单的例子,一个改变某个整型变量参数的函数
那么pChange所指向地址内容的指改变了吗?确实改变了。
因此一些教材就认为该方式是传址,其实过程应该是这样
比如调用的 时候有如下:
这样a的值改变了,真正的情况是参数传递后,编译器做了一个参数拷贝过程,比如声明一个整型指针pCopy = &a;
这样,pCopy只是传进来参数&a的一份拷贝,但是他们都指向了a的地址,因此用这种方法可以改变a 的值。
那么现在有个问题,通过传递一个指针,可以改变该指针所指向地址的内容,那么如何改变指针本身呢?即如何改变指针的指向?
先看一个错误的例子
如果是这样,能达到改变指针本身的目的吗?
如果你有迷惑,可以这样看,把类型去掉,把参数ptr传递进去,能改变ptr吗?
显然不能!
那该怎么做才能改变ptr呢?
既然ptr也是一个变量,我要在函数内部改变它,那么就传递一个指向ptr的指针!也就是二级指针!
正确的函数形式如下
其实指针也是一个变量,我们如果要改变它,必须找到它在内存中的地址,也就是指针的地址。
当然,也可以通过另一种方式,只不过该方式需要绑定调用者的行为
这样在调用的时候必须做如下形式的调用
否则string本身是不会改变的!但是这样做意义不大,不如直接来个string = dest方便。
能用到在函数内部改变指针指向的地方通常是:一个函数完成某项功能后,得到一个指针,需要把这个指针以参数的 形式返回。
比如: foo(..., type **value);
在使用的时候通常这样:
这样之后,val指针就指向了正确的位置。
这里申明一点,想去改变一个变量本身的地址是不可能的,无论你怎么做,在声明(定义)变量的时候,它的地址就由编译器决定好了。
比如这里,你能修改val本身的地址吗?这就如同你能修改常量吗?
另外,如果我们想改变结构体中某个变量,需要传递一个指向该结构体的指针!
这样,不管你想改变的是结构体中的成员是一个普通变量还是一个指针,都是可以改变的,因为通过该结构体指针,可以获得该结构体(也是该结构体中第一个成员)的地址,进而也就知道了结构体中任一成员的地址,因此对于结构体内容,想怎么改变就怎么改变!
比如
调用时
这时my_struct.head本身已经改变了。
可能大家在刚开始学习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语言函数内部改变指针本身
- 关于AVL平衡二叉树的c语言实现(函数内部改变指针本身)
- 函数内部改变指针本身
- 改变javascript函数内部this指针指向的三种方法
- 参数传递中,指针本身不改变
- 改变javascript函数内部this指针指向的三种方法
- 改变函数内部的this指针的指向
- 改变 javascript 函数 内部 this 指针 指向 的三种方法
- 改变javascript函数内部this指针指向的三种方法
- 改变javascript函数内部this指针指向的三种方法
- c++指针使用形参改变实参的方法
- c语言函数指针应用
- 诺基亚CEO内部备忘录曝光:承认失败 承诺改变
- 巧妙使用数组,内部匿名类改变外部类final对象值
- 编写一个C函数,将”I am a student. ”倒置为”student. a am I”,及将句子中的单词位置倒置,而不改变单词内部结构.
- C语言函数指针
- 编写一个C函数,将”I am from shanghai ”倒置为”shanghai from am I”; 及将句子中的单词位置倒置,而不改变单词内部结构.
- C语言函数指针,结构体阶段总结
- c语言函数指针和应用
- C语言函数指针小结