一.数组
- 存放类型相同,大小相等的元素
二.代码部分
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;
}
}
}