3.2 二级指针

本文详细介绍了指针在输入输出中的作用,包括指针作为输入时由主调函数分配内存,作为输出时由被调函数分配内存。接着,通过实例展示了二级指针作为输入的内存模型,包括指针数组和动态内存分配。同时,讨论了指针作为函数参数的两种内存模型,分别演示了如何对字符串数组进行排序。最后,提供了综合练习,将不同内存模型的数据进行拷贝和排序。文章深入浅出地探讨了C语言中指针与内存管理的技巧。
摘要由CSDN通过智能技术生成

3.1 指针的输入输出模型

        指针做输入:主调函数分配内存

        指针做输出:被调函数分配内存

3.2 二级指针做输入的第一种内存模型

·        1.指针数组:数组中的每一个元素都是一个指针

                   形如:char *myArray[] = {"aaa",bbb","ccc","ddd"};

                  内存模型:

                注:1)myArray代表 数组myArray的首地址;

                        2)*myArray等价于myArray[0],若以%s的形式输出,则输出myArray[0]中保存的地址中所存储的元素,即打印“aaa”。若以%d的形式输入,则打印的是0x2233即myArray[0]中保存的地址。

                       3) *(myArray+1)等价于myArray[1] ;

        2.定义函数实现{ "xxxx","bbbb","gggg","dddd" }的排序操作

int sortArray(char **initArray,int num)
{
	int ret = 0;
	int i, j;
	char* temp=NULL;
	if (*initArray == NULL)
	{
		ret = -1;
		return ret;
	}

	//排序
	for (i = 0; i < num; i++)
	{
		for (j = i + 1; j < num; j++)
		{
			if (strcmp(initArray[i], initArray[j]) > 0)//比较内存指向的数据
			{
                //交换数组中保存的内存地址,相当于改变指针的指向
				temp = initArray[i];
				initArray[i] = initArray[j];
				initArray[j] = temp;
			}
		}
	}
	return ret;
}
void printArray(char** initArray,int num)
{

	int i, j;
	for (i = 0; i < num; i++)
	{
		printf("%s\n", initArray[i]);
	}
}
void main()
{
	//数组   数组中的每一个元素是指针   指针数组

	int ret = 0;
	char* myArray[] = { "xxxx","bbbb","gggg","dddd" };
	int num = sizeof(myArray) / sizeof(myArray[0]);
	//打印


	printf("排序前:\n");
	printArray(myArray, num);
	//排序
	ret = sortArray(myArray, num);

	printf("排序后:\n");
	printArray(myArray,num);
	system("pause");
	return;
}

        内存模型示例:

         

3.3 指针做函数参数的第二种内存模型

1.内存模型的实例图

        

2.定义函数实现{ "xxxx","bbbb","gggg","dddd" }的排序操作

int sortArray1(char initArray[10][30], int num)
{
	int ret = 0;
	char tempBuf[30];
	int i, j;
	if (initArray == NULL)
	{
		ret = -1;
		return ret;
	}
	for (i = 0; i < num; i++)
	{
		for (j = i + 1; j < num; j++)
		{
			if (strcmp(initArray[i], initArray[j]) > 0)
			{
				strcpy(tempBuf, initArray[i]);//交换的内存块的数据
				strcpy(initArray[i], initArray[j]);
				strcpy(initArray[j], tempBuf);

			}
		}
	}
	return ret;
}
void printArray1(char initArray[10][30], int num)
{
	int i;
	for (i = 0; i < num; i++)
	{
		printf("%s\n", *(initArray + i));
        //printf("%s\n", initArray[i]);
	}
}
void main()
{
	int ret = 0;
	int num = 4;
	char myArray[10][30]={"ssss","2222","gggggg","88888"};
	//打印操作
	printf("排序之前:");
	printArray1(myArray, num);

	
	//排序操作
	printf("排序之后:");
	ret=sortArray1(myArray,num);


	printf("排序之后:\n");
	printArray1(myArray, num);
	system("pause");
	return;
}

3.4 二级指针做输入的第一种内存模型 

        1.内存模型实例图

 2.封装函数实现第三种内存模型

