前言

在纯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的文件,并编写如下的代码:

// my_vector默认大小

#define MY_VECTOR_DEF_SIZE 10

// 结构体定义

typedef struct {

int curSize; // 已用的大小

int maxSize; // 数组最大存储大小

int *data; // 实际的数据地址

} my_vector;

// 初始化结构体

void InitMyVector(my_vector *vector);

// 追加成员

void AppendMyVector(my_vector *vector, int value);

// 返回指定下标中的数据,如果失败返回-1

int GetMyVector(my_vector *vector, int index);

// 设置指定位置的指为指定数据

void SetMyVector(my_vector *vector, int index, int value);

// 将当前的my_vecotr存储空间直接扩大一倍

void DoubleCapacityMyVector(my_vector *vector);

// 释放资源

void FreeMyVector(my_vector *vector);

三.实现定义的my_vector结构体

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

#include

#include

#include "myVector.h"

// 初始化

void InitMyVector(my_vector *vector)

{

// 数据初始化

vector->curSize = 0;

vector->maxSize = MY_VECTOR_DEF_SIZE;

// 开辟存储实际数据的空间

vector->data = (int*)malloc(sizeof(int) * vector->maxSize);

}

// 追加值

void AppendMyVector(my_vector *vector, int value)

{

// 空间不够了需要增大

DoubleCapacityMyVector(vector);

// 添加新的数据到数组尾

vector->data[vector->curSize++] = value;

}

// 获的值

int GetMyVector(my_vector *vector, int index)

{

// 输入的数据如果小于0或者是大余数组最大存储值时,直接退出程序,因为数据不合法

if (index >= vector->curSize || index < 0) { exit(1); } // 如果输入的是一个合法的数据那么返回对应的数据 return vector->data[index];

}

// 设置值

void SetMyVector(my_vector *vector, int index, int value)

{

// 用0作为默认值来他填充数组

while (index >= vector->curSize)

{

AppendMyVector(vector, 0);

}

vector->data[index] = value;

}

// 扩大空间

void DoubleCapacityMyVector(my_vector *vector)

{

if (vector->curSize >= vector->maxSize)

{

// 扩大数组大小为当前的两倍

vector->maxSize *= 2;

vector->data = (int*)realloc(vector->data, sizeof(int) * vector->maxSize);

}

}

//释放空间

void FreeMyVector(my_vector *vector)

{

free(vector->data);

}

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

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

#include

#include "myVector.h"

int main()

{

// 声明vector对象

my_vector vector;

int i;

// 初始化vector对象

InitMyVector(&vector);

// 随便初始化点数据

for (i = 0; i <200; i++)

{

AppendMyVector(&vector, i);

}

// 测试用,在第200位置设置1,200之前的数据如果为空自动填充为0,当前程序就是200-299为0

SetMyVector(&vector, 300, 1);

// 测试用,取指定位置的数据

printf("%d\n", GetMyVector(&vector, 6));

// 测试用,输出每一个成员

for (i = 0; i < vector.curSize; i++)

{

printf("%d %d\n", i, GetMyVector(&vector, i));

}

// 使用完之后要释放,不然会有内存泄露

FreeMyVector(&vector);

return 0;

}

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

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

C语言网, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C语言实现动态数组!

