c语言动态数组的实现

动态数组是在程序运行时动态分配内存空间的数组,可以根据需要随时改变大小。在C语言中,动态数组通常通过指针和malloc函数来实现。

  1. 使用malloc函数动态分配内存空间:
int *arr;
int size = 10;
arr = (int*)malloc(size * sizeof(int));
  1. 使用realloc函数调整动态数组的大小
int new_size = 20;
arr = (int*)realloc(arr, new_size * sizeof(int));
  1. 使用free函数释放动态数组占用的内存
free(arr);
  1. 使用指针操作动态数组元素:
arr[0] = 10;
arr[1] = 20;

需要注意的是,动态数组在使用完毕后应该及时释放内存,避免内存泄漏。另外,使用动态数组时需要注意数组下标的范围,避免访问越界导致程序崩溃。

动态数组的实现

模块化的编程方式:将头文件,函数,和main文件分离出来

函数头文件:对函数和结构体进行声明

函数头文件的代码

#ifndef __MALLOC_H_
#define __MALLOC_H_
#include <stdbool.h>
// 定义符号常量,确定数组拥有的元素个数
#define VECTOR_INIT_CAPACITY 1
// 定义学生结构体:包含学生 id 名字,性别...
struct student {
	int id;
	char name[20];
	int gender;
	int mark;

};

// 动态数组vector包含动态数组的4个方法
struct vector {
	bool (*append) (struct vector* pVec, struct student data);
	struct student(*get)(struct vector* pVec, int index);
	void (*clear)(struct vector* pVec);
	void (*remove)(struct vector* pVec, int index);

	struct student* pData;// 数组首元素指针
	int size; // 数组已经存放的大小
	int capacity; // 数组容器的容量


};
void vectorInit(struct vector* pVec); // 初始化函数
bool vectorAppend(struct vector* pVec, struct student data);// 函数的添加
struct student vectorGet(struct vector* pVec, int index); // 获取数据
void vectorRemove(struct vector* pVec, int index); // 移除数组中的元素
void vectorClear(struct vector* pVec); // 清空数组
void vectorDestroy(struct vector* pVec); // 销毁数组

#endif

数组实现函数UTIL类别

函数具体实现代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "MallocLineData.h"
// 初始化函数
void vectorInit(struct vector* pVec) {
    // 初始化对象的方法
    pVec->get = vectorGet;
    pVec->append = vectorAppend;
    pVec->remove = vectorRemove;
    pVec->clear = vectorClear;


    pVec->pData = (struct student*)malloc(sizeof(struct student) * VECTOR_INIT_CAPACITY);
    pVec->size = 0;
    pVec->capacity = VECTOR_INIT_CAPACITY;
}
// 添加函数的代码
bool vectorAppend(struct vector* pVec, struct student data) {
    if (pVec->size >= pVec->capacity) {
        struct student* newData = (struct student*)
            realloc(pVec->pData, pVec->capacity * sizeof(struct student) * 2);
        if (newData == NULL) {
            return false;
        }
        pVec->pData = newData;
        pVec->capacity = 2 * pVec->capacity;
    }
    pVec->pData[pVec->size] = data;
    pVec->size++;
    return true;
}
// 获取数组元素的首地址
struct student vectorGet(struct vector* pVec, int index) {
    return pVec->pData[index];
}
// 移除数组中的元素
void vectorRemove(struct vector* pVec, int index) {
    for (int i = index; i < pVec->size - 1; i++) {
        pVec->pData[i] = pVec->pData[i + 1];
    }
    pVec->size -= 1;
}
//清除数组中元素的方法
void vectorClear(struct vector* pVec) {
    if (pVec->pData != NULL) {
        free(pVec->pData);
    }
    pVec->pData = (struct student*)malloc
    (sizeof(struct student) * VECTOR_INIT_CAPACITY);
    pVec->size = 0;
    pVec->capacity = VECTOR_INIT_CAPACITY;
}
// 销毁不需要使用的数组
void vectorDestroy(struct vector* pVec) {
    if (pVec->pData == NULL) {
        return;

    }
    free(pVec->pData);
    pVec->pData = NULL;
    pVec->size = 0;
    pVec->capacity = 0;
}


main函数代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "MallocLineData.h"

