1.动态数组

Posted codemagiciant

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1.动态数组相关的知识,希望对你有一定的参考价值。

1.动态数组结构

  上图所示,该动态数组有3个元素,空间容量是6,每个元素类型为void*,因为void*可以接受任何类型指针,可以用来存各种类型指针。第一个元素地址为pAddr,第一个元素为*pAddr。

用结构体表示动态数组为:

//动态数组结构体
struct dynamicArray

	void** pAddr;//维护真实在堆区的数组的指针
	int m_capacity;//数组容量
	int m_size;//数组大小
;

对应上图m_size是3,m_capacity是6

2.动态数组的操作

2.1动态数组的初始化操作

//初始化数组
struct dynamicArray * init_DynamicArray(int capacity);
struct dynamicArray* init_DynamicArray(int capacity)

	if (capacity <= 0)
	
		return NULL;
	

	//给数组分配空间
	struct dynamicArray* array = malloc(sizeof(struct dynamicArray));//array为数组名,是第一个元素的地址
	if (array == NULL)//判断分配空间操作是否成功,不成功立即退出
	
		return;
	
	//给数组初始化
	array->pAddr = malloc(sizeof(void*) * capacity);
	array->m_capacity = capacity;
	array->m_size = 0;

	return array;

2.2动态数组的插入操作

//插入数组
void insert_DynamicArray(struct dynamicArray * array, int pos, void * data);
//array为需要做插入操作的数组,所插数据的插入位置为pos、值为data,这里是插入一个数据
void insert_DynamicArray(struct dynamicArray * array, int pos, void * data)

	if (array == NULL)//无法对未分配空间的数组做插入操作
	
		return;
	
	if (data == NULL)//无法插入一个无效值
	
		return;
	

	//无效位置  尾插
	if (pos < 0 || pos > array->m_size)
	
		pos = array->m_size;
	

	//判断是否满了,如果满动态扩展
	if (array->m_size == array->m_capacity)
	
		//1、计算新空间大小   这里多分配空间,是防止多次分配空间,以空间换时间
		int newCapacity = array->m_capacity * 2;//array->m_capacity等价于(*array).m_capacity

		//2、创建新空间
		void ** newSpace = malloc(sizeof(void *)* newCapacity);//sizeof(void *)为每个元素大小

		//3、将原有数据拷贝到新空间下
		memcpy(newSpace, array->pAddr, sizeof(void *) * array->m_capacity);

		//4、释放原有内存空间
		free(array->pAddr);

		//5、更新新空间指向
		array->pAddr = newSpace;

		//6、更新新容量
		array->m_capacity = newCapacity;
	

	//插入新元素

	//移动元素 进行插入新元素
	for (int i = array->m_size - 1; i >= pos; i--)//将插入位置后的元素先后移,从尾元素开始
	
		//数据向后移动
		array->pAddr[i + 1] = array->pAddr[i];
	

	//将新元素 插入到指定位置上
	array->pAddr[pos] = data;
	//更新大小
	array->m_size++;

2.3动态数组的遍历操作

//打印数组
void foreach_DynamicArray(struct dynamicArray * array, void(*myPrint)(void*));
void foreach_DynamicArray(struct dynamicArray * array, void(*myPrint)(void*))

	if (array == NULL)
	
		return;
	
	if (myPrint == NULL)
	
		return;
	

	for (int i = 0; i < array->m_size; i++)
	
		myPrint(array->pAddr[i]);
	

2.4动态数组的删除操作

//删除数组  按位置删除
void removeByPos_DynamicArray(struct dynamicArray * array, int pos)

	if (NULL == array)
	
		return;
	

	if (pos < 0 || pos > array->m_size - 1)
	
		return;
	

	//数据前移
	for (int i = pos; i < array->m_size - 1; i++)
	
		array->pAddr[i] = array->pAddr[i + 1];
	

	//更新数组大小
	array->m_size--;

