您的位置:首页 > 其它

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

2017-12-13 21:51 344 查看
先说 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就是分配内存的首地址。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