C语言实现动态数组 超详细 小白也能懂

C语言数据结构一:动态数组 C语言数据结构一:动态数组;可插值,可删除,可动态拓展容量。 阅读详情
AI摘要

本文详细介绍了如何使用C语言实现动态数组,包括定义结构体、创建动态数组函数(create_array)、读取和更新数组元素的函数(read_array和update_array),以及释放内存的delete_array函数。通过实例展示了动态数组的创建、操作和内存管理过程。

前言

在学习数据结构时,我们最先接触的便是动态数组,本文将手把手带你用C语言实现动态数组。

具体实现

定义结构体

typedef struct 
{
    int* array;
    size_t size;
} dynamic_array;
  • 结构体内部包含两个成员:
    • int* array:一个指向整型数组的指针。这意味着动态数组实际存储的是一个整数数组的地址,通过这个指针可以访问和操作数组中的元素。
    • size_t size:一个无符号整数类型变量,通常用于表示数组当前的实际大小或容量,即数组中可用元素的数量。

通过使用这个结构体,可以创建并管理一个可变长度的整数数组,可以在运行时根据需要动态地改变其大小。在后续的函数实现中(如 create_array()、read_array() 等),会利用这两个成员来分配、读取和释放内存空间等操作。

用于创建动态数组的函数 Function to create a new dynamic array

dynamic_array* create_array(size_t size) 
{
    dynamic_array* arr = malloc(sizeof(dynamic_array));
    if (arr == NULL)
    {
        printf("Error: Failed to allocate memory for dynamic array structure.\n");
        return NULL;
    }
    arr->array = malloc(size * sizeof(int));
    if (arr->array == NULL)
    {
        printf("Error: Failed to allocate memory for the internal integer array.\n");
        free(arr);  
        return NULL;
    }
    arr->size = size;                       
    return arr;                             
}

基础知识解读

->

在C语言中,-> 运算符用于访问结构体或联合体类型的指针所指向的成员。它等价于解引用指针后通过.运算符来访问成员。

具体到 arr->array = malloc(size * sizeof(int)); 这行代码:

  1. arr 是一个指向 dynamic_array 结构体类型的指针。
  2. -> 运算符用于访问 arr 指向的结构体实例中的成员变量 array。
  3. 也就是说,这行代码为 arr 所指向的 dynamic_array 结构体的 array 成员分配内存空间。通常情况下,array 成员是一个指向整数数组的指针,这里根据传入的 size 参数动态分配了足够存储 size 个整数的空间。

简而言之,arr->array 相当于 (arr).array,即先通过指针 arr 访问到 dynamic_array 结构体对象,然后在这个结构体对象内部找到并操作 array 成员。

malloc

malloc 是C语言的动态内存分配函数,它从堆上分配指定大小的连续内存空间,并返回指向这块内存区域的指针。如果分配成功,则返回非空指针;否则(例如,当系统内存不足时),返回NULL

定义了一个名为 create_array 的函数,用于创建一个指定大小的动态数组。

函数接受一个 size_t 类型参数 size,表示要创建的整数数组的元素个数。

具体步骤如下:

  1. 调用 malloc(sizeof(dynamic_array)) 函数分配足够存储 dynamic_array 结构体的内存空间,并将返回的内存地址赋给指向该结构体类型的指针 arr。
  2. 为 dynamic_array 结构体中的 array 成员分配内存,调用 malloc(size * sizeof(int)) 分配能够存储 size 个整数的空间。这里的 sizeof(int) 获取的是每个整数在当前系统上占用的字节数。然后将新分配的内存地址赋给 arr->array,即为动态数组的内部整数数组分配了内存。
  3. 将传入的参数 size 赋给 arr->size,记录动态数组的实际容量(即可以存储多少个整数)。
  4. 最后,函数返回指向新创建的 dynamic_array 结构体的指针 arr,这样调用者就可以通过这个指针操作和访问这个动态数组了。

用于读取动态数组元素的函数Function to read an element from a dynamic array

