首页 新闻 会员 周边 捐助

why,到底是为什么

1
悬赏园豆:5 [已解决问题] 解决于 2013-12-25 11:51

1 #include <stdio.h>
2 #include <stdlib.h>
3 void f1(char **p){
4 char *p1 = (char*)malloc(100);
5 p = &p1;
6 }
7
8 void f2(char **p){
9 char *p1 = (char*)malloc(100);
10 *p = p1;
11 }
12
13 int main(){
14 char *p;
15 f2(&p);
16 free(p);
17
18
19 return 0;
20 }

 

 

为什么f2正常,f1是错误的

demps_c的主页 demps_c | 初学一级 | 园豆:128
提问于:2013-12-24 10:37
< >
分享
最佳答案
0

f1 和 f2 等同于下面的方法:

template<typename _Ty>

void f1(_Ty p){
  _Ty p1;
  p = p1;
  }

因此,使用替换法,设定 _Ty 为 int,那么我们可以写出 f3:

void f3(int p){
  int p1 = 10;
  p = p1;
  }

调用上述方法:

int p = 100;

f3(p);

现在 p 是多少?

收获园豆:5
Launcher | 高人七级 |园豆:45050 | 2013-12-24 11:30

我说的是指针的,这个应该弄个template<class *T> 吧

demps_c | 园豆:128 (初学一级) | 2013-12-24 11:43

@demps_c: 如果你这样来弄,而不是把指针也理解为一种类型,那么你可能永远不懂传值、传地址的区别。

Launcher | 园豆:45050 (高人七级) | 2013-12-24 11:53

@Launcher:f1,f2传的参数类型都是一样的,只是在函数内的有一些不一样,跟传址传参没关系吧

demps_c | 园豆:128 (初学一级) | 2013-12-24 12:01

@demps_c: 来,再给你添加个复杂的例子:

void f3(char *** p)
{
    char *p1 = (char*)malloc(100);
    char ** p2 = &p1;
    p = &p2;
}

void f4(char *** p)
{
    char *p1 = (char*)malloc(100);
    *p = &p1;
}

void f5(char *** p)
{
 char *p1 = (char*)malloc(100);
 **p = p1;
}
Launcher | 园豆:45050 (高人七级) | 2013-12-24 13:40

@Launcher: 4 char *p1 = (char*)malloc(100);
5 p = &p1;
6 }

此时因为p没有涉及到*和&,所以p此时跟地址无关,所以相当于传值

 

8 void f2(char **p){
9 char *p1 = (char*)malloc(100);
10 *p = p1;
11 }

此时使用了*,p就跟地址有关了,此时相当于传址对吗

demps_c | 园豆:128 (初学一级) | 2013-12-24 13:53

@demps_c: p = &p1 表示将变量 p1 的地址赋值给 p,而在 f1 中,p 是函数调用栈中的临时变量,也就是说在下面代码中(为了更清楚的表达,我把代码修改了下):

char * p = NULL;

char ** p2 = &p;

f1(p2);

f2(p2);

注意上面的代码,f1 中的 p 是 f1(p2) 中 p2 的副本,因此修改 p 的值(p=&p1),不影响 p2 的值,因此 f1 无法得到你想要的结果。f2 中的 p 仍然是 f2(p2) 中 p2 的副本,但是 *p 和 *p2 中保存的却是同一个指针,因此在 f2 中修改 *p 的值,就等同于修改了 *p2 的值,从而能得到你想要的结果。

调试的时候,注意观察 p,*p 的值在调用前,进入函数后,赋值后的变化,你就能明白了。

 

 

Launcher | 园豆:45050 (高人七级) | 2013-12-24 14:12

@demps_c: 为了让你更清楚的明白传值和传地址(传引用)的区别,我给你写了个你的 f1 函数的姐妹版:

void f11(char* & p)
{
    char * p1 = (char*)malloc(100);    
    p = p1;
}

int main()
{
   char * p = NULL;
   f11(p);
   return 0;
}
Launcher | 园豆:45050 (高人七级) | 2013-12-24 14:41

@Launcher: 彻底懂了

demps_c | 园豆:128 (初学一级) | 2013-12-25 11:49

@Launcher: 你的qq多少???能告诉我吗

demps_c | 园豆:128 (初学一级) | 2013-12-25 11:56
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册