//按值删除数据
void removeByValue_DynamicArray(struct dynamicArray * array, void * data, int(*myCompare)(void *, void *))

	if (array == NULL)
	
		return;
	
	if (data == NULL)
	
		return;
	

	for (int i = 0; i < array->m_size; i++)
	
		if (myCompare(array->pAddr[i], data))
		
			//如果找到要删除的数据,i就是要删除的具体位置
			removeByPos_DynamicArray(array, i);
			break;
		
	



int myComparePerson(void * data1, void *data2)

	struct Person *  p1 = data1;
	struct Person *  p2 = data2;

	return  strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;


removeByValue_DynamicArray(array, &p, myComparePerson);

2.5销毁数组

//销毁数组
void destroy_DynamicArray(struct dynamicArray* array)

	if (array == NULL)
	
		return;
	

	if (array->pAddr != NULL)
	
		free(array->pAddr);
		array->pAddr = NULL;
	
    
	free(array);
	array = NULL;

3.完整代码

头文件:dynamicArray.h

#pragma  once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//动态数组结构体
struct dynamicArray

	void ** pAddr; //维护真实在堆区创建的数组的指针

	int m_capacity;  // 数组容量

	int m_size;   //数组大小
;

//初始化数组
struct dynamicArray * init_DynamicArray(int capacity);

//插入数组
void insert_DynamicArray(struct dynamicArray * array, int pos, void * data);

//遍历数组
void foreach_DynamicArray(struct dynamicArray * array, void(*myPrint)(void*));

//删除数组  按位置删除
void removeByPos_DynamicArray(struct dynamicArray * array, int pos);

//按值删除数据
void removeByValue_DynamicArray(struct dynamicArray * array, void * data, int(*myCompare)(void *, void *));

//销毁数组
void destroy_DynamicArray(struct dynamicArray* array);

01 动态数组.c

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#include "dynamicArray.h"

////动态数组结构体
//struct dynamicArray
//
//	void ** pAddr; //维护真实在堆区创建的数组的指针
//
//	int m_capacity;  // 数组容量
//
//	int m_size;   //数组大小
//;
//
//
////初始化数组
//struct dynamicArray * init_DynamicArray(int capacity)
//
//	if (capacity <= 0)
//	
//		return NULL;
//	
//
//	//给数组分配空间
//
//	struct dynamicArray * array  = malloc(sizeof(struct dynamicArray));
//	if (array == NULL)
//	
//		return NULL;
//	
//
//	//给数组初始化
//	array->pAddr = malloc(sizeof(void *)* capacity);
//	array->m_capacity = capacity;
//	array->m_size = 0;
//	
//	return array;
//
//
////插入数组
//void insert_DynamicArray(struct dynamicArray * array , int pos  , void * data)
//
//	if ( array == NULL)
//	
//		return;
//	
//	if ( data == NULL)
//	
//		return;
//	
//
//	//无效位置  尾插
//	if (pos < 0 || pos > array->m_size)
//	
//		pos = array->m_size;
//	
//
//	//判断是否满了,如果满动态扩展
//	if (array->m_size == array->m_capacity)
//	
//		//1、计算新空间大小
//		int newCapacity = array->m_capacity * 2;
//
//		//2、创建新空间
//		void ** newSpace = malloc(sizeof(void *)* newCapacity);
//
//		//3、将原有数据拷贝到新空间下
//		memcpy(newSpace, array->pAddr, sizeof(void *)* array->m_capacity);
//
//		//4、释放原有内存空间
//		free(array->pAddr);
//
//		//5、更新新空间指向
//		array->pAddr = newSpace;
//
//		//6、更新新容量
//		array->m_capacity = newCapacity;
//	
//
//	//插入新元素
//
//	//移动元素 进行插入新元素
//	for (int i = array->m_size - 1; i >= pos; i--)
//	
//		//数据向后移动
//		array->pAddr[i + 1] = array->pAddr[i];
//	
//
//	//将新元素 插入到指定位置上
//	array->pAddr[pos] = data;
//	//更新大小
//	array->m_size++;
//
//
//
////遍历数组
//void foreach_DynamicArray(struct dynamicArray * array, void(*myPrint)(void*))
//
//	if (array == NULL)
//	
//		return;
//	
//	if (myPrint == NULL)
//	
//		return;
//	
//
//	for (int i = 0; i < array->m_size;i++)
//	
//		myPrint(array->pAddr[i]);
//	
//
//
//
////删除数组  按位置删除
//void removeByPos_DynamicArray(struct dynamicArray * array , int pos)
//
//	if ( NULL == array)
//	
//		return;
//	
//
//	if (pos < 0  || pos > array->m_size - 1)
//	
//		return;
//	
//
//	//数据前移
//	for (int i = pos; i < array->m_size - 1;i++)
//	
//		array->pAddr[i] = array->pAddr[i + 1];
//	
//
//	//更新数组大小
//	array->m_size--;
//
//
//
////按值删除数据
//void removeByValue_DynamicArray(struct dynamicArray * array , void * data , int (* myCompare)(void * ,void *))
//
//	if ( array == NULL)
//	
//		return;
//	
//	if ( data == NULL)
//	
//		return;
//	
//
//	for (int i = 0; i < array->m_size;i++)
//	
//		if (myCompare(array->pAddr[i], data))
//		
//				//如果找到要删除的数据,i就是要删除的具体位置
//			removeByPos_DynamicArray(array, i);
//			break;
//		
//	
//
//
//
////销毁数组
//void destroy_DynamicArray(struct dynamicArray* array)
//
//	if (array == NULL)
//	
//		return;
//	
//
//	if (array->pAddr != NULL)
//	
//		free(array->pAddr);
//		array->pAddr = NULL;
//	
//
//
//	free(array);
//	array = NULL;
//
//