int read_array(dynamic_array* arr, size_t index) {
if (index < arr->size)
    return arr->array[index];
else
    {
        printf("Error: index out of bounds: %d\n", index);
        return -1;
    }
}

这段代码定义了一个名为 read_array 的函数,用于从动态数组中读取指定索引处的整数值。函数接受两个参数:

  1. dynamic_array* arr:指向动态数组结构体的指针。
  2. size_t index:要读取的元素在数组中的索引位置。

函数执行流程如下:

  • 首先检查传入的索引值(index)是否小于动态数组的大小(arr->size)。如果索引有效(即 index < arr->size),则返回数组中对应索引位置的整数值,通过表达式 arr->array[index] 访问。
  • 如果索引超出数组边界(即 index >= arr->size),函数会输出错误信息 "Error: index out of bounds: %d\n",其中 %d 会被替换为实际的非法索引值,并返回一个特殊值 -1,表示读取失败或异常情况。

该函数提供了安全访问动态数组元素的方法,同时也确保了当尝试访问不存在的元素时能够提供明确的错误反馈。

用于更新动态数组元素的函数Function to update an element from a dynamic array

void update_array(dynamic_array* arr, size_t index, int value) {
    if (index < arr->size)
        arr->array[index] = value;
    else
        printf("Error: index out of bounds: %d\n", index);
}

这段代码定义了一个名为 update_array 的函数,其功能是更新动态数组中指定索引位置的元素值。该函数接受三个参数:

  1. dynamic_array* arr:指向动态数组结构体的指针。
  2. size_t index:要更新的元素在数组中的索引位置。
  3. int value:新值,将用于替换原数组中对应索引位置的值。

函数执行过程如下:

  • 首先检查传入的索引值(index)是否小于动态数组的大小(arr->size)。如果索引有效(即 index < arr->size),则将整数 value 赋给数组中对应索引位置的元素,通过表达式 arr->array[index] = value 完成更新操作。
  • 如果索引超出数组边界(即 index >= arr->size),函数会输出错误信息 "Error: index out of bounds: %d\n",其中 %d 会被替换为实际的非法索引值。但此处与 read_array 函数不同,它没有返回任何值,仅输出错误信息,不会改变数组的状态。

此函数提供了对动态数组元素进行安全更新的能力,并在尝试访问不存在的元素时给出错误提示。

用于删除动态数组的函数Function to delete a dynamic array

这段代码定义了一个名为 delete_array 的函数,用于释放动态数组占用的内存资源并确保后续不再使用已释放的指针。该函数接受一个参数:

  1. dynamic_array* arr:指向动态数组结构体的指针。

函数执行过程如下:

  • 首先调用 free(arr->array) 来释放动态数组内部整数数组所占用的内存空间,并将 arr->array 设置为 NULL。这样可以防止程序后续尝试访问已释放的内存区域,从而避免潜在的未定义行为或错误。

  • 接着调用 free(arr) 释放整个动态数组结构体(包括其成员变量 size)占用的内存空间。

  • 最后,将 arr 指针本身设置为 NULL。虽然这个操作不会改变传入函数的实际参数值(因为C语言中传递的是指针副本),但在某些情况下,特别是在单个作用域内需要确保指针在释放内存后不会被误用时,这是一个良好的编程实践。它能够明确地表明该指针当前不再指向有效数据,并且有助于调试和减少因误用已释放指针导致的问题。

需要注意的是,在实际编程中,尽管在函数内部将 arr 设置为 NULL 对于函数外部的影响有限,但这种做法可以增强代码的可读性和防御性编程水平。

Main函数

int main() {
    dynamic_array* arr = create_array(10);
    update_array(arr,6,99);
    int value = read_array(arr, 6);
    printf("The value is: %d \n", value);
    delete_array(arr);
}

