自定义数据类型
首先创建定义一个数组所需要的参数:int* pBase用于存储数组第一个元素的地址;int len表示数组所能容纳的最大元素的个数;int cnt表示当前数组有效元素的个数;int increment代表自动增长因子;其中自动增长因子的含义是向满数组中添加新元素时增长的单位大小。
方法声明
应当有数组的初始化方法,追加元素方法,插入元素方法,删除元素方法,获取元素的方法,判断是否为空,判断是否已满,排序函数,输出函数,倒置函数。
到目前为止大致的框架已经清晰,具体代码为
# include <stdio.h>
struct Arr
{
int* pBase;
int len;
int cnt;
};
void init_arr();//初始化
bool append_arr();//追加
bool insert_arr();//插入
bool delete_arr();//删除
int get();//获取
bool is_empty();//判断空
bool is_full();//判断满
void sort_arr();//排序
void show_arr();//输出
void inversion_arr();//倒置
int main(void)
{
return 0;
}
初始化函数实现
在main方法中首先定义一个struct Arr类型的变量arr,然后调用初始化函数对数组进行初始化,在main方法外实现。
初始化数组肯定要把需要初始化的数组的地址传给函数,还需要把所需的长度传递过去,这里以6举例,所以在主函数内的调用语句应该是init_arr(&arr,6);函数的声明要更改为void init_arr(struct Arr* pArr,int length);
这里要注意的是,pArr存放的arr的地址只是普普通通的结构体变量的地址,它是struct Arr*类型,并不是数组的首地址;数组的首地址应该是int*类型的,即为pArr所指向的pBase为数组首地址。
开始实现函数,首先使用malloc函数动态分配所需长度的内存,并把首地址赋值给pBase,用if判断下首地址是否为空检查是否分配成功,若为空则说明分配内存失败了,终止程序,若分配成功则初始化相应的参数,见代码:
void init_arr(struct Arr* pArr,int length)
{
pArr->pBase=(int*)malloc(sizeof(int)*length);
if(NULL==pArr->pBase)
{
printf("动态内存分配失败!\n");
exit(-1);//终止整个程序
}
else
{
pArr->len=length;
pArr->cnt=0;
}
return;
}
判断为空函数实现
判断是否为空需要数组的首地址,此函数的本质就是判断数组内有效元素的个数即可,若有效元素个数为0则说明为空,返回true,否则返回false,代码如下:
bool is_empty(struct Arr* pArr)
{
if(0==pArr->cnt)
return true;
else
return false;
}
输出函数实现
首先调用is_empty()函数判断一下数组是否为空函数,若为空则打印提示,若不为空则for循环有效个数cnt次,逐一把元素打印出来就可实现,pArr里的pBase[i]就相当于数组a[i]。
void show_arr(struct Arr* pArr)
{
if(is_empty(pArr))
{
printf("数组为空!\n");
}
else
{
for(int i=0;i<pArr->cnt;++i)
printf("%d ",pArr->pBase[i]);
printf("\n");
}
}
判断是否满的函数实现
当数组中的有效元素的个数等于数组的长度时说明数组满了
bool is_full(struct Arr* pArr)
{
if(pArr->cnt==pArr->len)
return true;
else
return false;
}
追加函数实现
追加函数需要结构体的首地址,还需要要追加的元素的值,首先调用is_full()函数判断下数组满不满,若数组满了则无法追加,返回false,若不满,则将所要追加的val值赋值给下标等于有效个数的位置,即在将val放在最后一个有效元素的后面,最后有效元素的个数自增一。
bool append_arr(struct Arr* pArr,int val)
{
if(is_full(pArr))
return false;
pArr->pBase[pArr->cnt]=val;
(pArr->cnt)++;
return true;
}
插入函数实现
需要参数:结构体的首地址、插入的位置和插入的数值。首先调用is_full()函数判断数组满不满,再判断插入位置pos的合法性,在小于第一个元素的位置和大于有效元素后一个的位置都为不合法,因为插入元素最前面的情况只能在第一个元素之前插入,在最后面的情况也只能在有效元素的后面插入,在最后一个有效元素后再空一个位置插入元素不现实,因为是线性的,不能有空位。
在合法的情况下,用for循环把插入位置后面的元素向后移动,因为是操作下标,所以cnt和pos要减一,移动元素后空出位置再把val插入即可,最后有效元素的个数加一。
bool insert_arr(struct Arr *pArr, int pos, int val)
{
int i;
if(is_full(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;
}
删除函数实现
此函数在实现删除功能的基础上还想实现显示被删除的元素,因此需要创建一个变量val用于存储被删除的元素,调用函数需要传参:结构体的首地址、删除的位置和val的地址;函数体内,首先判断数组是否为空,空数组肯定不可删除,还要判断删除位置的合法性,小于第一个位置没法删,大于最后一个位置也没法删,首先把要删除元素的地址赋值给val,pos-1即为要删除元素的下标,然后用for循环从要删除元素后一个的下标到最后一个有效元素,依次向前移即可完成删除,最后有效元素减一。
bool delete_arr(struct Arr *pArr, int pos, int* pVal)
{
int i;
if(is_empty(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;
}
倒置函数实现
分别定义两个指针,从数组的两端开始依次对调,直到交汇时停止。
void inversion_arr(struct Arr *pArr)
{
int i=0;
int j=pArr->cnt-1;
int t;
whille(i<j)
{
t=pArr->pBase[i];
pArr->pBase[i]=pArr->pBase[j];
pArr->pBase[j]=t;
++i
--j;
}
return;
}
排序函数
这里使用选择排序实现,依次与剩余元素比较,如果i大则交换,否则不变,比较完一轮后第二个在开始比较。
void sort_arr(struct Arr *pArr)
{
int i,j,t;
for(i=0;i<pArr->cnt;++i)
{
for(j=i+1;j<pArr->cnt;++j)
{
if(pArr->pBase[i] > pArr->pBase[j])
{
t=pArr->pBase[i];
pArr->pBase[i]=pArr->pBase[j];
pArr->pBase[j]=t;
}
}
}
}
完整代码:
# include <stdio.h>
# include <malloc.h>
# include <stdio.h>//包含了exit函数
struct Arr {
int *pBase;//数组的首地址
int len;//数组能容纳元素的最大个数
int cnt;//有效元素的个数
};
void init_arr(struct Arr *pArr, int length); //初始化
bool append_arr(struct Arr *pArr, int val); //追加
bool insert_arr(struct Arr *pArr, int pos, int val); //插入 pos为插入的位置
bool delete_arr(struct Arr *pArr, int pos, int* pVal);//删除 int* pVal接收呗删除的值
int get();//获取
bool is_empty(struct Arr *pArr);//判断空
bool is_full(struct Arr *pArr);//判断满
void sort_arr(struct Arr *pArr);//排序
void show_arr(struct Arr *pArr);//输出
void inversion_arr(struct Arr *pArr);//倒置
//初始化函数
void init_arr(struct Arr *pArr, int length) {
pArr->pBase = (int *)malloc(sizeof(int) * length);
if (NULL == pArr->pBase) {
printf("动态内存分配失败!\n");
exit(-1);//终止整个程序
} else {
pArr->len = length;
pArr->cnt = 0;
}
return;
}
//判断是否为空函数
bool is_empty(struct Arr *pArr) {
if (0 == pArr->cnt)
return true;
else
return false;
}
//输出函数
void show_arr(struct Arr *pArr) {
if (is_empty(pArr)) {
printf("数组为空!\n");
} else {
for (int i = 0; i < pArr->cnt; ++i)
printf("%d ", pArr->pBase[i]);
printf("\n");
}
}
//判断是否满函数
bool is_full(struct Arr *pArr) {
if (pArr->cnt == pArr->len)
return true;
else
return false;
}
//追加函数
bool append_arr(struct Arr *pArr, int val) {
if (is_full(pArr))
return false;
pArr->pBase[pArr->cnt] = val;
(pArr->cnt)++;
return true;
}
//插入函数
bool insert_arr(struct Arr *pArr, int pos, int val)
{
int i;
if(is_full(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;
}
//删除函数
bool delete_arr(struct Arr *pArr, int pos, int* pVal)
{
int i;
if(is_empty(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;
}
//倒置函数
void inversion_arr(struct Arr *pArr)
{
int i=0;
int j=pArr->cnt-1;
int t;
whille(i<j)
{
t=pArr->pBase[i];
pArr->pBase[i]=pArr->pBase[j];
pArr->pBase[j]=t;
++i
--j;
}
return;
}
//排序函数
void sort_arr(struct Arr *pArr)
{
int i,j,t;
for(i=0;i<pArr->cnt;++i)
{
for(j=i+1;j<pArr->cnt;++j)
{
if(pArr->pBase[i] > pArr->pBase[j])
{
t=pArr->pBase[i];
pArr->pBase[i]=pArr->pBase[j];
pArr->pBase[j]=t;
}
}
}
}
int main(void) {
struct Arr arr;
int val;//用于存储删除函数中被删除元素的
init_arr(&arr, 6);
show_arr(&arr);
append_arr(&arr, 1);
insert_arr(&arr,2,99);
delete_arr(&arr,1,&val);
inversion_arr(&arr);
sort_arr(&arr);
return 0;
}