//测试
struct Person

	char name[64];
	int age;
;


void myPrintPerson(void *data)

	struct Person * p = data;
	printf("姓名: %s 年龄:%d\\n", p->name, p->age);



int myComparePerson(void * data1, void *data2)

	struct Person *  p1 = data1;
	struct Person *  p2 = data2;

	return  strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;


int main()

	//初始化动态数组
	struct dynamicArray * array = init_DynamicArray(5);

	//准备数据
	struct Person p1 =  "亚瑟", 18 ;
	struct Person p2 =  "妲己", 20 ;
	struct Person p3 =  "安琪拉", 19 ;
	struct Person p4 =  "凯", 21 ;
	struct Person p5 =  "孙悟空", 999 ;
	struct Person p6 =  "李白", 999;

	printf("插入数据前: 容量:%d  大小:%d\\n", array->m_capacity, array->m_size);

	//插入数据
	insert_DynamicArray(array, 0, &p1);
	insert_DynamicArray(array, 0, &p2);
	insert_DynamicArray(array, 1, &p3);
	insert_DynamicArray(array, 0, &p4);
	insert_DynamicArray(array, -1, &p5);
	insert_DynamicArray(array, 2, &p6);

	// 凯 妲己 李白 安琪拉  亚瑟  孙悟空

	//遍历数据
	foreach_DynamicArray(array, myPrintPerson);


	printf("插入数据后: 容量:%d  大小:%d\\n", array->m_capacity, array->m_size);


	//测试删除 按位置删除
	removeByPos_DynamicArray(array, 2);
	printf("---------------------\\n");
	foreach_DynamicArray(array, myPrintPerson);
	printf("删除数据后: 容量:%d  大小:%d\\n", array->m_capacity, array->m_size);

	struct Person  p =  "亚瑟", 18 ;
	removeByValue_DynamicArray(array, &p, myComparePerson);
	printf("---------------------\\n");
	foreach_DynamicArray(array, myPrintPerson);
	printf("删除数据后: 容量:%d  大小:%d\\n", array->m_capacity, array->m_size);


	//array->pAddr = NULL;
	//array->m_capacity = 0;
	//array->m_size = 0;

	//销毁数组
	destroy_DynamicArray(array);
	array = NULL;

	system("pause");
	return EXIT_SUCCESS;

