写这一篇博客的主要目的是记录在C语言编程的过程中,碰到的一些奇怪的关于指针的问题,通过对指针这一C语言特色变量的研究,为以后编写更为稳定的程序打下良好的基础,主要介绍了指针在函数值传递、地址转换等方面的相关陷阱!
一、指针变量&函数形参
1.首先如下所示为基本的函数形参指针传递值过程:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int point(int *val){ 5 printf("Address Of ParamA=%x ",val); // Print the param val's address. 6 *val = 10; // Change the value of val var. 7 } 8 int main(void) 9 { 10 int A = 1; 11 printf("A=%d Address=%x ",A,&A); // Print the val and the Address of A. 12 point(&A); 13 printf("A'=%d Address'=%x ",A,&A); // Print the val and the Address of A. 14 }
如下所示为运行的结果:
val的地址应该是&val,而函数中打印的是val地址中的内容,也就是A的地址了。
这里我们可以看到,形参指向的地址0x65fe1c和main函数中A指向的地址是相同的,这里值得注意的是,对于A地址变量和val地址变量而言,其自身的存储地址是不同的,而地址中保存的指向a变量的地址是相同的,都是0x65fe1c,其自身的地址如下所示:
#include <stdio.h> #include <stdlib.h> int point(int *val){ printf("Address Of ParamA=%x ",&val); // Print the param val's address. *val = 10; // Change the value of val var. } int main(void) { int *A; int a = 1; A = &a; printf("A=%d Address=%x ",*A,&A); // Print the val and the Address of A. point(A); printf("A'=%d Address'=%x ",*A,&A); // Print the val and the Address of A. }
Notice:运行的结果如下,这里可以看到形参的地址和main中A的地址是不同的,当然他们指向了同一个地址空间,这就是为什么指针传递能够改变数值,因为传到函数中的地址是待改变的var变量的地址,因此完成了数值的改变,这也就是所谓的形参实际上是地址参数的一个副本,他不是完全相同的,而是地址不同,指向地址相同的两个不同的变量,当函数完成以后,这个形参地址变量副本将会被回收。
形参地址和传入地址变量的地址不同。
同时可以看到,通过在函数中改变val 的值确实达到了传递参数的效果。
2.在函数中改变形参指向地址的陷阱
1 #include <stdio.h> 2 3 int point(int *val){ 4 int *P = (int *)malloc(sizeof(int)*3); // Alloc a new mem in func-point 5 printf("Address Of ParamA=%x ",val); // Print the param val's address. 6 *P = 10; 7 val = P; 8 printf("Address Of ParamA=%x ",val); // Print the param val's address. 9 } 10 int main(void) 11 { 12 int *A; 13 int a = 1; 14 A = &a; 15 printf("A=%d Address=%x ",*A,&A); // Print the val and the Address of A. 16 point(A); 17 printf("A'=%d Address'=%x ",*A,&A); // Print the val and the Address of A. 18 }
程序运行结果如下所示:
可以看到在主函数中显示的A的地址0x65fe18居然不等于函数形参未改变之前的地址0x65fe14,经过Debug对程序进行调试,发现地址起始是一样的,都是0x65fe14,至于为什么会出现打印结果和Debug结果的不同还有待分析。
重要的是,在值传递之前,对形参中指向的地址进行了重新的赋值,此时形参副本将不会指向外部数据的地址,从此无法改变外部数据值,从而无法完成值传递,因此,一定要注意对形参进行指针赋值的情况,否则将造成数据无法传递的情况。(此时新的地址0x7713f0指向的地址的内容为10.)
二、数组地址值传递及分析
1.二维数组&多维数组的构造方式
2.如何传递数组到函数中
未完待续!