连续储存数组


一.数组

  • 存放类型相同,大小相等的元素

二.代码部分

1.对于传参

#include<stdio.h>

struct Arr{
	int *pBase;	//存储的是数组第一个元素的地址 
	int len;	//数组所能容纳的最大元素的个数 
	int cnt;	//当前数组有效元素的个数 
};

void initArr(struct Arr *pArr);

int main(void)
{
	struct Arr arr;
	
	initArr(&arr);				//地址只用第一个字节的地址表示,第一个字节的地址占4个字节 
	printf("%d\n",arr.len);
}

void initArr(struct Arr *pArr)	//此时指向arr的第一个地址,现在pArr存放的是arr第一个字节的地址 
{
	(*pArr).len=99;
}
initArr(&arr);
/*
对于这一行,如果写的是👇
initArr(arr);
在定义变量时传参传的是(struct Arr array)
此时返回到主函数里的arr的len是垃圾值,因为是静态分配内存,当调用完initArr之后传参的就不存在了
所以要用到"&arr",将指针的地址传给initArr中
那么在initArr函数里,*pArr就是arr
这样做的优点:对比用arr传参(需要用到12个字节),这样子传参省空间(arr的第一个地址只占4个字节)
*/

2.对结构体的理解

struct Arr{
	int *pBase;	//存储的是数组第一个元素的地址 
	int len;	//数组所能容纳的最大元素的个数 
	int cnt;	//当前数组有效元素的个数 
};

👉因为数组名就是数组首地址元素,所以在定义int *pBase 时,pBase是指针变量,也就是地址,同时它是一个数组名

👉其实也可以理解为,这个结构体,主体部分是pBase,其他成员是这个数组的一些属性的说明

👉为了把这些属性和数组主体联系起来,搞了一个结构体把它们放在一起

3.初始化

void initArr(struct Arr *pArr,int length)//此时指向arr的第一个地址,现在pArr存放的是arr第一个字节的地址 
{
	pArr->pBase=(int*)malloc(sizeof(int)*length); 
	if(NULL==pArr->pBase)
	{
		printf("动态内存分配失败!\n");
		exit(-1);
	}
	else
	{
		pArr->len=length;
		pArr->cnt=0;
	}
	return;//告诉程序这个函数结束了 
}

👉pBase是一个数组,先给他分配空间

  • 对pBase内存是否分配成功要做一个判定
  • 判定成功了就给他这个结构体赋值

4.打印

void showArr(struct Arr *pArr)
{
	if(isEmpty(pArr))
	{
		printf("数组为空!\n");
	}
	else
	{
		for(int i=0;i<pArr->cnt;++i)
		{
			printf("%d ",pArr->pBase[i]);
		}
			
		printf("\n");
			
	}
}

5.判断数组里是否有元素

bool isEmpty(struct Arr *pArr)
{
	if(pArr->cnt==0)
		return true;
	else
		return false;	
}

6.判断数组是否是满的

bool isFull(struct Arr *pArr)
{
	if(pArr->cnt==pArr->len)
		return true;
	else
		return false;	
}

7.追加元素

bool appendArr(struct Arr *pArr,int val)//val是要加入的元素
{
	//满时返回false,不加
	if(isFull(pArr))
		return false;
	//不满时追加
	pArr->pBase[pArr->cnt]=val; 
	(pArr->cnt)++;
}

👉cnt的值=最后一个元素的下标+1

👉最后记得要给有效值+1

8.插入元素

bool insertArr(struct Arr *pArr,int pos,int val)
{
	int i;
	
	if(isFull(pArr))
		return false;
	
	if(pos<1||pos>pArr->cnt+1)
		return false;
	 
	for(i=pArr->cnt-1;i>=pos-1;--i)
	{
		pArr->pBase[i+1]=pArr->pBase[i];
	}
	pArr->pBase[pos-1]=val;
	(pArr->cnt)++;
	return true;
} 
  • 满了、输入的位置不符合数组现有的→返回错误,在主程序里不执行

👉对于for里的

  • i=pArr->cnt-1 i对应着下标
  • i=pos-1 插入时只变动要插入位置的该位上和该位后的元素
  • —i 进行插入的逻辑是,先对最后一位操作,最后一位先往后移动,然后前面的再往后移动,最后空出一个位置给要插入的元素插入

👉然后

  • 前一个元素移动到后一个元素上

  • 放置新元素

  • 有效值+1

9.删除元素

bool deleteArr(struct Arr *pArr,int pos,int *pVal)
{
	int i; 
	if(isEmpty(pArr))
		return false;
	if(pos<1||pos>pArr->cnt)
		return false;
		
	*pVal=pArr->pBase[pos-1];
	for(i=pos;i<pArr->cnt;++i)
	{
		pArr->pBase[i-1]=pArr->pBase[i];
	}
	pArr->cnt--;
	return true;
}
  • 空的、输入不符合数组现有的→返回错误,再主程序中不执行

感觉跟插入一个意思….

10.元素倒置

void inversionArr(struct Arr *pArr)
{
	int i=0;
	int j=pArr->cnt-1;
	int t;
	
	while(i<j)
	{
		t=pArr->pBase[i];
		pArr->pBase[i]=pArr->pBase[j];
		pArr->pBase[j]=t;
		i++;
		j--;
	}
	return 0;
}

11.元素排序

void sortArr(struct Arr* pArr)
{
	int i,j,t;
	
	for(i=0;i<pArr->cnt;i++)
	{
		for(j=i+1;j<pArr->cnt;j++)
		{
			t=pArr->pBase[i];
			pArr->pBase[i]=pArr->pBase[j];
			pArr->pBase[j]=t;
		}
	}
}

文章作者: WB
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 WB !
  目录