C语言中动态数组的作用,C语言实现动态数组相关推荐

  1. c语言中的除号什么作用,c语言中除号用什么表示

    前言继承是OOP设计中的重要概念.在C++语言中,派生类继承基类有三种继承方式:私有继承(private).保护继承(protected)和公有继承(public).一.继承规则继承是C++中的重要特 ...

  2. c语言中预处理指令的作用,C语言中常用预处理指令

    转载自 https://blog.csdn.net/farsight2009/article/details/58602886 姓名:张艳博 学号:17021223249 [嵌牛导读]: C语言中常用 ...

  3. c语言中初始化的主要作用,C语言初始化——栈的初始化

    栈是一种具有后进先出性质的数据组织方式,也就是说后存放的先取出,先存放的后取出.栈底是第一个进栈的数据所处的位置,栈顶是最后一个进栈的数据所处的位置. 1.满栈与空栈 根据SP指针指向的位置,栈可以分 ...

  4. c语言中各种函数的作用,C语言常用函数用法大全

    C语言是当中广泛的计算机编程语言,是所有计算机编程语言的祖先,其他计算机编程语言包括当前流行的Java语言,都是用C语言实现的,C语言是编程效率高的计算机语言,既能完成上层应用开发,也能完成底层硬件驱 ...

  5. c语言中 程序各步作用,C语言学习网总结C语言学习五步曲

    很多人对C语言的第一感觉就是太难了,很难理解这种语言,也不知道该如何来理解,书也看了,视频也看了,但就是没什么太大的作用,那么C语言究竟该如何来学? C语言作为一门计算机语言,想要真正的掌握并使用需要 ...

  6. C语言中的逗号的作用,C语言逗号运算符和逗号表达式基础总结

    逗号运算符的作用: 1,起分隔符的作用: 定义变量用于分隔变量:int a,b 输入或输出时用于分隔输出表列 printf("%d%d",a,b) 2,用于逗号表达式的顺序运算符 ...

  7. c语言中符号起什么作用,C语言中的符号 和 | 是什么意思?

    &: 在C语言中有两种意思,一种是取地址符,是单目运算符:另一种是位运算符,表示"按位与",是双目运算符.|: 是位运算符,表示"按位或". 资料扩展 ...

  8. c语言中反斜线的作用,C语言中反斜杠的使用

    问题1: #define f(z) (z<2)?(((2-z)*(2-z))*((2-z)*(2-z)))*\ (((2-z)*(2-z))*((2-z)*(2-z)))/560:0; 上面这个 ...

  9. c语言中 小括号的作用,c语言小括号的用法有哪些用处

    C语言的小括号里面表示一条语句,返回值是多条语句中最靠右的语句的返回值,下面学习啦小编就为大家介绍c语言小括号的用法,欢迎大家阅读. c语言小括号的用法:单小括号 () ①命令组.括号中的命令将会新开 ...

  10. c语言中循环结构的作用,C语言循环结构知识点

    C语言循环结构知识点 引导语:循环结构可以减少源程序重复书写的工作量,用来描述重复执行某段算法的问题,这是程序设计中最能发挥计算机特长的程序结构.以下是百分网小编分享给大家的C语言循环结构知识点,欢迎 ...

最新文章

  1. DATAGRID学习
  2. php 打印变量内存地址_Python合集之Python变量
  3. 设计模式的概念和分类
  4. java阻塞队列作用_简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用...
  5. 阿里云新推出 HiTSDB + IoT套件 物联网设备上云步入快车道
  6. 阿里实习 电面,面试
  7. 鸿蒙手机(真机)播放音乐-第二集
  8. 想尝试搭建图像识别系统?这里有一份TensorFlow速成教程
  9. python读取mysql数据库行数_使用python读取mysql数据库并进行数据的操作
  10. 接雨水c语言算法精解,详解一道高频面试题:接雨水
  11. python爬虫网络库下载_Python3 DHT 网络磁力种子爬虫
  12. CSS布局及实例仿LOL主页
  13. nginx静态文件缓存
  14. 使用Requests库进行网页爬取
  15. Cerebral Cortex:基因和环境对大脑功能连接的影响
  16. Linux C报错: /usr/bin/ld: cannot find -ldb
  17. Matlab 矩阵运算(1)
  18. Python之面相对象 - 双下方法
  19. Angular CLI ng常用命令整理
  20. MySQL 服务正在启动 .MySQL 服务无法启动。踩坑(瞎子日记1)

热门文章

  1. MP3文件转换成arduino可以直接播放的wav格式,MP3转WAV工具
  2. PSO求解梯级水库优化调度
  3. 基于FPGA的costas环同步系统仿真与分析
  4. 什么是OOP(面向对象编程)?
  5. pyodbc psutil wmi paramiko
  6. 开始认真学习Android了
  7. 【Python】如何在Windows操作系统下安装Python和Networkx
  8. 【转载】Android数据库(SqlLite)操作和db文件查看
  9. Node.js笔记 - 修改文件后自动重启node服务
  10. QT中封装的IP地址的widget