• 欢迎访问C语言网www.dotcpp.com 比赛栏每月有奖月赛!举办比赛联系QQ:2045302297
  • 问题反馈、粉丝交流 QQ群327452739 蓝桥杯训练群:113766799 申请群时请备注排名里的昵称
  • C语言研究中心 为您提供有图、有料、解渴的C语言专题! 欢迎讨论!

C语言实现动态数组

编程经验 CTO 22925次浏览 1个评论

前言

在纯C语言编程中,数组的创建必须是固定的大小,因为C语言本身没有提供动态数组这种数据结构,这是一个让习惯了使用高级语言编程的人转做C开发面临的一个很头疼的问题,本篇文章就将介绍如何使用纯C语言编程实现一个对象来作为动态数组。
阅读本篇文章前,作者假设读者已经对C语言的基础概念有了一定了解,比如知道什么叫数组,知道C语言的基础语法等。如果读者还对C语言一无所知,请先对C语言做一个了解和入门级的学习之后,再来阅读本篇文章。

 

 

 

1:C语言中的数组分析

1.int my_array[100];

如上的代码,是使用C语言来创建了一个可以存放100个整数的数组,这个就是C语言中的数组。

 

2.这行代码一共做了两件事情:

(1):在栈或者全局数据区开辟了内存空间(如果是写在某个函数的内部,就是在栈上开辟的空间,如果是写在函数外面,就是在全局数据区上开辟的空间),开辟的内存空间大小为100*sizeof(int)个字节的内存空间。如果是在栈上开辟的,那么这块内存空间会在走到所在函数return之后释放,如果是在全局数据区,会随着进程的结束而释放。

(2):创建一个指针指向新开辟的内存区域,并将该区域的地址赋值给my_array保存,这样,我们就可以通过下标来对数组中的成员进行访问,比如:my_array[9]可以访问第10个成员。此外,还可以通过取地址指向内容的方式来访问数组成员,比如*(my_array+10),同样可以得到和my_array[10]一样的值。

 

3.从上面分析int my_array[100];这行代码可以看出,数组的操作本质上就是内存的操作,小标的索引只是一种糖衣语法。

 

 4.这种数组的缺点大家可以很容易想到,数组开辟的空间大小不根据实际数据的多少来决定,造成了空间上的浪费,另外当数据量大余数组的最大容量时,会造成程序的崩溃。

补充:有的朋友也许会说,按照上面的写法开辟数组后,执行my_array[100]=1或者my_array[102]=1都不出现崩溃,这个只是因为你的运气好,原因是在my_array指向的内存区域中,第101个或者第102位置正好有空间而已,因为我们写my_array[100]只能保证有100个位置是可以使用的,至于100以后的,那就要看系统的“心情”了!

二.定义一个my_vector结构体

接下来要介绍动态数组使用到的结构体以及对应的方法声明。首先创建一个myVector.h的文件,并编写如下的代码:

  1. // my_vector默认大小
  2. #define MY_VECTOR_DEF_SIZE 10
  3.  
  4. // 结构体定义
  5. typedef struct {
  6. int curSize; // 已用的大小
  7. int maxSize; // 数组最大存储大小
  8. int *data; // 实际的数据地址
  9. } my_vector;
  10.  
  11. // 初始化结构体
  12. void InitMyVector(my_vector *vector);
  13.  
  14. // 追加成员
  15. void AppendMyVector(my_vector *vector, int value);
  16.  
  17. // 返回指定下标中的数据,如果失败返回-1
  18. int GetMyVector(my_vector *vector, int index);
  19.  
  20. // 设置指定位置的指为指定数据
  21. void SetMyVector(my_vector *vector, int index, int value);
  22.  
  23. // 将当前的my_vecotr存储空间直接扩大一倍
  24. void DoubleCapacityMyVector(my_vector *vector);
  25.  
  26. // 释放资源
  27. void FreeMyVector(my_vector *vector);
  28.  

三.实现定义的my_vector结构体

