跳转到内容

C 语言多维数组

来自代码酷

模板:Note

C语言多维数组[编辑 | 编辑源代码]

多维数组是C语言中存储表格状数据(如矩阵、三维空间坐标等)的核心数据结构。它本质上是"数组的数组",通过多个下标访问元素。本章将详细讲解二维、三维数组的声明、初始化、内存布局及实际应用。

基本概念[编辑 | 编辑源代码]

多维数组是线性数组在更高维度的扩展:

  • 一维数组:单行数据(向量)
  • 二维数组:行和列的表格(矩阵)
  • 三维数组:多个表格的堆叠(如RGB图像数据)

数学上,二维数组可表示为:Am×n=[a0,0a0,n1am1,0am1,n1]

声明与初始化[编辑 | 编辑源代码]

二维数组[编辑 | 编辑源代码]

// 声明3行2列的整型数组
int matrix[3][2]; 

// 声明时初始化(行数可省略)
int matrix[][2] = {{1, 2}, {3, 4}, {5, 6}};

三维数组[编辑 | 编辑源代码]

// 声明2个3x4的表格
int cube[2][3][4]; 

// 分层初始化
int cube[][3][4] = {
    {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}, // 第一层
    {{13,14,15,16}, {17,18,19,20}, {21,22,23,24}} // 第二层
};

内存布局[编辑 | 编辑源代码]

C语言采用行优先存储(Row-major order):

graph LR A[matrix[0][0]] --> B[matrix[0][1]] B --> C[matrix[1][0]] C --> D[matrix[1][1]] D --> E[matrix[2][0]] E --> F[matrix[2][1]]

计算公式(二维数组): Address(a[i][j])=Base+(i×COLUMNS+j)×sizeof(type)

访问元素[编辑 | 编辑源代码]

#include <stdio.h>

int main() {
    float temperature[3][4] = {
        {22.5, 23.1, 24.0, 23.7},
        {21.8, 22.3, 23.5, 22.9},
        {20.7, 21.2, 22.1, 21.5}
    };

    // 访问第2行第3列(0-based)
    printf("周三中午温度: %.1f°C\n", temperature[2][3]);
    
    // 遍历所有元素
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 4; j++) {
            printf("%.1f\t", temperature[i][j]);
        }
        printf("\n");
    }
    return 0;
}

输出:

周三中午温度: 21.5°C
22.5    23.1    24.0    23.7    
21.8    22.3    23.5    22.9    
20.7    21.2    22.1    21.5    

实际应用案例[编辑 | 编辑源代码]

案例1:矩阵乘法[编辑 | 编辑源代码]

#include <stdio.h>
#define ROWS_A 2
#define COLS_A 3
#define COLS_B 2

void matrix_multiply(int a[][COLS_A], int b[][COLS_B], int result[][COLS_B]) {
    for(int i = 0; i < ROWS_A; i++) {
        for(int j = 0; j < COLS_B; j++) {
            result[i][j] = 0;
            for(int k = 0; k < COLS_A; k++) {
                result[i][j] += a[i][k] * b[k][j];
            }
        }
    }
}

int main() {
    int a[ROWS_A][COLS_A] = {{1, 2, 3}, {4, 5, 6}};
    int b[COLS_A][COLS_B] = {{7, 8}, {9, 10}, {11, 12}};
    int result[ROWS_A][COLS_B];

    matrix_multiply(a, b, result);

    // 输出结果矩阵
    for(int i = 0; i < ROWS_A; i++) {
        for(int j = 0; j < COLS_B; j++) {
            printf("%d\t", result[i][j]);
        }
        printf("\n");
    }
    return 0;
}

输出:

58      64      
139     154     

案例2:三维坐标系统[编辑 | 编辑源代码]

#include <math.h>

typedef struct {
    float points[100][3]; // 存储100个三维点
    int count;
} PointCloud;

float calculate_distance(PointCloud pc, int index1, int index2) {
    float dx = pc.points[index1][0] - pc.points[index2][0];
    float dy = pc.points[index1][1] - pc.points[index2][1];
    float dz = pc.points[index1][2] - pc.points[index2][2];
    return sqrt(dx*dx + dy*dy + dz*dz);
}

高级主题[编辑 | 编辑源代码]

动态多维数组[编辑 | 编辑源代码]

使用指针数组模拟:

#include <stdlib.h>

int** create_2d_array(int rows, int cols) {
    int **arr = (int**)malloc(rows * sizeof(int*));
    for(int i = 0; i < rows; i++) {
        arr[i] = (int*)malloc(cols * sizeof(int));
    }
    return arr;
}

void free_2d_array(int** arr, int rows) {
    for(int i = 0; i < rows; i++) {
        free(arr[i]);
    }
    free(arr);
}

数组与指针的关系[编辑 | 编辑源代码]

二维数组名是指向第一个子数组的指针:

int matrix[3][4];
int (*ptr)[4] = matrix; // 指向包含4个int的数组的指针

常见问题[编辑 | 编辑源代码]

页面模块:Message box/ambox.css没有内容。

  • Q: 为什么不能省略所有维度?
  • A: 编译器需要知道除第一维外的所有维度来计算内存布局
  • Q: 如何传递多维数组给函数?
  • A: 必须指定除第一维外的所有维度,如:void func(int arr[][4])

最佳实践[编辑 | 编辑源代码]

  1. 对大型数组使用static存储类避免栈溢出
  2. 使用#defineconst定义维度常量
  3. 初始化时使用嵌套花括号提高可读性
  4. 考虑使用结构体封装复杂的多维数组

模板:Exercise