c语言动态内存数组的使用案例,C语言基础 - 实现动态数组并增加内存管理

写在前面

弄了下个人站...防止内容再次被锁定...所有东西都在这里面

welcome~

个人博客

用C语言实现一个动态数组,并对外暴露出对数组的增、删、改、查函数

(可以存储任意类型的元素并实现内存管理)

这里我的编译器就是xcode

分析:

模拟存放 一个 People类 有2个属性 字符串类型:姓名 整型:年龄

array 结构体 应当有 数组长度:length 空间:capacity 存储对象:value(任意类型)

构造一个任意对象类.拥有retainCount属性.为内存计数器

使用一次retainCount+1,当retainCount为0时 释放该对象指向的内存

贴出部分代码

// Object.h

#ifndef Object_h

#define Object_h

#include

//定义结构体

typedef struct Object{

int retainCount;

}Object;

//宏定义方法 方便书写

#define OBJECTRETAIN(obj) objectRetain((Object*)obj)

#define OBJECTRELEASE(obj) objectRelease((Object*)obj)

#define GETRETAINCOUNT(obj) getRetainCount((Object*)obj)

void objectRetain(Object *obj);

void objectRelease(Object *obj);

int getRetainCount(Object *obj);

#endif /* Object_h */

// Object.c

#include "Object.h"

#include

void objectRetain(Object *obj) {

obj->retainCount ++;

// printf("retain计数+1 = %d\n",obj->retainCount);

}

void objectRelease(Object *obj) {

obj->retainCount --;

if (obj->retainCount <= 0) {

free(obj);

}

// printf("retain计数-1 = %d\n",obj->retainCount);

}

//获得当前计数

int getRetainCount(Object *obj) {

return obj->retainCount;

}

下面开始封装.

首先是对原始数据的封装.

将char* 字符串类型 封装成String

// String.h

#ifndef String_h

#define String_h

#include

typedef struct String{

int retainCount;

char *value;

}String;

String* newString(char* value);

char* getStringValue(String* ins);

#endif /* String_h */

// String.c

#include "String.h"

#include

#include "Object.h"

String* newString(char* value){

String *str = malloc(sizeof(String));

OBJECTRETAIN(str);

str->value = value;

return str;

}

char* getStringValue(String* ins){

return ins->value;

}

2.将年龄的类型int封装成Interger

// Integer.h

#ifndef Integer_h

#define Integer_h

#include

typedef struct Integer{

int retainCount;

int value;

}Integer;

Integer* newInteger(int value);

int getIntegerValue(Integer* ins);

#endif /* Integer_h */

// Integer.c

#include "Integer.h"

#include

#include "Object.h"

Integer *newInteger(int value) {

Integer *new = malloc(sizeof(Integer));

OBJECTRETAIN(new);

new->value = value;

return new;

}

int getIntegerValue(Integer* ins) {

return ins->value;

}

3.定义数组中存放的类 包含 name 和 age 属性

// People.h

#ifndef People_h

#define People_h

#include

#include "Integer.h"

#include "String.h"

typedef struct People{

int retainCount;

String* name;

Integer* age;

}People;

People* newPeople(String *name,Integer *age);

String* getName(People* people);

Integer* getAge(People* people);

#endif /* People_h */

// People.c

#include "People.h"

#include

#include "Object.h"

People* newPeople(String *name,Integer *age){

People *newP = malloc(sizeof(People));

OBJECTRETAIN(newP);

newP->age = age;

newP->name = name;

return newP;

}

String* getName(People* people){

return people->name;

}

Integer* getAge(People* people){

return people->age;

}

4.准备工作都做完 ,下面我们来实现数组Array

// Array.h

#ifndef Array_h

#define Array_h

#include

#include "People.h"

#include "Object.h"

typedef Object* AnyObject;

typedef struct Array{

int length;

int capacity;

AnyObject *value;

}Array;

Array* newArray();

//增加数组元素

void addElement(Array *array,AnyObject value);

//删除

Array* removeIndexAt(Array *arry,int index);

//插入

Array* insertIndexAt(Array *array,AnyObject value,int index);

//查找

AnyObject getValueIndexAt(Array *array,int index);

//获取数组长度

int getArrayLength(Array *array);

//销毁

void destroyArray(Array *array);

//打印

void printArray(Array *arr);

#endif /* Array_h */

// Array.c

#include "Array.h"

#include

#include

#include

//分配空间

static AnyObject* allocMemoryByCapacity(Array *arr){

return malloc(sizeof(AnyObject) * arr->capacity);

}

//创建数组