声明完成之后要做的就是实现声明的函数了。创建一个myVector. C的文件,并编写如下代码:

 

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "myVector.h"
  4.  
  5.  
  6.  
  7.  
  8. // 初始化
  9. void InitMyVector(my_vector *vector)
  10. {
  11. // 数据初始化
  12. vector->curSize = 0;
  13. vector->maxSize = MY_VECTOR_DEF_SIZE;
  14.  
  15. // 开辟存储实际数据的空间
  16. vector->data = (int*)malloc(sizeof(int) * vector->maxSize);
  17. }
  18.  
  19. // 追加值
  20. void AppendMyVector(my_vector *vector, int value)
  21. {
  22. // 空间不够了需要增大
  23. DoubleCapacityMyVector(vector);
  24. // 添加新的数据到数组尾
  25. vector->data[vector->curSize++] = value;
  26. }
  27.  
  28. // 获的值
  29. int GetMyVector(my_vector *vector, int index)
  30. {
  31. // 输入的数据如果小于0或者是大余数组最大存储值时,直接退出程序,因为数据不合法
  32. if (index >= vector->curSize || index < 0) { exit(1); } // 如果输入的是一个合法的数据那么返回对应的数据 return vector->data[index];
  33. }
  34.  
  35. // 设置值
  36. void SetMyVector(my_vector *vector, int index, int value)
  37. {
  38. // 用0作为默认值来他填充数组
  39. while (index >= vector->curSize)
  40. {
  41. AppendMyVector(vector, 0);
  42. }
  43.  
  44. vector->data[index] = value;
  45. }
  46.  
  47. // 扩大空间
  48. void DoubleCapacityMyVector(my_vector *vector)
  49. {
  50. if (vector->curSize >= vector->maxSize)
  51. {
  52. // 扩大数组大小为当前的两倍
  53. vector->maxSize *= 2;
  54. vector->data = (int*)realloc(vector->data, sizeof(int) * vector->maxSize);
  55. }
  56. }
  57.  
  58. //释放空间
  59. void FreeMyVector(my_vector *vector)
  60. {
  61. free(vector->data);
  62. }
  63.  

四.使用my_vector结构体创建结构体对象

创建一个main.c的文件,并编写如下代码

 

  1. #include <stdio.h>
  2. #include "myVector.h"
  3.  
  4. int main()
  5. {
  6. // 声明vector对象
  7. my_vector vector;
  8. int i;
  9. // 初始化vector对象
  10. InitMyVector(&vector);
  11.  
  12. // 随便初始化点数据
  13. for (i = 0; i <200; i++)
  14. {
  15. AppendMyVector(&vector, i);
  16. }
  17.  
  18. // 测试用,在第200位置设置1,200之前的数据如果为空自动填充为0,当前程序就是200-299为0
  19. SetMyVector(&vector, 300, 1);
  20. // 测试用,取指定位置的数据
  21. printf("%d\n", GetMyVector(&vector, 6));
  22. // 测试用,输出每一个成员
  23. for (i = 0; i < vector.curSize; i++)
  24. {
  25. printf("%d %d\n", i, GetMyVector(&vector, i));
  26. }
  27. // 使用完之后要释放,不然会有内存泄露
  28. FreeMyVector(&vector);
  29.  
  30. return 0;
  31. }
  32.  

到此为止,我们已经实现了用C语言去创建动态数组,其实动态数组的本质也是静态的,只不过空间的增加我们做了一些手动的处理而已。

类似的,删除指定位置的数据也可以用上面的方式去实现。请大家自己理解学习尝试进行实现!

 

C语言网提供「C语言、C++、算法竞赛」在线课程,全部由资深研发工程师或ACM金牌大佬亲授课,更科学、全面的课程体系,以在线视频+在线评测的学习模式学习,学练同步,拒绝理论派,真正学会编程!还有奖学金等增值福利等你!

C语言网, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C语言实现动态数组
喜欢 (38)
[jinyangH@aliyun.com]
分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
(1)个小伙伴在吐槽
  1. 用malloc分配实现动态数组不是比较简单嘛?
    MOYUN2019-11-01 23:46 回复