C语言指针参数传值的真相

来源:互联网 发布:爱奇艺网络电视剧 编辑:程序博客网 时间:2024/05/02 19:32

先来看一段代码:

void NatureOfPoint(){int a = 10;int* pt_a = &a;printf("指针pt_a的内存地址是:%d\n",&pt_a);printf("指针pt_a指向的内存地址是:%d\t变量a的内存地址是:%d\n",pt_a,&a);printf("指针pt_a指向的内存地址上存储的数据值是:%d\n",*pt_a);}

代码执行的结果如下:




分别来看下上述代码段中的对象的图形表示。

 

可以看到pt_a和a的关系就是pt_a的【存储值】=a的【内存地址】

这是指针的基本知识。

 

 

下面将讨论一个问题:在函数内改变形参指针的地址,会导致实参指针的变化吗?

再来看一段程序代码

void NatureOfPoint(){void changeVal(int* ,int );int a = 10;int* pt_a = &a;printf("指针pt_a的内存地址是:%d\n",&pt_a);printf("指针pt_a指向的内存地址是:%d\t变量a的内存地址是:%d\n",pt_a,&a);printf("指针pt_a指向的内存地址上存储的数据值是:%d\n",*pt_a);printf("----------------以上是调用changeVal函数之前实参的情况---------------------\n\n");changeVal(pt_a,11);printf("#####完成changeVal函数调用之后,来看看实参的情况:\n");printf("指针pt_a的内存地址是:%d\n",&pt_a);printf("指针pt_a指向的内存地址是:%d\t变量a的内存地址是:%d\n",pt_a,&a);printf("指针pt_a指向的内存地址上存储的数据值是:%d\n",*pt_a);}void changeVal(int* pt,int new_val){printf("形参pt的内存地址是 :%d\n",&pt);printf("形参pt指向的内存地址是:%d\t形参new_val的内存地址是:%d\n",pt,&new_val);printf("形参pt指向的内存地址上存储的数据值是:%d\n",*pt);printf("----------------漂亮的分割线---------------------\n\n");pt=&new_val;printf("#####将形参new_val的内存指给形参pt之后:\n");printf("形参pt的内存地址是 :%d\n",&pt);printf("形参pt指向的内存地址是:%d\t形参new_val的内存地址是:%d\n",pt,&new_val);printf("形参pt指向的内存地址上存储的数据值是:%d\n\n\n",*pt);}

执行的结果是:



通过观察结果,可以看到如下几个事实:

1、实参在调用函数changeVal的前后没有发生任何变化。

2、在执行changeVal中的语句pt=&new_val;之前:

(1)实参pt_a和形参pt是两个不同的变量。在上述的代码执行中可以看到实参pt_a的内存地址是5044648,而形参pt的内存地址是5044432。两个的内存地址是不同的,所以他们是两个不同的变量。

(2)实参pt_a和形参pt所指向的内存地址是相同的,都是5044660,这个地址是实参变量a的。

3、在执行changeVal中的语句pt=&new_val;之后:

(1)形参pt的指向的内存地址变为了5044432,这个地址是形参new_val的内存地址。

(2)形参pt所指的内存地址上所存储的值变为了11,这正是形参new_val的值。

 

通过上面的观察,已经可以知道,改变形参指针的所指向的地址,并不能改变实参所指向的地址,本质上的原因就在于,形参指针和实参指针是两个独立的变量,形参是实参的一个copy

 

让我们在以图形的方式看下上述的代码执行过程:

1、在NatureOfPoint函数内,在执行代码changeVal(pt_a,11);之前,各数据的情况如下:


2、在进入到changeVal函数之后,没有执行pt=&new_val;之前,各数据情况如下:




3、在NatureOfPoint函数内,在执行代码changeVal(pt_a,11);之后,各数据的情况如下:




相比前一副图的区别在于原本pt指针是指向a变量的,变为了指向new_val变量。

 

4、在NatureOfPoint函数执行完之后,各个数据的情况也就如上图一样,可以看到,通过NatureOfPoint函数内的改变形参pt所指向的操作并没有给实参带来任何变化。

 

 

所以写代码的时候要告诉自己,不要在函数内改变形参指针所指的地址,而是通过形参指针去改变其所指向的内存地址上的数据的值,这才是指针正确用法


而C语言指针参数传值的真相就是传入的指针只是原来指针的一个副本。


0 1