使用malloc函数动态分配内存创建数组,与传统的数组相比,可以手动释放内存,顺便练习一下C语言数据结构。
1.数据结构
struct Arr {
int * pBase;//存储的第一个元素的地址
int len;//数组的长度
int cnt;//数组的有效长度
};
2.数据初始化
//初始化数组
void init_arr(struct Arr * pArr,int length)
{
pArr->pBase = (int*) malloc(sizeof(int)*length);//动态分配堆内存 ,并用pBase存放第一个元素地址
if(NULL == pArr->pBase)
{
printf("分配内存失败!\n");
exit(-1);
}
else
{
pArr->len = length;//初始化数组长度
pArr->cnt = 0;//初始化数组有效长度
printf("初始化完成,数组长度为%d\n", length);
}
return;
}
3.输出数组
//输出数组 (有效长度的数组)
void show_arr(struct Arr * pArr)
{
if(is_empty(pArr))
{
printf("数组有效长度为0,请添加元素到数组!\n");
}
else
{
printf("当前数组为:");
for(int i = 0; i < pArr->cnt; i++)
{
printf("%d ", pArr->pBase[i]);
}
printf("\n");
}
}
4.添加元素
bool append_arr(struct Arr * pArr, int val)
{
if(is_full(pArr))//数组已满,返回false
{
printf("数组已满,添加元素失败!\n");
return false;
}
else
{
pArr->pBase[pArr->cnt] = val;//在数组有效长度末尾追加元素
(pArr->cnt)++;
return true;
}
}
5.插入元素
//插入元素
bool insert_arr(struct Arr * pArr, int pos, int val)
{
if(is_full(pArr))
{
printf("数组已满,插入元素失败!\n");
return false;
}
if(pos < 1 || pos > pArr->cnt+1)
return false;
for(int i = pArr->cnt - 1; i >= pos - 1; i--)//在指定位置插入元素
{
pArr->pBase[i+1] = pArr->pBase[i];
}
pArr->pBase[pos - 1] = val;
pArr->cnt++;
return true;
}
6.删除元素
bool delete_arr(struct Arr * pArr, int pos, int * pVal)
{
if (is_empty(pArr))
{
printf("数组有效长度为0,删除失败!\n");
return false;
}
if(pos < 1 || pos > pArr->cnt)
{
return false;
}
*pVal = pArr->pBase[pos-1];
for(int i = pos; i < pArr->cnt; i++)
{
pArr->pBase[i-1] = pArr->pBase[i];
}
pArr->cnt--;
return true;
}
7.数组倒置
//倒置 ,将第一个元素与最后一个元素的值进行交换,以此类推
void inversion_arr(struct Arr * pArr)
{
if(is_empty(pArr))
{
printf("数组有效长度为0,请添加元素到数组!\n");
return;
}
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;
}
8.排序
//排序(简单双重for循环)
void sort_arr(struct Arr * pArr)
{
if(is_empty(pArr))
{
printf("数组有效长度为0,请添加元素到数组!\n");
return;
}
int t;
for(int i = 0; i < pArr->cnt; i++)
{
for(int 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;
}
}
}
}
9.完整代码
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
struct Arr {
int * pBase;//存储的第一个元素的地址
int len;//数组的长度
int cnt;//数组的有效长度
};
void init_arr(struct Arr * pArr ,int length);//初始化数组
void show_arr(struct Arr * pArr );//输出数组
bool is_empty(struct Arr * pArr );//判断数组是否为空
bool is_full(struct Arr * pArr);//判断数组是否已满
bool append_arr(struct Arr * pArr, int val);//追加元素()
bool insert_arr(struct Arr * pArr, int pos, int val);//插入元素
bool delete_arr(struct Arr * pArr, int pos, int * val);//删除元素
void inversion_arr(struct Arr * pArr);//倒置
void sort_arr(struct Arr * pArr);//排序(简单双重for循环排序)
int main(void)
{
struct Arr arr;//声明结构体变量
int val;//接受删除元素
init_arr(&arr,6);//初始化数组长度为6;
show_arr(&arr);
printf("***************************************************************\n");
printf("添加元素功能测试:\n"); //[6,3,1,9,7]
append_arr(&arr,6);
show_arr(&arr);
append_arr(&arr,3);
show_arr(&arr);
append_arr(&arr,1);
show_arr(&arr);
append_arr(&arr,9);
show_arr(&arr);
append_arr(&arr,7);
show_arr(&arr);
printf("***************************************************************\n");
printf("插入元素功能测试:\n");
insert_arr(&arr,2,99);//在第二个位置插入99
show_arr(&arr);
printf("***************************************************************\n");
printf("删除元素功能测试:\n");
delete_arr(&arr,3,&val);
show_arr(&arr);
printf("删除元素为:");
printf("%d\n", val);
printf("***************************************************************\n");
printf("倒置元素功能测试:\n");
inversion_arr(&arr);
show_arr(&arr);
printf("***************************************************************\n");
printf("排序功能测试:\n");
sort_arr(&arr);
show_arr(&arr);
// printf("%d", val);
return 0;
}
//初始化数组
void init_arr(struct Arr * pArr,int length)
{
pArr->pBase = (int*) malloc(sizeof(int)*length);//动态分配堆内存 ,并用pBase存放第一个元素地址
if(NULL == pArr->pBase)
{
printf("分配内存失败!\n");
exit(-1);
}
else
{
pArr->len = length;//初始化数组长度
pArr->cnt = 0;//初始化数组有效长度
printf("初始化完成,数组长度为%d\n", length);
}
return;
}
//判断数组是否为空
bool is_empty(struct Arr * pArr)
{
if(pArr->cnt == 0)//有效长度为0,则数组为空
{
return true;
}
else
{
return false;
}
}
//输出数组 (有效长度的数组)
void show_arr(struct Arr * pArr)
{
if(is_empty(pArr))
{
printf("数组有效长度为0,请添加元素到数组!\n");
}
else
{
printf("当前数组为:");
for(int i = 0; i < pArr->cnt; i++)
{
printf("%d ", pArr->pBase[i]);
}
printf("\n");
}
}
//数组是否已满
bool is_full(struct Arr * pArr)
{
if(pArr->len == pArr->cnt)//数组的有效长度是否等于数组的长度
{
return true;
}
else
{
return false;
}
}
//添加元素
bool append_arr(struct Arr * pArr, int val)
{
if(is_full(pArr))//数组已满,返回false
{
printf("数组已满,添加元素失败!\n");
return false;
}
else
{
pArr->pBase[pArr->cnt] = val;//在数组有效长度末尾追加元素
(pArr->cnt)++;
return true;
}
}
//插入元素
bool insert_arr(struct Arr * pArr, int pos, int val)
{
if(is_full(pArr))
{
printf("数组已满,插入元素失败!\n");
return false;
}
if(pos < 1 || pos > pArr->cnt+1)
return false;
for(int 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中
bool delete_arr(struct Arr * pArr, int pos, int * pVal)
{
if (is_empty(pArr))
{
printf("数组有效长度为0,删除失败!\n");
return false;
}
if(pos < 1 || pos > pArr->cnt)
{
return false;
}
*pVal = pArr->pBase[pos-1];
for(int i = pos; i < pArr->cnt; i++)
{
pArr->pBase[i-1] = pArr->pBase[i];
}
pArr->cnt--;
return true;
}
//倒置 ,将第一个元素与最后一个元素的值进行交换,以此类推
void inversion_arr(struct Arr * pArr)
{
if(is_empty(pArr))
{
printf("数组有效长度为0,请添加元素到数组!\n");
return;
}
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;
}
//排序(简单双重for循环)
void sort_arr(struct Arr * pArr)
{
if(is_empty(pArr))
{
printf("数组有效长度为0,请添加元素到数组!\n");
return;
}
int t;
for(int i = 0; i < pArr->cnt; i++)
{
for(int 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;
}
}
}
}