int main()
{
   // 对象的声明
	struct vector vec;
	vectorInit(&vec);
	struct student s1 = { 1,"小黄",1,90 };
	vec.append(&vec, s1);
	for (int i = 0; i < vec.size; i++) {
		struct student s = vec.get(&vec, i);
		printf("%d %s %d %d\n", s.id, s.name, s.gender, s.mark);
	}
	printf("size:%d\n", vec.size);
	printf("capacity:%d\n", vec.capacity);

	// remove方法的测试
	vec.remove(&vec, 0);
	for (int i = 0; i < vec.size; i++) {
		struct student s = vec.get(&vec, i);
		printf("%d %s %d %d\n", s.id, s.name, s.gender, s.mark);
	}
	printf("size:%d\n", vec.size);
	printf("capacity:%d\n", vec.capacity);

	// 调用清除数据的方法
	vec.clear(&vec);
	for (int i = 0; i < vec.size; i++) {
		struct student s = vec.get(&vec, i);
		printf("%d %s %d %d\n", s.id, s.name, s.gender, s.mark);
	}
	printf("size:%d\n", vec.size);
	printf("capacity:%d\n", vec.capacity);

	// 调用销毁数据的方法
	vectorDestroy(&vec);
	for (int i = 0; i < vec.size; i++) {
		struct student s = vec.get(&vec, i);
		printf("%d %s %d %d\n", s.id, s.name, s.gender, s.mark);
	}
	printf("size:%d\n", vec.size);
	printf("capacity:%d\n", vec.capacity);
}

动态数组运行结果展示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/378834.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java八股面试系列】并发编程-进程与线程

目录 进程 线程 线程和进程的区别 Java线程和操作系统的线程的区别 请简要描述一下进程和线程在Java中的关系&#xff0c;区别及优缺点&#xff1f;​编辑​编辑​编辑 并发和并行的区别 为什么要使用多线程? 线程的生命周期 什么是线程上下文切换? sleep() 方法和…

Java Stram 流对于返回对象的处理 (结束流)

Java Stram 流对于返回对象的处理 &#xff08;结束流&#xff09; package com.zhong.streamdemo.showdownstreamdemo;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.*; import java.util.stream.Collectors; im…

Springboot 整合 Elasticsearch(三):使用RestHighLevelClient操作ES ①

&#x1f4c1; 前情提要&#xff1a; Springboot 整合 Elasticsearch&#xff08;一&#xff09;&#xff1a;Linux下安装 Elasticsearch 8.x Springboot 整合 Elasticsearch&#xff08;二&#xff09;&#xff1a;使用HTTP请求来操作ES 目录 一、Springboot 整合 Elasticsea…

【FPGA】快速学习路径

FPGA学习教程、功利式学习路径、以找工作为目的&#xff0c;早日入门FPGA_哔哩哔哩_bilibili

Redis篇之集群

一、主从复制 1.实现主从作用 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;就需要搭建主从集群&#xff0c;实现读写分离。主节点用来写的操作&#xff0c;从节点用来读操作&#xff0c;并且主节点发生写操作后&#xff0c;会把数据同…

倒计时61天

M-智乃的36倍数(normal version)_2024牛客寒假算法基础集训营3 (nowcoder.com) //非ac代码,超时了,54.17/100#include<bits/stdc.h> using namespace std; const int N1e55; const int inf0x3f3f3f3f; #define int long long int n; string s1[N]; void solve() {cin>…

第五篇【传奇开心果系列】vant开发移动应用示例:深度解读高度可定制

传奇开心果博文系列 系列博文目录Vant 开发移动应用示例系列 博文目录前言一、Vant高度可定制的重要作用二、样式定制介绍和示例代码三、组件定制介绍和示例代码四、组件库定制介绍和示例代码五、主题定制介绍和示例代码六、语言环境定制介绍和示例代码七、资源加载定制介绍和示…

[当人工智能遇上安全] 11.威胁情报实体识别 (2)基于BiGRU-CRF的中文实体识别万字详解

您或许知道&#xff0c;作者后续分享网络安全的文章会越来越少。但如果您想学习人工智能和安全结合的应用&#xff0c;您就有福利了&#xff0c;作者将重新打造一个《当人工智能遇上安全》系列博客&#xff0c;详细介绍人工智能与安全相关的论文、实践&#xff0c;并分享各种案…

DMA直接内存访问,STM32实现高速数据传输使用配置