这段代码是 main() 函数的实现,用于演示如何创建、操作和销毁动态数组。

  1. 首先调用 create_array(10) 函数,创建一个可以存储10个整数的动态数组,并将其地址赋值给指针变量 arr。

  2. 接着通过调用 update_array(arr, 6, 99) 函数,在动态数组中索引为6的位置处更新元素值为99。这里假设数组索引从0开始计数,因此第6个位置实际上是在数组中的第7个元素(因为数组下标是从0开始)。

  3. 调用 read_array(arr, 6) 函数,从动态数组中读取索引为6的位置处的整数值,并将该值存储在变量 value 中。

  4. 使用 printf("The value is: %d \n", value); 输出刚刚读取到的整数值,显示更新后的数组元素内容。

  5. 最后,调用 delete_array(arr) 函数来释放之前分配给动态数组的所有内存资源,完成对动态数组的生命周期管理。

总结


#include<stdio.h>
#include<stdlib.h>
//Define a dynamic array structure that stores an array and its size
typedef struct 
{
    int* array;
	size_t size;
}dynamic_array;
//Function to create a new dynamic array
dynamic_array* create_array(size_t size) 
{
    dynamic_array* arr = malloc(sizeof(dynamic_array));
    if (arr == NULL)
    {
        printf("Error: Failed to allocate memory for dynamic array structure.\n");
        return NULL;
    }
    arr->array = malloc(size * sizeof(int));
    if (arr->array == NULL)
    {
        printf("Error: Failed to allocate memory for the internal integer array.\n");
        free(arr);  
        return NULL;
    }
    arr->size = size;                       
    return arr;                             
}
//Function to read an element from a dynamic array
int read_array(dynamic_array* arr, size_t index) {
if (index < arr->size)
    return arr->array[index];
else
    {
        printf("Error: index out of bounds: %d\n", index);
        return -1;
    }
}
//Function to update an element from a dynamic array
void update_array(dynamic_array* arr, size_t index, int value) {
    if (index < arr->size)
        arr->array[index] = value;
    else
        printf("Error: index out of bounds: %d\n", index);
}
//Function to delete a dynamic array
void delete_array(dynamic_array* arr) {
    free(arr->array);
    arr->array = NULL;
    free(arr);
    arr = NULL;
}
//main
int main() {
    dynamic_array* arr = create_array(10);
    update_array(arr,6,99);
    int value = read_array(arr, 6);
    printf("The value is: %d \n", value);
    delete_array(arr);
    return 0;
}

该源码来自B站up Micro_Frank

c语言实现动态数组 前言 最近研究二级指针,发现了二级指针配合realloc函数其实可以用来实现动态数组 这篇博文我只实现动态数组的push_back操作,就是在数组的末端增加一个元素 修正一个思想 c语言的函数参数,是不能在函数内部被修改的!!!因为传进来的参数,是拷贝构造 我们平时说"传指针就可以在函数内修改参数",实际上是误导学生的说法, 因为这个时候,函数的参数是指针,而这时候你会发现,你函数返回以后,这个指... 阅读详情

相关推荐

【C语言】动态数组vector实现

