C语言指针及陷阱

写这一篇博客的主要目的是记录在C语言编程的过程中,碰到的一些奇怪的关于指针的问题,通过对指针这一C语言特色变量的研究,为以后编写更为稳定的程序打下良好的基础,主要介绍了指针在函数值传递、地址转换等方面的相关陷阱!

一、指针变量&函数形参

1.首先如下所示为基本的函数形参指针传递值过程:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int point(int *val){
 5     printf("Address Of ParamA=%x\n",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\n",A,&A); // Print the val and the Address of A.
12     point(&A);
13     printf("A'=%d Address'=%x\n",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\n",&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\n",*A,&A); // Print the val and the Address of A.
    point(A);
    printf("A'=%d Address'=%x\n",*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\n",val); // Print the param val's address.
 6     *P = 10;
 7     val = P;
 8     printf("Address Of ParamA=%x\n",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\n",*A,&A); // Print the val and the Address of A.
16     point(A);
17     printf("A'=%d Address'=%x\n",*A,&A); // Print the val and the Address of A.
18 }

程序运行结果如下所示:

 可以看到在主函数中显示的A的地址0x65fe18居然不等于函数形参未改变之前的地址0x65fe14,经过Debug对程序进行调试,发现地址起始是一样的,都是0x65fe14,至于为什么会出现打印结果和Debug结果的不同还有待分析。

重要的是,在值传递之前,对形参中指向的地址进行了重新的赋值,此时形参副本将不会指向外部数据的地址,从此无法改变外部数据值,从而无法完成值传递,因此,一定要注意对形参进行指针赋值的情况,否则将造成数据无法传递的情况。(此时新的地址0x7713f0指向的地址的内容为10.)

二、数组地址值传递及分析

1.二维数组&多维数组的构造方式

2.如何传递数组到函数中

 

未完待续!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章