C语言中处理二维数组
C语言中处理二维数组

前言

在C语言中,二维数组是一种常见的数据结构,用于存储和管理多维数据。 本篇博客将介绍如何在C语言中如何实现对结构体中的二维数组的处理,并提供具体的代码示例,作为c语言开发时的参考。

结构体中元素为普通数据的二维数组处理

示例代码

 1#include <stdio.h>
 2#include <stdlib.h>
 3
 4#define ROWS 5   // 二维数组的行数
 5#define COLS 5   // 二维数组的列数
 6
 7// 定义一个结构体,包含一个二维数组
 8typedef struct {
 9    int matrix[ROWS][COLS];  // 二维数组
10} Matrix;
11
12// 初始化二维数组
13void initializeMatrix(Matrix* m) {
14    for (int i = 0; i < ROWS; i++) {
15        for (int j = 0; j < COLS; j++) {
16            m->matrix[i][j] = 0;  // 初始化所有元素为0
17        }
18    }
19}
20
21// 打印二维数组
22void printMatrix(const Matrix* m) {
23    for (int i = 0; i < ROWS; i++) {
24        for (int j = 0; j < COLS; j++) {
25            printf("%d ", m->matrix[i][j]);
26        }
27        printf("\n");
28    }
29}
30
31// 插入一个值到二维数组的指定位置
32void insertElement(Matrix* m, int row, int col, int value) {
33    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
34        m->matrix[row][col] = value;
35    } else {
36        printf("插入失败:索引超出范围。\n");
37    }
38}
39
40// 删除指定位置的元素(将其设置为0)
41void deleteElement(Matrix* m, int row, int col) {
42    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
43        m->matrix[row][col] = 0;
44    } else {
45        printf("删除失败:索引超出范围。\n");
46    }
47}
48
49// 修改指定位置的元素
50void updateElement(Matrix* m, int row, int col, int newValue) {
51    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
52        m->matrix[row][col] = newValue;
53    } else {
54        printf("修改失败:索引超出范围。\n");
55    }
56}
57
58// 查询指定位置的元素
59int getElement(const Matrix* m, int row, int col) {
60    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
61        return m->matrix[row][col];
62    } else {
63        printf("查询失败:索引超出范围。\n");
64        return -1; // 返回一个错误值
65    }
66}
67
68int main() {
69    Matrix m;
70    initializeMatrix(&m);  // 初始化矩阵
71
72    printf("初始化后的矩阵:\n");
73    printMatrix(&m);
74
75    insertElement(&m, 2, 2, 10);  // 在 (2,2) 位置插入值 10
76    printf("\n插入元素后的矩阵:\n");
77    printMatrix(&m);
78
79    updateElement(&m, 2, 2, 20);  // 修改 (2,2) 位置的元素为 20
80    printf("\n修改元素后的矩阵:\n");
81    printMatrix(&m);
82
83    deleteElement(&m, 2, 2);  // 删除 (2,2) 位置的元素
84    printf("\n删除元素后的矩阵:\n");
85    printMatrix(&m);
86
87    int value = getElement(&m, 2, 2);  // 查询 (2,2) 位置的元素
88    printf("\n查询 (2,2) 位置的元素值:%d\n", value);
89
90    return 0;
91}

说明

  1. 结构体定义Matrix结构体包含一个matrix二维数组。
  2. 初始化函数initializeMatrix函数将二维数组中的所有元素初始化为0。
  3. 打印函数printMatrix函数用于打印二维数组的内容。
  4. 增删改查函数:分别为insertElementdeleteElementupdateElementgetElement函数,分别用于插入、删除、更新和查询二维数组中的元素。

结构体中元素为结构体的二维数组处理

示例代码

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4
  5#define ROWS 3   // 二维数组的行数
  6#define COLS 3   // 二维数组的列数
  7
  8// 定义一个结构体,表示二维数组中的元素
  9typedef struct {
 10    int id;
 11    char name[50];
 12    float score;
 13} Element;
 14
 15// 定义一个结构体,包含一个元素类型的二维数组
 16typedef struct {
 17    Element matrix[ROWS][COLS];  // 二维数组,元素为Element结构体
 18} Matrix;
 19
 20// 初始化二维数组
 21void initializeMatrix(Matrix* m) {
 22    for (int i = 0; i < ROWS; i++) {
 23        for (int j = 0; j < COLS; j++) {
 24            m->matrix[i][j].id = 0;  // 初始化id为0
 25            strcpy(m->matrix[i][j].name, "");  // 初始化name为空字符串
 26            m->matrix[i][j].score = 0.0f;  // 初始化score为0.0
 27        }
 28    }
 29}
 30
 31// 打印二维数组
 32void printMatrix(const Matrix* m) {
 33    for (int i = 0; i < ROWS; i++) {
 34        for (int j = 0; j < COLS; j++) {
 35            printf("(%d, %s, %.2f) ", m->matrix[i][j].id, m->matrix[i][j].name, m->matrix[i][j].score);
 36        }
 37        printf("\n");
 38    }
 39}
 40
 41// 插入一个结构体到二维数组的指定位置
 42void insertElement(Matrix* m, int row, int col, int id, const char* name, float score) {
 43    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
 44        m->matrix[row][col].id = id;
 45        strcpy(m->matrix[row][col].name, name);
 46        m->matrix[row][col].score = score;
 47    } else {
 48        printf("插入失败:索引超出范围。\n");
 49    }
 50}
 51
 52// 删除指定位置的结构体元素(将其重置为默认值)
 53void deleteElement(Matrix* m, int row, int col) {
 54    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
 55        m->matrix[row][col].id = 0;
 56        strcpy(m->matrix[row][col].name, "");
 57        m->matrix[row][col].score = 0.0f;
 58    } else {
 59        printf("删除失败:索引超出范围。\n");
 60    }
 61}
 62
 63// 修改指定位置的结构体元素
 64void updateElement(Matrix* m, int row, int col, int newId, const char* newName, float newScore) {
 65    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
 66        m->matrix[row][col].id = newId;
 67        strcpy(m->matrix[row][col].name, newName);
 68        m->matrix[row][col].score = newScore;
 69    } else {
 70        printf("修改失败:索引超出范围。\n");
 71    }
 72}
 73
 74// 查询指定位置的结构体元素
 75Element getElement(const Matrix* m, int row, int col) {
 76    Element emptyElement = {0, "", 0.0f};  // 用于返回空元素
 77    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
 78        return m->matrix[row][col];
 79    } else {
 80        printf("查询失败:索引超出范围。\n");
 81        return emptyElement;
 82    }
 83}
 84
 85int main() {
 86    Matrix m;
 87    initializeMatrix(&m);  // 初始化矩阵
 88
 89    printf("初始化后的矩阵:\n");
 90    printMatrix(&m);
 91
 92    // 插入元素
 93    insertElement(&m, 1, 1, 1, "Alice", 88.5f);  
 94    printf("\n插入元素后的矩阵:\n");
 95    printMatrix(&m);
 96
 97    // 修改元素
 98    updateElement(&m, 1, 1, 2, "Bob", 92.0f);  
 99    printf("\n修改元素后的矩阵:\n");
100    printMatrix(&m);
101
102    // 删除元素
103    deleteElement(&m, 1, 1);  
104    printf("\n删除元素后的矩阵:\n");
105    printMatrix(&m);
106
107    // 查询元素
108    Element e = getElement(&m, 1, 1);
109    printf("\n查询 (1, 1) 位置的元素:id=%d, name=%s, score=%.2f\n", e.id, e.name, e.score);
110
111    return 0;
112}

说明

  1. 结构体定义

    • Element 结构体包含3个成员:id(整型)、name(字符串)和score(浮点型)。
    • Matrix 结构体包含一个 Element 类型的二维数组 matrix
  2. 初始化函数initializeMatrix 函数将二维数组中的所有元素初始化为默认值(id 为0,name为空字符串,score为0.0)。

  3. 打印函数printMatrix 函数用于打印整个二维数组的内容。

  4. 增删改查函数

    • insertElement 函数用于插入一个新的 Element 到指定位置。
    • deleteElement 函数用于删除指定位置的元素(将其重置为默认值)。
    • updateElement 函数用于修改指定位置的元素。
    • getElement 函数用于查询并返回指定位置的 Element

结构体中元素为结构体且结构体中包含指针元素的二维数组处理

示例代码

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4
  5#define ROWS 3  // 二维数组的行数
  6#define COLS 3  // 二维数组的列数
  7
  8// 定义一个结构体,表示二维数组中的元素
  9typedef struct {
 10    int id;
 11    char* name;  // 动态分配的字符串指针
 12    float score;
 13} Element;
 14
 15// 定义一个结构体,包含一个元素类型的二维数组
 16typedef struct {
 17    Element matrix[ROWS][COLS];  // 二维数组,元素为Element结构体
 18} Matrix;
 19
 20// 初始化二维数组
 21void initializeMatrix(Matrix* m) {
 22    for (int i = 0; i < ROWS; i++) {
 23        for (int j = 0; j < COLS; j++) {
 24            m->matrix[i][j].id = 0;  // 初始化id为0
 25            m->matrix[i][j].name = NULL;  // 初始化指针为空
 26            m->matrix[i][j].score = 0.0f;  // 初始化score为0.0
 27        }
 28    }
 29}
 30
 31// 打印二维数组
 32void printMatrix(const Matrix* m) {
 33    for (int i = 0; i < ROWS; i++) {
 34        for (int j = 0; j < COLS; j++) {
 35            printf("(%d, %s, %.2f) ", m->matrix[i][j].id,
 36                m->matrix[i][j].name ? m->matrix[i][j].name : "NULL",
 37                m->matrix[i][j].score);
 38        }
 39        printf("\n");
 40    }
 41}
 42
 43// 插入一个结构体到二维数组的指定位置
 44void insertElement(Matrix* m, int row, int col, int id, const char* name, float score) {
 45    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
 46        // 释放之前的内存(如果有)
 47        if (m->matrix[row][col].name) {
 48            free(m->matrix[row][col].name);
 49        }
 50        m->matrix[row][col].id = id;
 51        m->matrix[row][col].name = malloc(strlen(name) + 1);  // 分配内存
 52        if (m->matrix[row][col].name) {
 53            strcpy(m->matrix[row][col].name, name);  // 复制字符串
 54        }
 55        m->matrix[row][col].score = score;
 56    } else {
 57        printf("插入失败:索引超出范围。\n");
 58    }
 59}
 60
 61// 删除指定位置的结构体元素(释放内存并重置为默认值)
 62void deleteElement(Matrix* m, int row, int col) {
 63    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
 64        m->matrix[row][col].id = 0;
 65        if (m->matrix[row][col].name) {
 66            free(m->matrix[row][col].name);  // 释放动态分配的内存
 67            m->matrix[row][col].name = NULL;
 68        }
 69        m->matrix[row][col].score = 0.0f;
 70    } else {
 71        printf("删除失败:索引超出范围。\n");
 72    }
 73}
 74
 75// 修改指定位置的结构体元素
 76void updateElement(Matrix* m, int row, int col, int newId, const char* newName, float newScore) {
 77    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
 78        // 释放之前的内存(如果有)
 79        if (m->matrix[row][col].name) {
 80            free(m->matrix[row][col].name);
 81        }
 82        m->matrix[row][col].id = newId;
 83        m->matrix[row][col].name = malloc(strlen(newName) + 1);  // 分配内存
 84        if (m->matrix[row][col].name) {
 85            strcpy(m->matrix[row][col].name, newName);  // 复制新字符串
 86        }
 87        m->matrix[row][col].score = newScore;
 88    } else {
 89        printf("修改失败:索引超出范围。\n");
 90    }
 91}
 92
 93// 查询指定位置的结构体元素
 94Element getElement(const Matrix* m, int row, int col) {
 95    Element emptyElement = {0, NULL, 0.0f};  // 用于返回空元素
 96    if (row >= 0 && row < ROWS && col >= 0 && col < COLS) {
 97        return m->matrix[row][col];
 98    } else {
 99        printf("查询失败:索引超出范围。\n");
100        return emptyElement;
101    }
102}
103
104// 释放矩阵中所有动态分配的内存
105void freeMatrix(Matrix* m) {
106    for (int i = 0; i < ROWS; i++) {
107        for (int j = 0; j < COLS; j++) {
108            if (m->matrix[i][j].name) {
109                free(m->matrix[i][j].name);
110                m->matrix[i][j].name = NULL;
111            }
112        }
113    }
114}
115
116int main() {
117    Matrix m;
118    initializeMatrix(&m);  // 初始化矩阵
119
120    printf("初始化后的矩阵:\n");
121    printMatrix(&m);
122
123    // 插入元素
124    insertElement(&m, 1, 1, 1, "Alice", 88.5f);  
125    printf("\n插入元素后的矩阵:\n");
126    printMatrix(&m);
127
128    // 修改元素
129    updateElement(&m, 1, 1, 2, "Bob", 92.0f);  
130    printf("\n修改元素后的矩阵:\n");
131    printMatrix(&m);
132
133    // 删除元素
134    deleteElement(&m, 1, 1);  
135    printf("\n删除元素后的矩阵:\n");
136    printMatrix(&m);
137
138    // 查询元素
139    Element e = getElement(&m, 1, 1);
140    printf("\n查询 (1, 1) 位置的元素:id=%d, name=%s, score=%.2f\n", e.id, e.name ? e.name : "NULL", e.score);
141
142    // 释放矩阵中的所有动态分配的内存
143    freeMatrix(&m);
144
145    return 0;
146}

说明

  1. 结构体定义

    • Element 结构体包含三个成员:id(整型)、name(指向字符数组的指针)和score(浮点型)。
    • Matrix 结构体包含一个 Element 类型的二维数组 matrix
  2. 内存管理

    • 每次插入或修改 name 字段时,动态分配内存(使用 malloc),并将字符串复制到分配的内存中。
    • 在插入、修改或删除元素前,先检查是否已有动态分配的内存,如果有则使用 free 释放。
    • 提供了 freeMatrix 函数,用于在程序结束时释放所有动态分配的内存,防止内存泄漏。
  3. 增删改查操作

    • insertElementupdateElementdeleteElementgetElement 函数分别实现增、删、改、查操作,同时正确地处理内存分配和释放。

动态生成包含指针的结构体的二维数组

示例代码

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4
  5// 定义一个结构体,表示二维数组中的元素
  6typedef struct {
  7    int id;
  8    char* name;  // 动态分配的字符串指针
  9    float score;
 10} Element;
 11
 12// 定义一个结构体,用来管理动态生成的二维数组
 13typedef struct {
 14    int rows;
 15    int cols;
 16    Element** matrix;  // 指向指针的指针,表示动态分配的二维数组
 17} Matrix;
 18
 19// 初始化动态二维数组
 20Matrix* createMatrix(int rows, int cols) {
 21    Matrix* m = (Matrix*)malloc(sizeof(Matrix));  // 为Matrix结构体分配内存
 22    if (m == NULL) {
 23        printf("内存分配失败。\n");
 24        return NULL;
 25    }
 26
 27    m->rows = rows;
 28    m->cols = cols;
 29    m->matrix = (Element**)malloc(rows * sizeof(Element*));  // 分配行指针数组
 30    if (m->matrix == NULL) {
 31        printf("内存分配失败。\n");
 32        free(m);
 33        return NULL;
 34    }
 35
 36    for (int i = 0; i < rows; i++) {
 37        m->matrix[i] = (Element*)malloc(cols * sizeof(Element));  // 为每行分配内存
 38        if (m->matrix[i] == NULL) {
 39            printf("内存分配失败。\n");
 40            // 释放已分配的内存
 41            for (int j = 0; j < i; j++) {
 42                free(m->matrix[j]);
 43            }
 44            free(m->matrix);
 45            free(m);
 46            return NULL;
 47        }
 48
 49        // 初始化每个元素
 50        for (int j = 0; j < cols; j++) {
 51            m->matrix[i][j].id = 0;
 52            m->matrix[i][j].name = NULL;  // 初始化指针为空
 53            m->matrix[i][j].score = 0.0f;
 54        }
 55    }
 56
 57    return m;
 58}
 59
 60// 打印二维数组
 61void printMatrix(const Matrix* m) {
 62    for (int i = 0; i < m->rows; i++) {
 63        for (int j = 0; j < m->cols; j++) {
 64            printf("(%d, %s, %.2f) ", m->matrix[i][j].id,
 65                   m->matrix[i][j].name ? m->matrix[i][j].name : "NULL",
 66                   m->matrix[i][j].score);
 67        }
 68        printf("\n");
 69    }
 70}
 71
 72// 插入一个结构体到二维数组的指定位置
 73void insertElement(Matrix* m, int row, int col, int id, const char* name, float score) {
 74    if (row >= 0 && row < m->rows && col >= 0 && col < m->cols) {
 75        // 释放之前的内存(如果有)
 76        if (m->matrix[row][col].name) {
 77            free(m->matrix[row][col].name);
 78        }
 79        m->matrix[row][col].id = id;
 80        m->matrix[row][col].name = malloc(strlen(name) + 1);  // 分配内存
 81        if (m->matrix[row][col].name) {
 82            strcpy(m->matrix[row][col].name, name);  // 复制字符串
 83        }
 84        m->matrix[row][col].score = score;
 85    } else {
 86        printf("插入失败:索引超出范围。\n");
 87    }
 88}
 89
 90// 删除指定位置的结构体元素(释放内存并重置为默认值)
 91void deleteElement(Matrix* m, int row, int col) {
 92    if (row >= 0 && row < m->rows && col >= 0 && col < m->cols) {
 93        m->matrix[row][col].id = 0;
 94        if (m->matrix[row][col].name) {
 95            free(m->matrix[row][col].name);  // 释放动态分配的内存
 96            m->matrix[row][col].name = NULL;
 97        }
 98        m->matrix[row][col].score = 0.0f;
 99    } else {
100        printf("删除失败:索引超出范围。\n");
101    }
102}
103
104// 修改指定位置的结构体元素
105void updateElement(Matrix* m, int row, int col, int newId, const char* newName, float newScore) {
106    if (row >= 0 && row < m->rows && col >= 0 && col < m->cols) {
107        // 释放之前的内存(如果有)
108        if (m->matrix[row][col].name) {
109            free(m->matrix[row][col].name);
110        }
111        m->matrix[row][col].id = newId;
112        m->matrix[row][col].name = malloc(strlen(newName) + 1);  // 分配内存
113        if (m->matrix[row][col].name) {
114            strcpy(m->matrix[row][col].name, newName);  // 复制新字符串
115        }
116        m->matrix[row][col].score = newScore;
117    } else {
118        printf("修改失败:索引超出范围。\n");
119    }
120}
121
122// 查询指定位置的结构体元素
123Element getElement(const Matrix* m, int row, int col) {
124    Element emptyElement = {0, NULL, 0.0f};  // 用于返回空元素
125    if (row >= 0 && row < m->rows && col >= 0 && col < m->cols) {
126        return m->matrix[row][col];
127    } else {
128        printf("查询失败:索引超出范围。\n");
129        return emptyElement;
130    }
131}
132
133// 释放矩阵中所有动态分配的内存
134void freeMatrix(Matrix* m) {
135    if (!m) return;
136    
137    for (int i = 0; i < m->rows; i++) {
138        for (int j = 0; j < m->cols; j++) {
139            if (m->matrix[i][j].name) {
140                free(m->matrix[i][j].name);
141            }
142        }
143        free(m->matrix[i]);  // 释放每一行的内存
144    }
145    free(m->matrix);  // 释放行指针数组
146    free(m);  // 释放Matrix结构体本身
147}
148
149int main() {
150    int rows = 3, cols = 3;
151    Matrix* m = createMatrix(rows, cols);  // 动态创建矩阵
152
153    if (m == NULL) {
154        printf("矩阵创建失败。\n");
155        return 1;
156    }
157
158    printf("初始化后的矩阵:\n");
159    printMatrix(m);
160
161    // 插入元素
162    insertElement(m, 1, 1, 1, "Alice", 88.5f);
163    printf("\n插入元素后的矩阵:\n");
164    printMatrix(m);
165
166    // 修改元素
167    updateElement(m, 1, 1, 2, "Bob", 92.0f);
168    printf("\n修改元素后的矩阵:\n");
169    printMatrix(m);
170
171    // 删除元素
172    deleteElement(m, 1, 1);
173    printf("\n删除元素后的矩阵:\n");
174    printMatrix(m);
175
176    // 查询元素
177    Element e = getElement(m, 1, 1);
178    printf("\n查询 (1, 1) 位置的元素:id=%d, name=%s, score=%.2f\n", e.id, e.name ? e.name : "NULL", e.score);
179
180    // 释放矩阵中的所有动态分配的内存
181    freeMatrix(m);
182
183    return 0;
184}

说明

  1. 结构体定义

    • Element 结构体包含三个成员:id(整型)、name(指向动态分配的字符数组的指针)、score(浮点型)。
    • Matrix 结构体包含一个动态二维数组的指针 matrix、行数和列数。
  2. 内存管理

    • createMatrix 函数动态分配内存来创建一个 Matrix 结构体和二维数组。首先分配 Matrix 结构体,然后为每一行指针数组和每个元素分配内存。
    • 在插入或修改元素时,动态分配内存给 name 指针,并使用 free 释放之前的内存。
    • freeMatrix 函数用于在程序结束时释放所有动态分配的内存,防止内存泄漏。
  3. 增删改查操作

    • insertElementupdateElementdeleteElementgetElement 函数分别实现增、删、改、查操作,并正确地处理内存分配和释放。

二维数组行列数需要随数据规模变化而变化

实话说,要实现这个功能,对于纯c语言真的麻烦。

示例代码

  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4
  5// 定义一个结构体,表示二维数组中的元素
  6typedef struct {
  7    int id;
  8    char* name;  // 动态分配的字符串指针
  9    float score;
 10} Element;
 11
 12// 定义一个结构体,用来管理动态生成的二维数组
 13typedef struct {
 14    int rows;       // 当前行数
 15    int cols;       // 当前列数
 16    int capacity;   // 当前容量(列的最大值)
 17    Element** matrix;  // 指向指针的指针,表示动态分配的二维数组
 18} DynamicMatrix;
 19
 20// 初始化动态二维数组
 21DynamicMatrix* createMatrix(int initialRows, int initialCols) {
 22    DynamicMatrix* m = (DynamicMatrix*)malloc(sizeof(DynamicMatrix));  // 为DynamicMatrix结构体分配内存
 23    if (m == NULL) {
 24        printf("内存分配失败。\n");
 25        return NULL;
 26    }
 27
 28    m->rows = initialRows;
 29    m->cols = initialCols;
 30    m->capacity = initialCols;
 31    m->matrix = (Element**)malloc(initialRows * sizeof(Element*));  // 分配行指针数组
 32    if (m->matrix == NULL) {
 33        printf("内存分配失败。\n");
 34        free(m);
 35        return NULL;
 36    }
 37
 38    for (int i = 0; i < initialRows; i++) {
 39        m->matrix[i] = (Element*)malloc(initialCols * sizeof(Element));  // 为每行分配内存
 40        if (m->matrix[i] == NULL) {
 41            printf("内存分配失败。\n");
 42            // 释放已分配的内存
 43            for (int j = 0; j < i; j++) {
 44                free(m->matrix[j]);
 45            }
 46            free(m->matrix);
 47            free(m);
 48            return NULL;
 49        }
 50
 51        // 初始化每个元素
 52        for (int j = 0; j < initialCols; j++) {
 53            m->matrix[i][j].id = 0;
 54            m->matrix[i][j].name = NULL;  // 初始化指针为空
 55            m->matrix[i][j].score = 0.0f;
 56        }
 57    }
 58
 59    return m;
 60}
 61
 62// 扩展矩阵容量(增加列数)
 63void expandMatrix(DynamicMatrix* m) {
 64    int newCapacity = m->capacity * 2;  // 增加容量(例如,增加一倍)
 65
 66    for (int i = 0; i < m->rows; i++) {
 67        Element* newRow = (Element*)realloc(m->matrix[i], newCapacity * sizeof(Element));
 68        if (newRow == NULL) {
 69            printf("内存重新分配失败。\n");
 70            return;
 71        }
 72        // 初始化新增加的元素
 73        for (int j = m->capacity; j < newCapacity; j++) {
 74            newRow[j].id = 0;
 75            newRow[j].name = NULL;
 76            newRow[j].score = 0.0f;
 77        }
 78        m->matrix[i] = newRow;
 79    }
 80    m->capacity = newCapacity;
 81}
 82
 83// 添加新元素到二维数组中(按行扩展)
 84void addElement(DynamicMatrix* m, int row, int id, const char* name, float score) {
 85    if (row >= m->rows) {
 86        // 增加行数
 87        int newRows = row + 1;
 88        Element** newMatrix = (Element**)realloc(m->matrix, newRows * sizeof(Element*));
 89        if (newMatrix == NULL) {
 90            printf("内存重新分配失败。\n");
 91            return;
 92        }
 93
 94        m->matrix = newMatrix;
 95
 96        // 为新增的行分配内存
 97        for (int i = m->rows; i < newRows; i++) {
 98            m->matrix[i] = (Element*)malloc(m->capacity * sizeof(Element));
 99            if (m->matrix[i] == NULL) {
100                printf("内存分配失败。\n");
101                return;
102            }
103
104            // 初始化新行的每个元素
105            for (int j = 0; j < m->capacity; j++) {
106                m->matrix[i][j].id = 0;
107                m->matrix[i][j].name = NULL;
108                m->matrix[i][j].score = 0.0f;
109            }
110        }
111
112        m->rows = newRows;
113    }
114
115    // 当列超过当前容量时扩展容量
116    if (m->cols >= m->capacity) {
117        expandMatrix(m);
118    }
119
120    // 插入元素
121    m->matrix[row][m->cols].id = id;
122    m->matrix[row][m->cols].name = malloc(strlen(name) + 1);  // 分配内存
123    if (m->matrix[row][m->cols].name) {
124        strcpy(m->matrix[row][m->cols].name, name);  // 复制字符串
125    }
126    m->matrix[row][m->cols].score = score;
127    m->cols++;  // 增加列数
128}
129
130// 打印二维数组
131void printMatrix(const DynamicMatrix* m) {
132    for (int i = 0; i < m->rows; i++) {
133        for (int j = 0; j < m->cols; j++) {
134            printf("(%d, %s, %.2f) ", m->matrix[i][j].id,
135                   m->matrix[i][j].name ? m->matrix[i][j].name : "NULL",
136                   m->matrix[i][j].score);
137        }
138        printf("\n");
139    }
140}
141
142// 释放矩阵中所有动态分配的内存
143void freeMatrix(DynamicMatrix* m) {
144    if (!m) return;
145
146    for (int i = 0; i < m->rows; i++) {
147        for (int j = 0; j < m->capacity; j++) {
148            if (m->matrix[i][j].name) {
149                free(m->matrix[i][j].name);
150            }
151        }
152        free(m->matrix[i]);  // 释放每一行的内存
153    }
154    free(m->matrix);  // 释放行指针数组
155    free(m);  // 释放DynamicMatrix结构体本身
156}
157
158int main() {
159    int initialRows = 1, initialCols = 2;
160    DynamicMatrix* m = createMatrix(initialRows, initialCols);  // 动态创建矩阵
161
162    if (m == NULL) {
163        printf("矩阵创建失败。\n");
164        return 1;
165    }
166
167    printf("初始化后的矩阵:\n");
168    printMatrix(m);
169
170    // 添加新元素
171    addElement(m, 0, 1, "Alice", 88.5f);
172    addElement(m, 0, 2, "Bob", 92.0f);
173    addElement(m, 1, 3, "Charlie", 75.0f);  // 自动扩展行
174    printf("\n添加元素后的矩阵:\n");
175    printMatrix(m);
176
177    // 释放矩阵中的所有动态分配的内存
178    freeMatrix(m);
179
180    return 0;
181}

关键实现说明

  1. 动态扩展容量

    • 通过realloc函数来扩展二维数组的行数和列数。
    • 每次容量不足时,容量翻倍(或根据实际需求扩展),以避免频繁的内存分配操作。
  2. 按需增加行或列

    • 如果需要插入新元素超过了当前容量,则调用expandMatrix函数扩展容量。
    • 当需要增加新行时,重新分配行指针数组,并为新行分配内存。
  3. 内存管理

    • 确保在每次分配新内存之前,检查是否需要释放旧内存。
    • 提供freeMatrix函数用于释放所有动态分配的内存,防止内存泄漏。

最后修改于 2024-09-04 19:04