免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3689 | 回复: 9
打印 上一主题 下一主题

[函数] 函数调用时的参数传递研究 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-07-24 09:56 |只看该作者 |倒序浏览
大家都知道,c函数调用时有两种方法:值传递和址传递:
值传递,如:
void swap(int a, int b)

{
    int temp;
    temp=a;
    a=b;
    b=temp;
}

void Test(void)
{
    int m(5),n(9);
    swap(m,n);
}
函数的执行结果大家一定都很清楚,调用函数test中的m,n没有发生变化,而被调用函数swap中的局部变量a,b被交换.
址传递,如:
void swap(int *a, int* b)

{
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;
}

void Test(void)
{
    int m(5),n(9);
    swap(&m,&n);
}
完成类似的功能,但是无论是调用函数还是被调用函数中的变量内容都被交换.
看上去很简单,是吧,那么下面这个例子是值传递还是址传递呢?
void GetMemory(char *p, int num)

{

    p = (char *)malloc(sizeof(char) * num);

}

void Test(void)

{

    char *str = NULL;

    GetMemory(str, 100);    // str 仍然为 NULL  

    strcpy(str, "hello";   // 运行错误

}
答案是值传递,大家一定会问了,明明传递的是指针,为什么是值传递呢, 其实在编译器中到底是值传递还是址传递并不是看传递的是不是指针,而是看调用函数中(test)的实际参数是变量本身还是变量的地址,这个变量可以是int,float,char,也可以是指针int*,float*,char*,在这个例子中,传递的是指针变量char* str,所以是值传递,弄清楚了值传递还是址传递有什么意义呢,准确的区分两者的区别对于我们实现高质量的编程很重要.值传递时,编译器简单地为实际参数做一个备份,完成被调用函数地功能;址传递在两种情况下使用:
1.需要将一个较大地对象或者实例作为参数传给被调用函数的情况
2.当参数值必须被修改后返回的情况
第一种情况实际就是我们上面的例子,严格的来说,它是值传递,我把它叫做伪址传递,对于第二种情况,大家肯定都遇到过这种使用方法,如下面的例子:
void GetMemory2(char **p, int num)

{

    *p = (char *)malloc(sizeof(char) * num);

}

void Test2(void)

{

    char *str = NULL;

    GetMemory2(&str, 100);  // 注意参数是 &str,而不是str

    strcpy(str, "hello";   

    cout<< str << endl;

    free(str);  

}
在这个例子中str在被调用函数中动态分配了内存,在调用函数test中使用了在GetMemory2中被修改的参数,大家在实际情况中会遇到很多类似的使用.很遗憾,对于值传递,址传递一般的c教程中都未能对以上这种差别作出区分,而这些差别又会给初学者很大的误导,希望大家小心区分

[url][/url]

论坛徽章:
0
2 [报告]
发表于 2003-07-24 12:15 |只看该作者

函数调用时的参数传递研究

**p 可以认为是*p的地址传递吧

刚开始时我也不知道要什么返回指针 后来试过多次后才知道应该使用二级指针的形式 当然如果要返回二级指针的值那么应该使用三级指针了

以此类推

这个对C语言开发的比较有用 就转到C版吧     让更多的人分享你的知识

论坛徽章:
0
3 [报告]
发表于 2003-07-24 13:01 |只看该作者

函数调用时的参数传递研究

原帖由 "lhftonny" 发表:


答案是值传递,大家一定会问了,明明传递的是指针,为什么是值传递呢, 其实在编译器中到底是值传递还是址传递并不是看传递的是不是指针,而是看调用函数中(test)的实际参数是变量本身还是变量的地址,这个变量可以是int,float,char,也可以是指针int*,float*,char*,
   

怎么分清楚对于char * a而言:
func(a)是传递的a本身还是a的地址?   

对于上面那个例子,如果改成:

  1. void swap(int *a, int* b)

  2. {
  3. int temp;
  4. temp=*a;
  5. *a=*b;
  6. *b=temp;
  7. }

  8. void Test(void)
  9. {
  10. int *m,*n;
  11. m=(int *) malloc(1);
  12. n=(int *)malloc(1);
  13. *m=5;*n=9;
  14. swap(m,n);
  15. free(m);
  16. free(n);
  17. }
复制代码


m和n不还是地址传递吗?
swap并没有定义成二级指针啊?
原来一直认为指针一定是地址传送,现在知道不对,但怎么理解呢?那位能详细解释一下.

论坛徽章:
0
4 [报告]
发表于 2003-07-24 13:17 |只看该作者

函数调用时的参数传递研究

呵呵,指针的值是一个地址,所以你说地址传递是指的指针的内容,其实就是指针变量的值。
关于指针的理解我在一个帖子里仔细论述过,被无双删了。

论坛徽章:
0
5 [报告]
发表于 2003-07-24 13:41 |只看该作者

函数调用时的参数传递研究

谢谢楼上的回答,偶有些明白了,偶上面说的那个是值传送,只不过这个值是个地址而以。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
6 [报告]
发表于 2003-07-24 13:52 |只看该作者

函数调用时的参数传递研究

楼主的分析有一定的参考价值。
fieryfox 所说的理解是什么?

论坛徽章:
0
7 [报告]
发表于 2003-07-24 14:15 |只看该作者

函数调用时的参数传递研究

是啊,把你那个理解贴出来看看。

论坛徽章:
0
8 [报告]
发表于 2003-07-24 16:07 |只看该作者

函数调用时的参数传递研究

感谢大家的捧场,看来大家都注意导这个问题了,对于li2002的问题,char * a,定义了a是一个char*的指针,而函数func(a)直接调用了该变量(在这里,这个变量是一个指针),所以应该叫做值传递,不具备返回参数的功能.
对于我上面的问题,有一点补充,一般情况下,对于一个函数而言,如果需要返回参数的时候,推荐使用返回值来表示函数的执行结果,对于返回的参数,则使用我上面说的址传递的第二种情况,当然这也不是绝对的,只是一个大的原则,参见thinking in c++,例子可以参考我的第3 个示例,谢谢大家!

论坛徽章:
0
9 [报告]
发表于 2003-07-24 19:39 |只看该作者

函数调用时的参数传递研究

#include <stdio.h>;

struct A {
        char *a;
};

int getmemory(struct A *a, int num)
{
        a->;a=(char *) malloc(num);
        return 0;
}

main() {
        struct A a;
        getmemory(&a, 100);
        strcpy(a.a, "hello";
        printf("%s", a.a);
        free(a);
}

论坛徽章:
0
10 [报告]
发表于 2003-07-25 08:56 |只看该作者

函数调用时的参数传递研究

是呀,历历1979的例子和我下面的这个例子不是一样吗.
void CAboutDlg::GetMemory(char* p,int len)
{
        p=(char*)malloc(sizeof(char)*len);
}
void CAboutDlg::OnOK()
{
        char  str=0;
        GetMemory(&str,100);
        memcpy(&str,"hello",6);
        free(&str);
        str=NULL;
        CDialog::OnOK();
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP