跳到主要内容

C 语言动态数组

在C语言中,数组是一种非常常用的数据结构,用于存储相同类型的多个元素。然而,静态数组的大小在编译时就已经确定,无法在运行时改变。为了解决这个问题,C语言提供了动态数组的概念,允许我们在程序运行时动态地分配和释放内存。

什么是动态数组?

动态数组是指在程序运行时通过动态内存分配函数(如 malloccallocreallocfree)来创建和管理的数组。与静态数组不同,动态数组的大小可以在运行时根据需要调整,这使得它更加灵活。

动态数组的创建与使用

1. 使用 malloc 创建动态数组

malloc 函数用于在堆内存中分配指定大小的内存块。它的原型如下:

c
void* malloc(size_t size);

size 参数表示要分配的内存大小(以字节为单位)。malloc 返回一个指向分配内存的指针,如果分配失败,则返回 NULL

以下是一个使用 malloc 创建动态数组的示例:

c
#include <stdio.h>
#include <stdlib.h>

int main() {
int n;
printf("请输入数组的大小: ");
scanf("%d", &n);

// 动态分配内存
int* arr = (int*)malloc(n * sizeof(int));
if (arr == NULL) {
printf("内存分配失败\n");
return 1;
}

// 初始化数组
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}

// 打印数组
printf("数组元素: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

// 释放内存
free(arr);

return 0;
}

输入输出示例:

请输入数组的大小: 5
数组元素: 1 2 3 4 5
备注

在使用 malloc 分配内存后,务必检查返回的指针是否为 NULL,以确保内存分配成功。

2. 使用 calloc 创建动态数组

calloc 函数与 malloc 类似,但它会将分配的内存初始化为零。它的原型如下:

c
void* calloc(size_t num, size_t size);

num 参数表示要分配的元素数量,size 参数表示每个元素的大小(以字节为单位)。

以下是一个使用 calloc 创建动态数组的示例:

c
#include <stdio.h>
#include <stdlib.h>

int main() {
int n;
printf("请输入数组的大小: ");
scanf("%d", &n);

// 动态分配内存并初始化为零
int* arr = (int*)calloc(n, sizeof(int));
if (arr == NULL) {
printf("内存分配失败\n");
return 1;
}

// 打印数组
printf("数组元素: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

// 释放内存
free(arr);

return 0;
}

输入输出示例:

请输入数组的大小: 5
数组元素: 0 0 0 0 0
提示

calloc 适用于需要将数组初始化为零的场景。

3. 使用 realloc 调整动态数组大小

realloc 函数用于调整已分配内存块的大小。它的原型如下:

c
void* realloc(void* ptr, size_t size);

ptr 参数是指向先前分配的内存块的指针,size 参数表示新的内存大小(以字节为单位)。realloc 返回一个指向新内存块的指针,如果调整失败,则返回 NULL

以下是一个使用 realloc 调整动态数组大小的示例:

c
#include <stdio.h>
#include <stdlib.h>

int main() {
int n;
printf("请输入初始数组的大小: ");
scanf("%d", &n);

// 动态分配内存
int* arr = (int*)malloc(n * sizeof(int));
if (arr == NULL) {
printf("内存分配失败\n");
return 1;
}

// 初始化数组
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}

// 打印初始数组
printf("初始数组元素: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

// 调整数组大小
int new_n;
printf("请输入新的数组大小: ");
scanf("%d", &new_n);

arr = (int*)realloc(arr, new_n * sizeof(int));
if (arr == NULL) {
printf("内存调整失败\n");
return 1;
}

// 初始化新增的元素
for (int i = n; i < new_n; i++) {
arr[i] = i + 1;
}

// 打印调整后的数组
printf("调整后的数组元素: ");
for (int i = 0; i < new_n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

// 释放内存
free(arr);

return 0;
}

输入输出示例:

请输入初始数组的大小: 3
初始数组元素: 1 2 3
请输入新的数组大小: 5
调整后的数组元素: 1 2 3 4 5
警告

使用 realloc 时,如果调整失败,原始内存块仍然有效,因此需要小心处理返回的指针。

4. 使用 free 释放动态数组

在使用完动态数组后,务必使用 free 函数释放已分配的内存,以避免内存泄漏。free 函数的原型如下:

c
void free(void* ptr);

ptr 参数是指向先前分配的内存块的指针。

注意

释放内存后,不要再访问已释放的内存块,否则会导致未定义行为。

动态数组的实际应用场景

动态数组在许多实际应用中非常有用,例如:

  1. 处理未知大小的数据:当程序需要处理的数据量在编译时未知时,动态数组可以根据实际数据量动态调整大小。
  2. 实现动态数据结构:动态数组是许多动态数据结构(如链表、栈、队列等)的基础。
  3. 优化内存使用:通过动态调整数组大小,可以避免静态数组可能导致的过多内存浪费。

总结

动态数组是C语言中一种非常灵活的数据结构,允许在运行时动态分配和调整内存。通过使用 malloccallocreallocfree 函数,我们可以轻松地创建和管理动态数组。掌握动态数组的使用对于编写高效、灵活的C语言程序至关重要。

附加资源与练习

  • 练习1:编写一个程序,要求用户输入一个整数数组的大小,然后动态分配内存并存储用户输入的数组元素,最后打印数组。
  • 练习2:修改上述程序,使其能够动态调整数组大小,并在调整后打印新的数组内容。
  • 附加资源:阅读C语言标准库中关于动态内存分配函数的文档,了解更多细节和高级用法。

通过不断练习和探索,你将能够熟练掌握C语言中的动态数组及其应用。