- 论坛徽章:
- 0
|
大家都知道,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] |
|