1、DMA运用场景 随着智能化、信息化的不断推进&#xff0c;嵌入式设备的数据处理量也呈现指数级增加&#xff0c;因此对于巨大的数据量处理的情况时&#xff0c;必须采取其它的方式去替CPU减负&#xff0c;以保证嵌入式设备性能。例如SD卡存储器和音视频、网络高速通信等其它情…

探讨CSDN等级制度:博客等级、原力等级、创作者等级

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…

数据结构:双向链表

文章目录 1. 双向带头循环链表的结构2. 相关操作2.1 创建节点2.2 尾插2.3 头插2.4 打印2.5 尾删2.6 头删2.7 查找2.8 指定位置前/后插入2.9 删除指定位置的节点2.10 删除指定位置后的节点2.11 销毁链表 3.顺序表与链表区别 1. 双向带头循环链表的结构 与单链表不同的是&#xf…

C#,奥西里斯数(Osiris Number)的算法与源代码

1 奥西里斯数(Osiris Number) 奥西里斯数(Osiris Number)是一个数字&#xff0c; 其值等于通过将其自身数字的所有排列相加而形成的所有数字的值之和。 计算结果&#xff1a; 2 源程序 using System; namespace Legalsoft.Truffer.Algorithm { /// <summary> /…

Django学习记录02

1.请求与响应 1.1get与post的区别 get 一般是从url输入地址&#xff0c;会调用get请求 post 一般是内部数据传输# get请求 def something(request):# req是一个对象&#xff0c;封装了用户发送过来的所有请求相关数据# 1.获取请求方式 http://localhost:8000/something# pri…

Ubuntu22.04 gnome-builder gnome C 应用程序习练笔记(二)

gnome-builder创建的程序&#xff0c;在工程树中有三个重要程序&#xff1a;main主程序、application应用程序和window主窗口程序。main整个程序的起始&#xff0c;它会操作application生产应用环境&#xff0c;application会操作window生成主窗口&#xff0c;于是就有了 appli…

【lesson47】进程通信之system V(共享内存)补充知识

文章目录 补充知识 补充知识 进行通信的key值问题&#xff0c;进程要通信的对方进程怎么能保证对方能看到&#xff0c;并且看到的就是该进程创建的共享内存的。 所以就通过key值来标识共享内存&#xff0c;key值是几不重要&#xff0c;只要在系统里是唯一的即可。 这样server和…

Java图形化界面编程——Container容器 笔记

2.3 Container容器 2.3.1 Container继承体系 Winow是可以独立存在的顶级窗口,默认使用BorderLayout管理其内部组件布局;Panel可以容纳其他组件&#xff0c;但不能独立存在&#xff0c;它必须内嵌其他容器中使用&#xff0c;默认使用FlowLayout管理其内部组件布局&#xff1b;S…

2月8日作业

1、现有文件test.c\test1.c\main.c,编写Makkefile 代码&#xff1a; CCgcc EXEa.out OBJS$(patsubst %.c,%.o,$(wildcard *.c)) CFLAGS-c -oall:$(EXE)$(EXE):$(OBJS)$(CC) $^ -o $%.o:%.c$(CC) $(CFLAGS) $ $^.PHONY:cleanclean:rm $(OBJS) $(EXE)运行结果&#xff1a; 2、…

【网络】:序列化和反序列化

序列化和反序列化 一.json库 二.简单使用json库 前面已经讲过TCP和UDP&#xff0c;也写过代码能够进行双方的通信了&#xff0c;那么有没有可能这种通信是不安全的呢&#xff1f;如果直接通信&#xff0c;可能会被底层捕捉&#xff1b;可能由于网络问题&#xff0c;一方只接收到…

云计算运营模式介绍

目录 一、云计算运营模式概述 1.1 概述 二、云计算服务角色 2.1 角色划分 2.1.1 云服务提供商 2.1.2 云服务消费者 2.1.3 云服务代理商 2.1.4 云计算审计员 2.1.5 云服务承运商 三、云计算责任模型 3.1 云计算服务模式与责任关系图 3.2 云计算服务模式与责任关系解析…

【LeetCode每日一题】525连续数组 303区域和检索(前缀和的基本概念和3个简单案例)

前缀和 // 构造prefix let prefix [0] arr.forEach(num > {prefix.push(prefix.at(-1) num); })如果想要计算某个区间 i 到 j 这个子数组的和时&#xff0c;可以根据 prefix[j1] - prefix[i] 获得。 例题1&#xff1a;303.区域和检索 - 数组不可变 给定一个整数数组 num…