先来看一段代码:
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语言指针参数传值的真相就是传入的指针只是原来指针的一个副本。