void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
本人在VC6.0运行失败,原因是不能读些0号内存
分析如下:
第一:char *str = NULL;
这里定义了变量str,同时给了初始值0
第二:函数调用语句GetMemory(str); 的确传递了参数,但是请注意,这里传递的是一个等于零的值。因为str=NULL; 在C语言里NULL就是0
第三:GetMemory(char *p)当程序执行到这里,系统产生了一个临时的变量p,这个变量是有实际地址的并且和str不在同一个位置。这个步骤很多人不清楚。
第四:p = (char *)malloc(100);这个语句可以正常运行。但是这里仅仅是修改了函数内的形式参数的值,就如同在传值调用情况下,修改形式参数不会更改实际参数一样。这里的p虽然给修改了,但是主函数里的str并没有被修改。
第五:回到主函数里,由于str的值依然是NULL,因此VC6.0运行strcpy失败
如果能在其他编译器运行成功,那么应该是编译器的问题
最后提示一个要点
所谓传值调用和传引用调用的定义是这样的
如果要传递变量a
那么,直接使用变量名,就是传值调用
如果传递的是a的地址,那么就是传地址调用
并且,不论传值还是地址,被调用函数的形式参数必然是处在和实际参数不同的另一个内存位置上的
回到本程序
我们传递的是字符型指针变量str,实际参数是变量名本身,因此这个参数的传递方式是传值调用,而不是传地址调用。
如果将str的地址作为参数传递本程序就可以在VC6.0内通过
具体程序如下:
#include<stdio.h>
#include<malloc.h>
#include<string.h>
void GetMemory(char **p)
{
*p = (char *)malloc(100);
//这个语句的等价含义其实就是 str=(char *)malloc(100);相信大家都能看懂
//因为二级指针p等于str的地址 p<=>&str 这里不是等于符号,是等价的意思,两边表达式的数据类型等价,下同
//对二级指针作取值运算就是一级指针 *(p)<=>*(&str)<=>str
}
void main()
{
char *str = NULL;
GetMemory(&str); //这里传递的是变量str的地址
strcpy(str, "hello world");
printf(str);
}