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

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

大家都知道,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);