dynamicArray.c

#include "dynamicArray.h"

//初始化数组
struct dynamicArray * init_DynamicArray(int capacity)

	if (capacity <= 0)
	
		return NULL;
	

	//给数组分配空间

	struct dynamicArray * array = malloc(sizeof(struct dynamicArray));
	if (array == NULL)
	
		return NULL;
	

	//给数组初始化
	array->pAddr = malloc(sizeof(void *)* capacity);
	array->m_capacity = capacity;
	array->m_size = 0;

	return array;


//插入数组
void insert_DynamicArray(struct dynamicArray * array, int pos, void * data)

	if (array == NULL)
	
		return;
	
	if (data == NULL)
	
		return;
	

	//无效位置  尾插
	if (pos < 0 || pos > array->m_size)
	
		pos = array->m_size;
	

	//判断是否满了,如果满动态扩展
	if (array->m_size == array->m_capacity)
	
		//1、计算新空间大小
		int newCapacity = array->m_capacity * 2;

		//2、创建新空间
		void ** newSpace = malloc(sizeof(void *)* newCapacity);

		//3、将原有数据拷贝到新空间下
		memcpy(newSpace, array->pAddr, sizeof(void *)* array->m_capacity);

		//4、释放原有内存空间
		free(array->pAddr);

		//5、更新新空间指向
		array->pAddr = newSpace;

		//6、更新新容量
		array->m_capacity = newCapacity;
	

	//插入新元素

	//移动元素 进行插入新元素
	for (int i = array->m_size - 1; i >= pos; i--)
	
		//数据向后移动
		array->pAddr[i + 1] = array->pAddr[i];
	

	//将新元素 插入到指定位置上
	array->pAddr[pos] = data;
	//更新大小
	array->m_size++;



//遍历数组
void foreach_DynamicArray(struct dynamicArray * array, void(*myPrint)(void*))

	if (array == NULL)
	
		return;
	
	if (myPrint == NULL)
	
		return;
	

	for (int i = 0; i < array->m_size; i++)
	
		myPrint(array->pAddr[i]);
	



//删除数组  按位置删除
void removeByPos_DynamicArray(struct dynamicArray * array, int pos)

	if (NULL == array)
	
		return;
	

	if (pos < 0 || pos > array->m_size - 1)
	
		return;
	

	//数据前移
	for (int i = pos; i < array->m_size - 1; i++)
	
		array->pAddr[i] = array->pAddr[i + 1];
	

	//更新数组大小
	array->m_size--;



//按值删除数据
void removeByValue_DynamicArray(struct dynamicArray * array, void * data, int(*myCompare)(void *, void *))

	if (array == NULL)
	
		return;
	
	if (data == NULL)
	
		return;
	

	for (int i = 0; i < array->m_size; i++)
	
		if (myCompare(array->pAddr[i], data))
		
			//如果找到要删除的数据,i就是要删除的具体位置
			removeByPos_DynamicArray(array, i);
			break;
		
	



//销毁数组
void destroy_DynamicArray(struct dynamicArray* array)

	if (array == NULL)
	
		return;
	

	if (array->pAddr != NULL)
	
		free(array->pAddr);
		array->pAddr = NULL;
	

	free(array);
	array = NULL;

参考资料来源:

黑马程序员

c语言动态数组如何扩充空间

不是构造动态数组,是能够实现申请一个存储空间就往数组中输入一个数据,然后再返回数组的大小。然后再能申请一个存储空间再输入一个数据到数组中,再返回数组的大小。

不规定数组大小,只往数组中每输入一个数据元素就动态申请一个存储位置,数组长度加1

c语言动态数组扩充空间,主要是利用动态存储分配库函数来实现的,常用的有malloc函数和calloc函数。