C语言中缺少类似C++ Vector或者Java ArrayList 的通用动态数组的库函数。但有些场景数组的容量没法确定,故自己造个简单的动态数组轮子,以便后续能使用得到。 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <stdbool.h> /* 数组...

小灰灰土拨鼠的博客 807

动态数组(Array)

动态数组的概念 我们可以理解为动态数组就是在普通数组上增加了一个可以根据元素的个数动态调整数组大小的功能。在Java中提供的数组一般都是静态数组int[]char[]long[](定义之后没法改变长度)这时候就需要我们自己定义一个类,拓展基础数组的功能就为动态数组。 public class Array { private int[] data; //存放元素仍是整型数组; private int size; //表是动态数组中已经存储的元素个数; ...

m0_68990465的博客 1万+

C语言实现动态数组

在C语言中,数组是一种固定大小的数据结构,其长度在声明时就确定了,无法在运行时改变。然而,有时候我们需要处理的数据规模是不确定的,这就需要使用动态数组。通过使用指针和内存管理函数,我们可以在C语言中实现动态数组。在C语言中,可以使用指针和内存管理函数来实现动态数组。最后,我们通过循环打印出动态数组的所有元素,并调用。函数用于初始化动态数组,它接受一个容量参数并分配相应大小的内存空间。函数用于向动态数组添加元素,如果数组已满,则会自动扩展数组的容量。函数用于删除指定索引位置的元素,并在必要时缩小数组的容量。

2301_79325657的博客 401

C语言如何实现动态数组?

提出问题请问在c语言里如何实现动态大小的数组啊,比如说int a[N];,这里N的值可以在程序中定,或者有什么方法可以实现类似的功能?总之只要在编译时不用制定数组大小就行。分析问题嵌入式系...

4815

c++ 知识点 : 动态定义数组

首先:为什么需要动态定义数组呢? 这是因为,很多情况下,在预编译过程阶段,数组的长度是不能预先知道的,必须在程序运行时动态的给出 但是问题是,c++要求定义数组时,必须明确给定数组的大小,要不然编译通不过 如: int Array[5];正确 int i=5; int Array[i]; 错误 因为在编译阶段,编译器并不知道 i

目前打算换一个工作,有招聘windows c++方向的也欢迎联系,北京、济南 最好 2万+

C语言中动态数组的设计与实现

一个典型的动态数组结构体应该包含以下几个基本元素:存储空间指针:指向动态分配的数组内存。当前大小:表示数组当前存储了多少元素。容量:表示当前内存可以容纳的元素数量。这里是一个简单的Vector结构体的示例:int* data;// 指向动态分配数组的指针// 当前存储的元素数量// 数组的容量// 构造函数、析构函数、以及其他成员函数的声明。

weixin_42311427的博客 990

数据结构之动态数组的代码实现(新手小白也能懂/C语言版)

基本数据结构动态数组的代码实现,小白也能轻松拿捏。

morandi666的博客 2225

详解一典型的反激式开关电源方案

如图,在某系统方案上看到下图所示的单端反激式开关电源方案。

alala120的博客 1万+

C语言中动态数组的实现

C 语言中动态数组的实现 c语言中数组直接申请,int a[10],是存放在栈上。栈是被系统严格管理胡,故数组的大小一经申请便无法再被修改。 因此,动态数组需要在堆中才能实现,使用malloc,calloc等函数在系统中开辟所需的内存空间,接收返回的地址作为数组的首地址(头指针)。在用循环即可进行动态数组的初始化。 注:动态数组需要使用后,需要释放内存空间。 // 函数申请一个动态数组保...

qq_26308587的博客 3633

【ESP32实战】SPI驱动ILI9341屏幕:从基础绘图到汉字显示

本文详细介绍了如何使用ESP32通过SPI驱动ILI9341屏幕,从基础连接、SPI初始化到实现基础绘图、数字显示及汉字显示的全过程。文章包含实用的代码示例和优化技巧,帮助开发者快速掌握屏幕驱动技术,提升显示性能。特别针对常见问题如花屏、刷新率等提供了解决方案。

weixin_29164091的博客 621

[原创]Keil工程STM32F103C8T6无缝转换到STM32F103RCT6

有个项目,老版本是STM32F103C8T6,硬件资源不够了,新版本采用STM32F103RCT6。 无缝过渡,如下: 选定芯片 宏定义改为STM32F10X_HD,USE_STDPERIPH_DRIVER 删除原有的启动汇编文件,更换为高密度器件汇编文件 时钟系统紊乱? 那得看你程序怎么写: 先看F103时钟树 int main(void) { unsigned char stat...

江东风又起 2万+

C/C++语言实现动态数组

C/C++语言实现动态数组C数组的小问题     这里说的动态数组是可以根据需要动态增长占用内存的数组,比如程序初始分配了100个元素,可是运行了一段时间后区区100个空间不能满足了,现在需要400个,怎么办呢;那肯定需要再额外分配300个。     C语言有realloc()函数来解决空间扩充的问题,但是不要忘了realloc可能会迁移内存,很多时候数组中的元素会被其它函数/模块

sparkliang的专栏 1万+

六轴机械臂正逆解计算

机械臂运动学就是。包括(Forward Kinematics)和(InverseKinematics)两部分。正运动学就是逆运动学则是关节变量->机械臂末端执行器的姿势=正向运动学机械臂未端执行器的位姿->关节变量=逆向运动学。

gaoxiaochan的博客 1万+

C 语言实现动态数组(malloc() 动态存储)

掌握动态内存管理是 C 语言编程中的核心技能!的基本用法,并实现了一维动态数组。(如姓名、成绩),并且数量在运行时确定,就必须使用。在前面的内容中,我们学习了 malloc(),必须在编译时确定。在 C 语言中,静态二维数组的大小。在 C 语言中,数组的大小通常是。,可以使用 realloc(),以适应不同的数据量需求。动态分配的内存,会导致。,相比静态数组更灵活。

小宝哥Code的专栏 2806

MATLAB控制信号发生器(USB-GPIB-HS)GPIB仪器控制教程(含matlab代码)

自动化测试时需要自动产生信号,通过matlab控制信号发生器的频率与功率,以实现自动化信号生成输出

qq_43686057的博客 1606

ESP32 Arduino学习篇 (一) 引脚和串口的基本使用

简单来讲arduino就是通过源代码控制开发板的信号输入输出从而实现对一些电子元件的控制,例如LED灯,蜂鸣器,按键arduino程序首先来讲arduino程序是基于C语言,而实现类似对于LED灯和蜂鸣器的简单控制只需简单C语言知识即可实现。arduino程序是基于函数的,而在arduino的库有很多函数,我们只需要调用即可。arduino的程序主体是**setup()函数和loop()**函数以及其它在使用过程中需要构建的函数:setup()函数。

DOF526570的博客 1万+

C语言修改数组元素(指针)并实现动态数组

东北大学在线编程社区problem1672 题目描述: 输入元素个数及数组中的各元素,利用指针将其中所有负数都变为0,输出数组。 //含有错误的代码 #include <stdio.h> int main(void) { int n,i,*p; scanf("%d",n); int a[n]; p=a; for(i=0;i<n;i++){ scanf("%d", *p); if(*p<0) *p=0; printf(

Patrick140816的博客 6162

NVMe-MI --- Message Servicing Model(消息服务模型)

本文主要介绍NVMe-MI消息服务模型,两个主要类别是请求消息和响应消息。并介绍带外机制消息服务状态机。

智小星的博客 2014

C语言建立动态数组

C语言建立动态数组        数组的有点在于随机存取,然而其不足也是明显的,就是一旦建立其大小就不能改变。若用数组存储数据,则必须创建一个可能存放的最大空间的数组,这无疑浪费了空间。动态数组解决了这个问题。动态数组的思路是:先建立一定大小的数组,向这个 数组中存放数据,如果数组已满,则重新申请一个更大的空间来存放。每次重新申请时可以指定增量(inc)的大小,也可以固定大小。这样做的好处是空

喂兔子的菜 1万+

老款 NUC 复活计划:装 Ubuntu 部署 OpenClaw 本地 AI

老款 NUC 变身本地 AI 服务器指南 本文详细介绍了如何将老旧华硕 NUC 设备改造为本地 AI 服务器。主要内容包括: 硬件评估:列出老款 NUC 的最低配置要求(i3 6代/8GB内存/256GB SSD),并提供兼容性检查命令和性能预期表 系统准备:指导备份数据、下载 Ubuntu 22.04 LTS 和制作启动盘的方法(Windows/Linux双平台) 安装流程:从 BIOS 设置到 Ubuntu 安装的完整步骤,包括推荐的分区方案 系统优化:禁用不必要的服务、内核参数调优、Swap 配置和

博客 7607

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C语言动态数组实现

环境:VS2015 头文件 DynamicArray.h #ifndef DYNAMICARRAY_H //如果没有定义 #define DYNAMICARRAY_H //则定义 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct DYNAMICARRAY { int* pAdder; //动态数组地址 int capacity; //动态...

StudyWinter的博客 1106

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

上一篇: C语言期末大作业:学生考试成绩统计分析管理系统
啸行
博客等级 码龄3年 24粉丝 3原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值