头文件 动态数组.h
#include<stdio.h>
#include<stdlib.h>
struct data
{
int *p;//指针保存数组的起始点
int length;//保存数组的长度
int stat;//0代表无序,1代表从小到大,2代表从大到小
int reallength;//实际分配的内存长度
};
//findalldata需要返回地址和个数,所以需要返回一个结构体
struct findres
{
int **pp;
int n;
};
//实现增加,删除,查找,修改,插入
void init(struct data *pdata);//初始化
void reinit(struct data *pdata);//使用之后初始化
void addobject(struct data *pdata, int num);//增加一个数据
void addobjects(struct data *pdata, int *pnum, int n);//增加一个数组
void printfall(struct data *pdata);//打印数据
void deleteone(struct data *pdata, int num);//删除第一个找到的数据
void deleteall(struct data *pdata, int num);//删除所有能找到的数据
int *finddata(struct data *pdata, int num);//返回第一个找到数据的地址
//int **findalldata(struct data *pdata, int num);//返回一片内存,包含所有的元素
struct findres findalldata(struct data *pdata, int num);//返回一个结构体,里面包含查找的数据地址和个数
void change(struct data *pdata, int oldnum, int newnum);//修改
void sort(struct data *pdata, int obj);//obj=0,从小到大,否则从大到小
void insert(struct data *pdata, int num, int insertnum, int headback);//插入,headback=1前插,否则后插
源文件 动态数组.c
#include"动态数组.h"
void init(struct data *pdata)//使用之前初始化
{
pdata->p = NULL;//意味着还没初始化
pdata->length = 0;
pdata->stat = 0;//代表无序
pdata->reallength = 0;//实际长度
}
void reinit(struct data *pdata)//使用之后初始化
{
if (pdata->p == NULL)
{
return;
}
else
{
free(pdata->p);
pdata->p = NULL;
pdata->length = 0;
int stat = 0;//代表无序
pdata->reallength = 0;//实际长度
}
}
//增加一个数据
void addobject(struct data *pdata, int num)
{
if (pdata->p == NULL)
{
pdata->p = (int*)malloc(sizeof(int));//增加一个元素+
pdata->length += 1;//数组标识增加一个元素
pdata->reallength = 1;//实际长度
pdata->p[pdata->length - 1] = num;//赋值
}
else
{
if (pdata->length == pdata->reallength)
{
pdata->p = (int*)realloc(pdata->p, (pdata->length + 1) * sizeof(int));
pdata->length += 1;
pdata->reallength += 1;
pdata->p[pdata->length - 1] = num;
}
else
{
pdata->length += 1;
pdata->p[pdata->length - 1] = num;//赋值
}
}
}
//增加一个数组
void addobjects(struct data *pdata, int *pnum, int n)
{
if (pdata->p == NULL)
{
pdata->p = (int*)malloc(sizeof(int)*n);//增加n个元素
pdata->length = n;
pdata->reallength = n;
for (int i = 0; i < n; i++)
{
pdata->p[i] = pnum[i];//拷贝数组
}
}
else
{
if (pdata->length + n <= pdata->reallength)
{
for (int i = 0; i < n; i++)
{
pdata->p[pdata->length + i] = pnum[i];
}
pdata->length += n;
}
else
{
pdata->p = (int*)realloc(pdata->p, (pdata->length + n) * sizeof(int));
for (int i = 0; i < n; i++)
{
pdata->p[pdata->length + i] = pnum[i];
}
pdata->length += n;
pdata->reallength += n;
}
}
}
//打印数据
void printfall(struct data *pdata)
{
for (int i = 0; i < pdata->length; i++)
{
printf("%d\n", pdata->p[i]);
}
}
//排序 obj=0,从小到大,否则从大到小
void sort(struct data *pdata, int obj)
{
if (obj == 0)
{
for (int i = 0; i < pdata->length - 1; i++)
{
for (int j = 0; j < pdata->length - i - 1; j++)
{
if (pdata->p[j] > pdata->p[j + 1])// j >j+1
{
int temp = pdata->p[j]; //交换数据
pdata->p[j] = pdata->p[j + 1];
pdata->p[j + 1] = temp;
}
}
}
pdata->stat = 1;//代表从小到大
}
else
{
for (int i = 0; i < pdata->length - 1; i++)
{
for (int j = 0; j < pdata->length - i - 1; j++)//冒泡没循环一次,沉底一个极值
{
if (pdata->p[j] < pdata->p[j + 1])// j <j+1
{
//int temp = pdata->p[j]; //交换数据
//pdata->p[j] = pdata->p[j + 1];
//pdata->p[j + 1] = temp;
pdata->p[j] = pdata->p[j] ^ pdata->p[j + 1];
pdata->p[j + 1] = pdata->p[j] ^ pdata->p[j + 1];
pdata->p[j] = pdata->p[j] ^ pdata->p[j + 1];
}
}
}
pdata->stat = 2;//代表从大到小
}
}
//查找 返回第一个找到数据的地址
int *finddata(struct data *pdata, int num)//返回第一个找到数据的地址
{
if (pdata->stat == 0)
{
for (int i = 0; i < pdata->length; i++)//顺序循环
{
printf("查找第%d次\n", i);
if (num == pdata->p[i])//判定是否相等
{
printf("找到%d\n", pdata->p[i]);
return &pdata->p[i];//返回一个地址
break;//跳出循环
}
}
return NULL;
}
else if (pdata->stat == 1)//从小到大,用二分查找法
{
int shang = 0;
int xia = pdata->length - 1;
while (shang <= xia)
{
int zhong = (shang + xia) / 2;
printf("%d,%d,%d\n", shang, zhong, xia);
if (pdata->p[zhong] == num)
{
return &pdata->p[zhong];
}
else if (num > pdata->p[zhong])
{
shang = zhong + 1;
}
else if (num < pdata->p[zhong])
{
xia = zhong - 1;
}
}
return NULL;
}
else//从大到小,用二分查找法
{
int shang = 0;
int xia = pdata->length - 1;
while (shang <= xia)
{
int zhong = (shang + xia) / 2;
printf("%d,%d,%d\n", shang, zhong, xia);
if (pdata->p[zhong] == num)
{
return &pdata->p[zhong];
}
else if (num < pdata->p[zhong])
{
shang = zhong + 1;
}
else if (num > pdata->p[zhong])
{
xia = zhong - 1;
}
}
return NULL;
}
}
int *find(int *p, int num, int n)//从一个地址开始,n个范围内查找
{
for (int i = 0; i < n; i++)
{
if (p[i] == num)
{
return p + i;//返回地址
break;
}
}
return NULL;//没有找到
}
//查找全部
struct findres findalldata(struct data *pdata, int num)
{
//思路 先统计找到多少个
struct findres res1;//构建结构体变量
int i = 0;
for (int *p = find(pdata->p, num, pdata->length - 1); p != NULL; p = find(p + 1, num, (pdata->length - 1) - (p - pdata->p)))
{
i++;
}
printf("i=%d\n", i);
res1.n = i;//长度
int **pint = (int*)malloc(sizeof(int*) * i);//指针数组
res1.pp = pint;
for (int *p = find(pdata->p, num, pdata->length - 1), j = 0; p != NULL; p = find(p + 1, num, (pdata->length - 1) - (p - pdata->p)), j++)
{
pint[j] = p;
printf("\n%p,%d\n", pint[j], *pint[j]);
}
return res1;
}
//实现修改
void change(struct data *pdata, int oldnum, int newnum)//依赖于查找
{
int *p = finddata(pdata, oldnum);
if (p == NULL)
{
printf("没有找到,修改失败");
return;
}
else
{
*p = newnum;//修改数据
}
}
//插入数据
void insert(struct data *pdata, int num, int insertnum, int headback)//插入,headback=0前插,=1后插
{
int *p = finddata(pdata, num);
if (p == NULL)
{
printf("没有找到数据");
return NULL;//没有找到
}
else//找到,分为前插和后插
{
if (headback == 1)//前插入
{
if (pdata->length < pdata->reallength)//不用分配
{
int curr = p - pdata->p;//获取要插入位置的下标
for (int i = pdata->length - 1; i >= curr; i--)
{
pdata->p[i + 1] = pdata->p[i];//从后往前移动
}
pdata->p[curr] = insertnum;//实现前插
pdata->length++;
}
else//需要分配
{
pdata->p = (int*)realloc(pdata->p, (pdata->length + 1) * sizeof(int));
pdata->reallength++;//实际长度+1
int curr = p - pdata->p;//获取要插入位置的下标
for (int i = pdata->length - 1; i >= curr; i--)
{
pdata->p[i + 1] = pdata->p[i];//从后往前移动
}
pdata->p[curr] = insertnum;//实现前插
pdata->length++;
}
}
else//后插入
{
if (pdata->length < pdata->reallength)//不用分配
{
int curr = p - pdata->p;
for (int i = pdata->length - 1; i > curr; i--)
{
pdata->p[i + 1] = pdata->p[i];
}
pdata->p[curr + 1] = insertnum;//实现插入
pdata->length++;
}
else//需要分配
{
pdata->p = (int*)realloc(pdata->p, (pdata->length + 1) * sizeof(int));
pdata->reallength++;//实际长度+1
int curr = p - pdata->p;//获取要插入位置的下标
for (int i = pdata->length - 1; i > curr; i--)
{
pdata->p[i + 1] = pdata->p[i];
}
pdata->p[curr + 1] = insertnum;//实现插入
pdata->length++;
}
}
}
}
//删除第一个找到的数据
void deleteone(struct data *pdata, int num)//删除依赖于查找
{
int *p = finddata(pdata, num);//查找数据
if (p == NULL)
{
return NULL;//没有找到
}
else
{
int curr = p - pdata->p;//curr当前要删除的下标
/*printf("%d,%p", *p, p);
printf("%d,%p", pdata->p[curr], &pdata->p[curr]);*/
for (int i = curr; i < pdata->length - 1; i++)
{
pdata->p[i] = pdata->p[i + 1];//从后向前移动
}
pdata->length -= 1;
}
}
//删除全部
void deleteall(struct data *pdata, int num)
{
for (int *p = finddata(pdata, num); p != NULL; p = finddata(pdata, num))
{
int curr = p - pdata->p;//curr当前要删除的下标
for (int i = curr; i < pdata->length - 1; i++)
{
pdata->p[i] = pdata->p[i + 1];
}
pdata->length -= 1;
}
}
调用测试 main.c
#include<stdio.h>
#include<stdlib.h>
#include"动态数组.h"
void main1()
{
int a[10] = { 1,22,3,4,15,6,37,8,19,0 };
struct data data1;
init(&data1);
/*addobject(&data1, 10);
addobject(&data1, 11);
addobject(&data1, 12);
reinit(&data1);
addobjects(&data1,a,10);
printfall(&data1);
printf("\n\n");*/
addobjects(&data1, a, 10);
/*{
int *pfind = finddata(&data1, 6);
if (pfind != NULL)
{
printf("%d,%p\n", *pfind, pfind);
}
else
{
printf("没有找到");
}
}*/
//printf("\n\n");
sort(&data1, 0);//从小到大
//printfall(&data1);
//块语句
{
int *pfind = finddata(&data1, 6);
if (pfind != NULL)
{
printf("%d,%p\n", *pfind, pfind);
}
else
{
printf("没有找到");
}
}
getchar();
}
void main2()
{
int a[10] = { 1,22,3,4,15,6,37,8,19,0 };
struct data data1;
init(&data1);
addobjects(&data1, a, 10);
{
int *pfind = finddata(&data1, 6);
if (pfind != NULL)
{
//printf("%d,%p\n", *pfind, pfind);
}
else
{
printf("没有找到");
}
}
getchar();
}
void main3()
{
int a[10] = { 1,22,15,4,15,6,37,15,19,0 };
struct data data1;
init(&data1);
addobjects(&data1, a, 10);
printfall(&data1);
printf("\n\n\n");
struct findres resn = findalldata(&data1, 15);//查找
for (int i = 0; i < resn.n; i++)
{
printf("\nresn %p,%d\n", *(resn.pp + i), **(resn.pp + i));//二级指针遍历指针数组
}
free(resn.pp);//释放内存
printfall(&data1);
getchar();
}
void main4()
{
int a[10] = { 1,22,15,4,15,6,37,15,19,23 };
struct data data1;
init(&data1);
addobjects(&data1, a, 10);
printfall(&data1);
printf("\n\n\n");
int *p = finddata(&data1, 6);
printf("%d\n", *p);
getchar();
}
void main()
{
int a[10] = { 1,22,15,4,15,6,37,15,19,23 };
struct data data1;
init(&data1);
addobjects(&data1, a, 10);
printfall(&data1);
printf("\n\n\n");
//测试插入
insert(&data1, 6, 1988, 1);//前插
insert(&data1, 6, 1988, 0);//后插
printfall(&data1);
getchar();
}
-----------------------------测试与调用-------------------------------------
#include<stdio.h>
#include<stdlib.h>
#include"动态数组.h"
#pragma comment(lib,"数组lib.lib")//引用lib,先要把lib文件放入数组库测试的目录下
void main1()
{
struct data data1;//第一种调用方式
int a[10] = { 5,2,65,874,2,12,486,2,215,2 };
init(&data1);
addobjects(&data1, a, 10);
printfall(&data1);
printf("\n\n");
//change(&data1, 5, 1001);
//deleteall(&data1, 2);
insert(&data1, 2, 99999, 0);
printfall(&data1);
getchar();
}
void main()
{
struct data *pdata = (struct data*)malloc(sizeof(struct data));//第二种调用方式
int a[10] = { 5,2,65,874,2,12,486,2,215,2 };
init(pdata);
addobjects(pdata, a, 10);
printfall(pdata);
printf("\n\n");
//change(&data1, 5, 1001);
//deleteall(&data1, 2);
insert(pdata, 2, 99999, 0);
printfall(pdata);
getchar();
}
最后在属性里改为lib,生成lib文件,完成封装,其他文件调用的时候要把lib文件和头文件复制到目标文件夹下面