malloc()是C语言中动态存储管理的一组标准库函数之一。其作用是在内存的动态存储区中分配一个长度为size的连续空间。其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。

例如:

char *x;

x = (char *)malloc(10); //x就指向了包含10个字符单元的存储空间。

扩展资料:

函数定义

其函数原型为void *malloc(unsigned int size);其作用是在内存的动态存储区中分配一个长度为size的连续空间。此函数的返回值是分配区域的起始地址,或者说,此函数是一个指针型函数,返回的指针指向该分配域的开头位置。

如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。

参考资料来源:百度百科-malloc函数

参考技术A 数据结构专门有讲的,下几个课件看看就行了.
1.分配内存空间函数malloc

调用形式: (类型说明符*) malloc (size) 功能:在内存的动态存储区中分配一块长度为"size" 字节的连续区域。函数的返回值为该区域的首地址。 “类型说明符”表示把该区域用于何种数据类型。(类型说明符*)表示把返回值强制转换为该类型指针。“size”是一个无符号数。例如: pc=(char *) malloc (100); 表示分配100个字节的内存空间,并强制转换为字符数组类型, 函数的返回值为指向该字符数组的指针, 把该指针赋予指针变量pc。

2.分配内存空间函数 calloc

calloc 也用于分配内存空间。调用形式: (类型说明符*)calloc(n,size) 功能:在内存动态存储区中分配n块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。(类型说明符*)用于强制类型转换。calloc函数与malloc 函数的区别仅在于一次可以分配n块区域。例如: ps=(struet stu*) calloc(2,sizeof (struct stu)); 其中的sizeof(struct stu)是求stu的结构长度。因此该语句的意思是:按stu的长度分配2块连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps。

3.释放内存空间函数free

调用形式: free(void*ptr); 功能:释放ptr所指向的一块内存空间,ptr 是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区应是由malloc或calloc函数所分配的区域:

main()

struct stu

int num;
char *name;
char sex;
float score;
*ps;
ps=(struct stu*)malloc(sizeof(struct stu));
ps->num=102;
ps->name="Zhang ping";
ps->sex='M';
ps->score=62.5;
printf("Number=%d\nName=%s\n",ps->num,ps->name);
printf("Sex=%c\nScore=%f\n",ps->sex,ps->score);
free(ps);
追问

是动态数组存储空间的扩充,不是用到链表这些存储结构的扩充

参考技术B 那我改下之前的回答,你的意思就是要做个内存管理堆栈系统嘛。

可以考虑这么做。

int *p = NULL;
p = malloc(xxx* sizeof(int)); //xxx你的存储空间总得有个大小吧
int *pFirst = p;
int size = 0;

然后封装一个int * my_malloc(malloc_size)

int ret_val = size;
size += malloc_size;
return p[size];

这个函数记载返回空间的首地址
每次输入一个数据时调用my_malloc加上你输入数据的大小就可以了。本回答被提问者采纳
参考技术C 什么叫动态数组,C的都是指定好下标的数组 参考技术D c语言动态数组扩充空间,主要是利用动态存储分配库函数来实现的,常用的有malloc函数和calloc函数。

malloc()是C语言中动态存储管理的一组标准库函数之一。其作用是在内存的动态存储区中分配一个长度为size的连续空间。其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。
例如:
char *x;
x = (char *)malloc(10); //x就指向了包含10个字符单元的存储空间

calloc()函数是在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
例如:
char*str = NULL;
str = (char*)calloc(10,sizeof(char));
strcpy(str, "Hello");
printf("String is %s\n",str);
free(str);

以上是关于1.动态数组的主要内容,如果未能解决你的问题,请参考以下文章

JS 索引数组关联数组和静态数组动态数组

javascript 动态删除数组

#yyds干货盘点# leetcode算法题:一维数组的动态和

1248.统计[优美子数组]-动态规划

算法-一维数组的动态和

动态规划法解最大子数组问题