最近在做一些笔试面试之类的题目,今天遇到一个关于C语言函数传参的问题,感觉自己的概念还是有点模糊,本篇文章再学一下关于函数传参。
这是遇到的一个题目:(高质量C++编程指南)
#include <stdlib.h>
#include <stdio.h
#include <string.h>
void GetMemory(char *p, int num)
{
p = (char *)malloc(sizeof(char) * num);
}
int main()
{
char *str = NULL;
GetMemory(str, 100);
strcpy(str, "hello");
printf("%s\n", str);
return 0;
}
首先malloc没有free,然后我们传过去的指针并没有被分配内存,由以下结果可见:
使用内存检测工具valgrind的结果:
下面具体分析一下这个程序:
当str传过去的时候,我们相当于执行了一个这样的操作:p = str,即将我们的str赋给p,然后我们给p动态分配一块内存,那么问题来了,p得到了内存,那么和我们的str有毛关系呀?!我们的str还是所谓的NULL。。。因此我们必须要传我们这个指针的地址过去嘛:
然后我们修改这个程序:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void GetMemory(char **p, int num)
{
*p = (char *)malloc(sizeof(char) * num);
}
int main()
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf("%s\n", str);
free(str);
return 0;
}
检测结果:
下面就谈一谈我们的函数传参的几种方式:
- 值传递
- 地址传递
- 引用传递
值传递
void Exchg1(int x, int y) //形参
{
int tmp;
tmp = x;
x = y;
y = tmp;
printf("x = %d, y = %d\n", x, y);
}
main()
{
int a = 4,b = 6;
Exchg1(a, b); //实参
printf("a = %d, b = %d\n", a, b);
return(0);
}
本段代码的结果显而易见,不可能将a,b的值交换出来。
我们和开始一样,人为替它加上几行代码,就清楚多了:
x = a;
y = b;
那么这里还是那个问题,无论x,y干嘛,都与a,b毫无瓜葛。如果我们要用值传递,必须要用返回值返回我们的改变的结果。
地址传递
void Exchg2(int *px, int *py)
{
int tmp = *px;
*px = *py;
*py = tmp;
printf("*px = %d, *py = %d.\n", *px, *py);
}
main()
{
int a = 4;
int b = 6;
Exchg2(&a, &b);
printf("a = %d, b = %d.\n”, a, b);
return(0);
}
如果不通过返回值来传递参数,那么我们就要传递实参的地址,因此交换的函数的形参应该改为指针,指针存储地址嘛,我们再人为加几行代码试试看:
px = &a;
py = &b;
这里px和py即是a和b的地址,因此我们对这俩地址操作,即是对a,b进行操作。
引用传递
void Exchg3(int &x, int &y) /* 注意定义处的形式参数的格式与值传递不同 */
{
int tmp = x;x = y;
y = tmp;
printf("x = %d, y = %d.\n", x, y);
}
main()
{
int a = 4;
int b = 6;
Exchg3(a, b); /*注意:这里调用方式与值传递一样*/
printf("a = %d, b = %d.\n”, a, b);
}
这里的取地址符其实在C++中是引用,人为操作一下:
&x = a;
&y = b;
这个操作称为引用,x、y分别引用了 a、b变量。这里仅适用于C++。