//内存开辟函数
char** signMemo(int num)
{
	int i;
	char** p = NULL;
	//开辟一级数组内存块,数组中存储的地址
	p = (char**)malloc(sizeof(char*) * num);
	//开辟二级数组内存
	for (i = 0; i < num; i++)
	{
		p[i] = (char*)malloc(sizeof(char) * 100);
		//初始化内存数组
		sprintf(p[i], "%d%d%d", i + 1, i + 1, i + 1);
	}
	return p;
}
//输出函数
void printArr(char** initArr, int num)
{
	int i;
	for (i = 0; i < num; i++)
	{
	//	printf("%s\n", initArr[i]);
		printf("%s\n", *(initArr + i));
	}
}
//排序算法
int sortArr(char** initArr, int num)
{
	int i,j;
	char* temp;
	char tempBuf[100];//交换数据的临时变量
	/*交换数据的排序*/
	/*
	for (i = 0; i < num; i++)
	{
		for (j = i + 1; j < num; j++)
		{
			if (strcmp(initArr[i], initArr[j]) < 0)
			{
				strcpy(tempBuf, initArr[i]);
				strcpy(initArr[i], initArr[j]);
				strcpy(initArr[j], tempBuf);

			}
		}
	}
	*/
	
	//交换内存地址实现排序
	for (i = 0; i < num; i++)
	{
		for (j = i+1; j < num; j++)
		{
			if (strcmp(initArr[i], initArr[j]) < 0)
			{
				temp = initArr[i];
				initArr[i] = initArr[j];
				initArr[j] = temp;
			}
		}
	}
}
//内存空间的释放
void free_Memo(char** p,int num)
{
	int i;
	//释放第二层内存
	for (i = 0; i < num; i++)
	{
		if (p[i] != NULL)
		{
			free(p[i]);
			p[i] = NULL;
		}
	}
	//释放第一层内存
	if (p != NULL)
	{
		free(p);
		p = NULL;
	}

}
void main()
{
	char** p = NULL;
	int num = 5;
	int i,j;
	char* temp;//交换内存地址的临时变量
	p = signMemo(num);

	printf("排序前:\n");

	//调用打印函数
	printArr(p, num);
	
	//调用排序函数
	sortArr(p, num);
		
	printf("排序后:\n");
	//调用打印函数
	printArr(p, num);

	//释放堆区内存
	free_Memo(p, num);
	system("pause");
	return;
}

3.5二级指针综合练习 

示例1:将二级指针的第一种和第二种内存模型数据拷贝到第三种内存模型中,并进行排序

int sortArray(char** firPoint/*in*/, int firCount, char(*secPoint)[30]/*in*/, int secCount, char*** thiPoint/*out*/, int* thiCount)
{
	int ret = 0;//函数返回值
	int i = 0,j=0;
	//判断传入的地址是否为空
	if (firPoint == NULL || secPoint == NULL || thiPoint == NULL)
	{
		ret = -1;
		return ret;
	}
	int count=0;//统计firCount+secCount
	count = firCount + secCount;
	*thiCount = count;
	//开辟内存空间
	char** tempMome = NULL;
	tempMome = (char**)malloc(count * sizeof(char*));//开辟内存空间
	for (i = 0; i < count; i++)
	{
		tempMome[i] = (char*)malloc(60);
		if (i <= firCount - 1)
		{
			strcpy(tempMome[i], firPoint[i]);
		}
		else
		{
			strcpy(tempMome[i], secPoint[j]);
			j++;
		}
		
	}
	
	//排序操作
	char tempStr[60] ;
	//tempStr = (char*)malloc(60);
	
	for (i = 0; i < count; i++)
	{
		for (j = i + 1; j < count; j++)
		{
			if (strcmp(tempMome[i], tempMome[j]) > 0)
			{
				//修改指针指向空间的数据
				strcpy(tempStr ,tempMome[i]);
				strcpy(tempMome[i], tempMome[j]);
				strcpy(tempMome[j], tempStr);
				//修改指针的指向
				/*
				* tempStr=tempMome[i];
				* tempMome[i]= tempMome[j];
				* tempMome[j]= tempStr;
				*/
			}
		}
	}
	*thiPoint = tempMome;
	return ret;
}
void printArray(char** p, int count)
{
	int i = 0;

	for (i = 0; i < count; i++)
	{
		printf("%s\n", p[i]);
	}
}
void freeMomery01(char** p, int count)
{
	int i = 0;
	if (p == NULL)
	{
		return;
	}
	for (i = 0; i < count; i++)
	{
		free(p[i]);
	}
	free(p);
}
void freeMomery02(char*** p, int count)
{
	int i = 0;
	if (p == NULL)
	{
		return;
	}
	char** temp = NULL;
	temp = *p;//还原成2级指针
	if (temp == NULL)
	{
		return;
	}
	for (i = 0; i < count; i++)
	{
		free(temp[i]);
	}
	free(temp);
	*p = NULL;

}
int  main()
{
	int ret = 0;
	char* firMome[] = { "asd","xfg","dga","ygf" };//指针数组
	char secMome[10][30] = { "4545","23345","3434" };
	char** thiMome = NULL;
	int len1, len2, len3;
	len1 = sizeof(firMome) / sizeof(*firMome);
	len2 = 3;
	len3 = 0;
	ret = sortArray(firMome, len1, secMome, len2, &thiMome, &len3);
	if (ret != 0)
	{
		printf("err: func sortArray():%d", ret);
		return ret;
	}
	printArray(thiMome, len3);
	freeMomery01(thiMome, len3);
	printf("hello...\n");
	system("pause");
	return;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值