Array* newArray(){

Array *arr = malloc(sizeof(Array));

arr->length = 0;

arr->capacity = 32;

arr->value = allocMemoryByCapacity(arr);

return arr;

}

//获取数组长度

int getArrayLength(Array *array){

return array->length;

}

//增加元素

void addElement(Array *array,AnyObject value){

if (array->length >= array->capacity) {

array->capacity *= 2;

AnyObject *oldValue = array->value;

memcpy(array->value, oldValue, array->length*sizeof(AnyObject));

free(oldValue);

}

OBJECTRETAIN(value);

array->value[array->length] = value;

array->length++;

}

//删除元素

Array* removeIndexAt(Array *arry,int index){

assert(index >= 0 && index < arry>length); //断言 防止越界

OBJECTRELEASE(getValueIndexAt(arry, index));

arry->length -- ;

for (int i = index-1; i < arry>length; i++) {

arry->value[i] = arry->value[i+1];

}

return arry;

}

//在指定位置增加元素

Array* insertIndexAt(Array *array,AnyObject value,int index){

if (array->length >= array->capacity) {

array->capacity *= 2;

AnyObject *oldValue = array->value;

memcpy(array->value, oldValue, array->length*sizeof(AnyObject));

free(oldValue);

}

array->length++;

//插入指定位置

array->value[index-1] = value;

//将元素后移

for (int i = index; i < array>length; i++) {

array->value[array->length] = array->value[array->length-i];

}

OBJECTRETAIN(value);

return array;

}

//获取某个元素

AnyObject getValueIndexAt(Array *array,int index){

assert(index >= 0 && index < array>length);

return array->value[index];

}

//销毁

void destroyArray(Array *array){

free(array->value);

free(array);

printf("数组被销毁\n");

}

//打印结果

void printArray(Array *arr){

for (int i = 0; i < arr>length; i++) {

printf("位置:%d,姓名:%s,年龄:%d\n",i, getStringValue(getName((People*)getValueIndexAt(arr, i))),getIntegerValue(getAge((People*)getValueIndexAt(arr, i))));

}

}

接下来就可以来测试数据了.

// main.m

#import

#import "People.h"

#import "Array.h"

#import "Object.h"

int main(int argc, const char * argv[]) {

@autoreleasepool {

Array *arr = newArray();

People *p0 = newPeople(newString("张三"), newInteger(20));

People *p1 = newPeople(newString("李四"), newInteger(16));

People *p2 = newPeople(newString("王五"), newInteger(17));

People *p3 = newPeople(newString("赵二"), newInteger(14));

People *p4 = newPeople(newString("林三"), newInteger(22));

People *p5 = newPeople(newString("小明"), newInteger(18));

People *p6 = newPeople(newString("小红"), newInteger(25));

People *p7 = newPeople(newString("小方"), newInteger(11));

People *p8 = newPeople(newString("小花"), newInteger(19));

People *p9 = newPeople(newString("小兔"), newInteger(22));

People *p10 = newPeople(newString("新人"), newInteger(23));

//增加元素

addElement(arr, (Object *)p0);

addElement(arr, (Object *)p1);

addElement(arr, (Object *)p2);

addElement(arr, (Object *)p3);

addElement(arr, (Object *)p4);

addElement(arr, (Object *)p5);

addElement(arr, (Object *)p6);

addElement(arr, (Object *)p7);

addElement(arr, (Object *)p8);

addElement(arr, (Object *)p9);

//释放内存

OBJECTRELEASE((Object*) p0);

OBJECTRELEASE((Object*) p1);

OBJECTRELEASE((Object*) p2);

OBJECTRELEASE((Object*) p3);

OBJECTRELEASE((Object*) p4);

OBJECTRELEASE((Object*) p5);

OBJECTRELEASE((Object*) p6);

OBJECTRELEASE((Object*) p7);

OBJECTRELEASE((Object*) p8);

OBJECTRELEASE((Object*) p9);

printf("增加10个元素\n");

printArray(arr);

printf("删除第3个元素\n");

//删除第数组中某一个元素

removeIndexAt(arr, 3);

printArray(arr);

printf("插入P10成为第4个元素\n");

//插入

insertIndexAt(arr, (Object *)p10, 4);

printArray(arr);

OBJECTRELEASE((Object*) p10);

printf("查找第5个元素\n");

//index从0开始 查找第5个元素 index=4

printf("位置:%d,姓名:%s,年龄:%d\n",4, getStringValue(getName((People*)getValueIndexAt(arr, 4))),getIntegerValue(getAge((People*)getValueIndexAt(arr, 4))));

//销毁数组

destroyArray(arr);

}

return 0;

}

看下结果吧。

10838aa67a63

array.png

有兴趣的可以研究下哈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值