1、主函数 被调函数
(1)主调函数可以把堆区、栈区、全局数据内存地址传给被调用函数。
(2)被调用函数只能返回堆区、全局数据(因为栈区数据在被调函数结束后已经被析构掉)
2、内存分配方式
指针做函数参数,是有输入和输出特性的。
(1)指针的输入:在主调用函数中分配的内存,然后把这块内存传递给被调用函数的用法。
(2)指针的输出:在被调用函数中分配内存,把结果写入已分配的内存中,然后让主调用函数使用。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
//函数参数 char **myp1 表示定义了一个2级指针
//主函数调用该函数时,把指针p1的地址作为实参传给了myp1,相当于 myp1=&p1;
int getMem2( char **myp1/*OUT 2级指针做输出,在被调函数中修改实参1级指针的值*/, int *mylen1/*OUT 1级指针做输出,在被调函数中修改实参的值*/, char **myp2/*OUT*/, int *mylen2/*OUT*/ )
{
int ret = 0;
char *tmp1,*tmp2;
tmp1 = (char *)malloc(100);
strcpy(tmp1,"123456789");
//间接赋值
*mylen1 = strlen(tmp1); //1级指针
*myp1 = tmp1; //2级指针
tmp2 = (char *)malloc(200);
strcpy(tmp2,"asdsffffdf");
//间接赋值
*mylen2 = strlen(tmp2); //1级指针
*myp2 = tmp2; //2级指针
printf("tmp2:%s\n",tmp2);
printf("*myp2:%s\n",*myp2);
return ret;
}
char * getMem(int num)
{
int ret = 0;
char *tmp1;
tmp1 = (char *)malloc(num);
strcpy(tmp1,"123456789");
return tmp1;
}
void main()
{
int ret = 0;
char *p1 = NULL; //1级指针
int len1 = 0;
char *p2 = NULL; //2级指针
int len2 = 0;
char **p3 = NULL;
p1=0x11;
p3=0x22;
//直接修改p1的值
p1 = 0x111;
//间接修改p1的值
p3 = &p1;
*p3 = 100; //间接赋值,p3是p1的地址
printf("p1:%d\n",p1); //打印的是指针变量p1的值,而不是p1指向的内存空间,因为还没有分配空间,打印会宕机
{
*p3 = 200; //间接赋值,p2是p1的地址
printf("p1:%d\n",p1); //打印的是指针变量p1的值,而不是p1指向的内存空间,因为还没有分配空间,打印会宕机
}
ret = getMem2(&p1,&len1,&p2,&len2); //调用函数以后,p1即指向函数中分配的大小为100的内存空间
//p2指向函数中分配的大小为200的内存空间
if( 0 != ret )
{
printf("func getMem2() err:%d\n",ret);
return ret;
}
printf("p1:%s, len1:%d, p2:%s, len2:%d\n",p1,len1,p2,len2);
//释放函数getMem2中分配的内存空间(即主函数中p1、p2所指向的内存空间)
if( NULL != p1 )
{
free(p1);
p1=NULL;
}
if( NULL != p2 )
{
free(p2);
p2=NULL;
}
p1 = getMem(100);
printf("p1:%s\n",p1);
if( NULL != p1 )
{
free(p1);
p1=NULL;
}
system("pause");
return;
}