2021-08-09-01 二级指针做输入内存模型-第一种01指针数组-分析及内存图

对指针数组进行排序

一、引入:

``可用于把*号表示出来。

(一)、char * myArray[4]:

1、优先级:()>[]>*
2、[ ]的优先级比*高,说明myArray是一个数组, char *说明这是一个字符型指针数组,它有4个指针类型的数组元素。
3、指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。
4、数组指针只是1个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。

1、myArray[0]、myArray[1]、myArray[2]、myArray[3]都是char *,他们是指向char类型的指针,并排在一起是一个数组。

2、这个数组装的内容是指针,也就是这个数组装的内容是地址。

3、*myArray[0]、*myArray[1],对指针取值取出来的都是char。

4、这里执行myArray+1,则myArray指向下一个数组元素。
myArray = a,这样的赋值是错误的,因为myArray是个不可知的表示,只存在myArray[0]、myArray[1]、myArray[2]…myArray[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 myArray=a,这里myArray表示指针数组第一个元素的值,myArray的首地址的值。

(二)、char ** 与char * myArray[ ]

 char *myArray[ ] = {"China","French","America","German"}

1、这是一个数组,每个数组的元素是一个char型指针,所以sizeof(myArray) = 16, 即4个指针的大小。指针都是占用4个字节,不管是什么类型的指针。

2、char **s 为二级指针, s保存一级指针 char *的地址。可以这样赋值 char **s = myArray; (myArray代表数组元素内存单元的首地址)。但是不能 myArray=s, 因为myArray相当于一个常量。

3、char**s = “hello world!” 这样赋值是错误的。因为s的类型是char **,即为二级指针,而 “hello world!” 的类型是char* ,虽然都是地址,但是指向的类型不一样。

4、因其本质上分析,"hello world!"代表一个地址,比如0x10000,这个地址中的内容是’h‘,为char型;而s也保存一个地址,这个地址中的内容是(*s)是char*型的,是一个指针类型,所以两者类型是不一样的

(三)、数组指针(也称行指针)

定义int (*p)[n]:

()的优先级高 ,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n, 也可以说p的步长是n。就是如果执行p+1,p要跨过n个整型数据的长度。

如果要把一个二维数组赋值给一个指针,应该这样赋值:

int a[3][4];

int (*p)[4]; //定义一个数组指针,指向含4个元素的1维数组

p=a; //将该二维数组的首地址赋给p,也就是a[0]&a[0][0]

p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][ ]指向了行a[1][]

二、例题分析

(一)指针数组排序的普通做法

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

void main()
{
	int		i = 0, j = 0;
	int		num = 0;
	char	*tmp = NULL;
	//数组 数组中的每一个元素是指针 指针数组
	char *myArray[] = {"aaaaaa", "ccccc", "bbbbbb", "111111"};
	
	//打印
	num = sizeof(myArray)/sizeof(myArray[0]);
	
	printf("排序之前\n");
	for (i=0; i<num; i++)
	{
		//printf("%s \n", myArray[i]);
		printf("%s \n", *(myArray+i) );
	}
	
	//排序
	for (i=0; i<num; i++)
	{
		for (j=i; j<num; j++)
		{
			if (strcmp(myArray[i], myArray[j]) > 0 )
			{
				tmp = myArray[i];  //注意  交换的是数组元素 交换的是指针的值
				myArray[i] = myArray[j];
				myArray[j] = tmp;
			}
		}
	}
	
	printf("\n排序之后\n");
	for (i=0; i<num; i++)
	{
		//printf("%s \n", myArray[i]);
		printf("%s \n", *(myArray+i) );
	}
	
	printf("hello...\n");
	system("pause");
	return ;
}

在这里插入图片描述

(二)指针数组做函数参数进行排序的做法

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

//编写一个打印函数
void printMyArray11(char **myArray, int num) //数组做函数参数退化为指针
{
	int i = 0;
	for (i=0; i<num; i++)
	{
		//printf("%s \n", myArray[i]);
		printf("%s \n", *(myArray+i) ); //将
	}
}

//编写一个排序函数
void sortMyArray11(char **myArray, int num)
{
	int i =0 , j = 0;
	char *tmp = NULL;
	
	//排序
	for (i=0; i<num; i++)
	{
		for (j=i; j<num; j++)
		{
			if (strcmp(myArray[i], myArray[j]) > 0 )
			{
				tmp = myArray[i];  //注意:交换的是数组元素 交换的是指针的值 //改变指针的指向
				myArray[i] = myArray[j];
				myArray[j] = tmp;
			}
		}
	}
}

