一级指针,二级指针在函数调用传址问题。在子函数中分配内存。

来源:互联网 发布:北京计算机编程培训学校 编辑:程序博客网 时间:2024/05/22 16:07

先说 int* q和 * q这两个式子中的 “ * ” 区别。

    前者中的 * 表示:声明q为一个指针,    后者中的 * 表示:把q当作地址,把这个地址中的东西取出来。

经常在C语言书上看到定义指针:

     int a=1;     int* p=&a;//如果把这里的 * 当作取地址中内容就错了。

等价定义:

     int a=1;     int* q;     q=&a;

有时候在想 假如定义了一个指针:int * q,那么这个q到底在内存中是个什么东西,q代表什么?

     我的理解是:只要你定义了一个指针,在对程序进行编译时,系统会为这个指针分配空间,注意:这个空间也会有个地址!这个空间代表q,q代表这个空间,这个空间的地址是&q。意思就是q和这个空间等价,这个指针也会有个地址。注意:这个空间也就是这个q只能存地址,不能存其他类型的东西。意思就是:这句话,int* q  表示这个空间q只能存地址,不能存其他东西!!!  而*q是整型的,可以存整型数。 int** p 表示这个空间p只能存地址的地址,既不能存地址,也不能存其他东西,*q只能存地址,不能存其他东西,**q可以存整型数。     例如:int* q =1;//会报错,因为这句话相当于两句话:           int* q;           q=1; //这个当然不对啦,q只能存地址,怎么能存整                  型数呢?

有时候我们需要在子函数中分配内存,然后希望在别的函数中使用这块内存。

  • 第一种是直接用返回值的办法,直接return这块内存的首地址。
  • 第二种是使用二级指针。为什么要用二级指针?上代码解析:
首先说这么写是错的,编译不会报错,运行会报错。下面有分析为什么?int main(int argc, char** argv) {    int *p;     Distribute(p);    printf("*p=%d\n",*p);    return 0;}void Distribute(int* q) {    q=(int*)malloc(sizeof(int));    printf("q=%d\n",q);}

很多像我这样的开始学C语言的人很容易犯这样的错误。
重点在这句话的理解:Distribute(p);传地址时在这句话里面有赋值运算int* q=p;等价于:int* q; q=p; 这两句。等于就是相当于把p空间赋值给了q空间。开始定义时,int* p ,p空间没有赋值,那么p空间是个垃圾值(&p是系统分配的不是垃圾值),是什么我也不知道。然后把这个垃圾值给了q,q也没觉得有啥不妥,就接受了。关键是,q在子函数中有了新欢,q得到了malloc给的值。p最后啥没有得到。所以在主函数中得不到这块内存的首地址。运行出错在于,竟然引用了p的值,就是在printf中打印*p的值,p空间是个垃圾值,把这个垃圾值作为地址,取出这个垃圾值的在内存中的东西,当然出错啦。

  • 第二种出错: 好了,好了,有人说我知道用二级指针了,但是还是错了,上代码:

用了二级指针还是错了??!! 编译没有问题,运行出错??!!int main(int argc, char** argv) {    int **p;     Distribute(p);    return 0;}void Distribute(int** q) {    *q=(int*)malloc(sizeof(int));}

-定义了 int** p,p空间是个垃圾值,然后传址时赋值:q=p, 此时q是个垃圾值, *q更怕不知道是什么,可怕的是:
q=(int )malloc(…) ?? 还给这个垃圾值代表的内存空间赋值??! 不错才怪。

    -

正确做法:

int main(int argc, char** argv) {    int *p;     Distribute(&p);    return 0;}void Distribute(int** q) {    *q=(int*)malloc(sizeof(int));}

定义了int* p , p是个指针,p的值是个垃圾值,而且p只能存地址。但是&p不是垃圾值啊,定义时,系统给了p空间,这个空间地址是存在的啊! 理解这一点特别重要。
还有,p是个指针,p空间只能存地址也就是p表示一个地址,&p表示的就是地址的地址。而int** q 这里的q空间只能存地址的地址,不正好吻合吗?传址时:int** q=&p;分解为两句话就是:int** q; q=&p; 完美啊!然后两边同时取运算:*q=(&p)也就是:*q=p; 也就是*q和p表示的同一个内存空间,你*q得到什么,我p就得到什么。然后在子函数中 :
q=(int)malloc(…) ,*q有了分配内存首地址,然后p也有了。在主函数中p就是分配内存的首地址。

阅读全文
0 0