首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

函数调用时的参数传递研究(强烈推荐),该怎么处理

2012-02-03 
函数调用时的参数传递研究(强烈推荐)函数调用时的参数传递研究大家都知道,c函数调用时有两种方法:值传递和

函数调用时的参数传递研究(强烈推荐)
函数调用时的参数传递研究

大家都知道,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教程中

都未能对以上这种差别作出区分,而这些差别又会给初学者很大的误导,希望大家小心区分:)  

 

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

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

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

以此类推  


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

-->          

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

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

[code]   void   swap(int   *a,   int*   b)  

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

void   Test(void)  
{  
int   *m,*n;
m=(int   *)   malloc(1);


n=(int   *)malloc(1);
*m=5;*n=9;
swap(m,n);
free(m);
free(n);  
}   [/code]

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

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

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

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

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

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

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

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

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

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

感谢大家的捧场,看来大家都注意导这个问题了,对于li2002的问题,char   *   a,定义了a是一个char*的指针,而函数func(a)直接调用了该变量(在这里,这个变量是一个指针),所以应该叫做值传

递,不具备返回参数的功能.
对于我上面的问题,有一点补充,一般情况下,对于一个函数而言,如果需要返回参数的时候,推荐使用返回值来表示函数的执行结果,对于返回的参数,则使用我上面说的址传递的第二种情况,当

然这也不是绝对的,只是一个大的原则,参见thinking   in   c++,例子可以参考我的第3   个示例,谢谢大家!:)  

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

#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);
}
:P  

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

是呀,历历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();
}

[解决办法]
有价值, 顶

热点排行