void main()
{
	int		i = 0, j = 0;
	int		num = 0;
	char	*tmp = NULL;

	//数组中的每一个元素是指针,指针数组
	char *myArray[] = {"aaaaaa", "ccccc", "bbbbbb", "111111"};
	
	//打印数组
	num = sizeof(myArray)/sizeof(myArray[0]);
	
	printf("排序之前\n");
	printMyArray11(myArray, num);
	
	//对数组进行排序
	sortMyArray11(myArray, num);
	
	//排序后打印数组
	printf("\n排序之后\n");
	printMyArray11(myArray, num);
	
	printf("hello...\n");
	system("pause");
	return ;
}

在这里插入图片描述
注:
在地址传递方式中,传递给函数的是指向初始数组的指针,不用复制初始数组,因此程序变得精练和高效,并且也节省了栈中的内存空间。在地址传递方式中,只需在函数原型中将函数的参数说明为指向数组元素数据类型的一个指针

(三)内存分析图-指针数组做函数参数进行排序的做法

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

//编写一个打印函数
void printMyArray11(char **myArray, int num) //数组做函数参数退化为指针
{
	int i = 0;
	for (i=0; i<num; i++)
	{
		//printf("%s \n", myArray[i]);
		printf("  &myArray[%d] = %p, myArray[%d]中存放的地址【%p】指向的字符串=%s \n", 
			i, &myArray[i], i, myArray[i], *(myArray+i)); //将
	}
	printf("\n字符串常量的地址,指针数组存放的地址\n");
	printf("  &aaaaaa=%p  \n", &"aaaaaa" );
	printf("  &ccccc=%p  \n", &"ccccc" );
	printf("  &bbbbbb=%p  \n", &"bbbbbb" );
	printf("  &111111=%p  \n\n", &"111111" );

}

//编写一个排序函数
void sortMyArray11(char **myArray, int num)
{
	int i =0 , j = 0;
	char *tmp = NULL;
	
	//排序
	for (i=0; i<num; i++)
	{
		for (j=i; j<num; j++)
		{
			if (strcmp(myArray[i], myArray[j]) > 0 )
			{
				printf("外层循环第%d次,内层循环第%d次\n", i, j);
				printf(" myArray[%d]=[%p]指向字符串=%s|| myArray[%d]=[%p]指向字符串=%s \n", 
			i, myArray[i], *(myArray+i), j, myArray[j], *(myArray+j));

				tmp = myArray[i];  //注意:交换的是数组元素 交换的是指针的值 //改变指针的指向
				myArray[i] = myArray[j];
				myArray[j] = tmp;

				printf("本次交换后\n");
				printf(" myArray[%d]=[%p]指向字符串=%s|| myArray[%d]=[%p]指向字符串=%s \n", 
			i, myArray[i], *(myArray+i), j, myArray[j], *(myArray+j));
				printf("..................................................\n\n");
			}
		}
	}
	printf("==============================================================================================================\n\n");
}

void main()
{
	int		i = 0, j = 0;
	int		num = 0;
	char	*tmp = NULL;
	
	//数组中的每一个元素是指针,指针数组
	char *myArray[] = {"aaaaaa", "ccccc", "bbbbbb", "111111"};
	
	printf("创建指针数组后,立马打印数组元素的相关信息\n");
	
	printf("  &myArray[0]=%p\t myArray[0]=%p\t &aaaaaa=%p  \n", &myArray[0], myArray[0], &"aaaaaa" );
	printf("  &myArray[1]=%p\t myArray[1]=%p\t &ccccc=%p  \n", &myArray[1], myArray[1], &"ccccc" );
	printf("  &myArray[2]=%p\t myArray[2]=%p\t &bbbbbb=%p  \n", &myArray[2], myArray[2], &"bbbbbb" );
	printf("  &myArray[3]=%p\t myArray[3]=%p\t &111111=%p  \n\n", &myArray[3], myArray[3], &"111111" );
	
	
	//计算循环次数
	num = sizeof(myArray)/sizeof(myArray[0]);
	
	//打印数组
	
    printf("=======================================================\n");

	printf("\n排序之前\n");
	printMyArray11(myArray, num);

	printf("==============================================================================================================\n");
	
	//对数组进行排序
	sortMyArray11(myArray, num);
	
	//排序后打印数组
	printf("\n排序之后\n");
	printMyArray11(myArray, num);
	
	
	
	printf("hello...\n");
	system("pause");
	return ;
}

在这里插入图片描述
内存分析
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大大枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值