首页 > 编程笔记 > C语言笔记

C语言二维数组的定义和使用(附带示例)

二维数组是C语言中一个强大而灵活的结构,它允许我们以表格或矩阵的形式组织和存储数据。这种数据结构在处理复杂的数学计算、图像处理和游戏开发等领域中扮演着重要角色。

二维数组的概念

二维数组可以被想象成一个由行和列组成的表格。每个元素都有两个索引:一个表示行,另一个表示列。这种结构使得我们可以轻松地表示和操作矩阵、棋盘等二维数据。
 

C语言二维数组示意图

声明二维数组

在C语言中,声明二维数组的语法如下:

数据类型 数组名[行数][列数];

例如,要声明一个 3 行 4 列的整数二维数组,我们可以这样写:

int matrix[3][4];

这行代码创建了一个可以存储 12 个整数的二维数组,分布在 3 行 4 列中。值得注意的是,C语言中的数组索引是从 0 开始的,所以第一个元素的索引是 [0][0],而不是 [1][1]。

初始化二维数组

二维数组的初始化可以在声明时完成,也可以在之后通过赋值完成。以下是几种常见的初始化方法:

1. 声明时初始化

int matrix[3][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

这种方法清晰地展示了数组的结构,每个大括号内的数字代表一行。

2. 省略行数的初始化

int matrix[][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
};

在这种情况下,编译器会根据初始化的数据自动计算行数。

3. 单行初始化

int matrix[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

这种方法虽然简洁,但可能不如前两种方法直观。数组会按行顺序填充。

访问二维数组元素

访问二维数组的元素需要使用两个索引,语法如下:

数组名[行索引][列索引]

例如,要访问上面定义的 matrix 数组中第二行第三列的元素(值为 7),我们可以这样写:

int element = matrix[1][2];  // 注意索引从 0 开始

下面是一个完整的示例,展示了如何遍历和打印二维数组的所有元素:

#include <stdio.h>

int main() {
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    return 0;
}

这段代码会输出:

1 2 3 4
5 6 7 8
9 10 11 12

二维数组的内存布局

理解二维数组在内存中的存储方式对于深入掌握它的工作原理非常重要。C语言中的二维数组是以行主序(row-major order)存储的,这意味着同一行的元素在内存中是连续存储的。
 

C语言二维数组的内存布局


例如,对于一个 3x4 的数组,内存中的布局实际上是一个长度为 12 的一维数组。这种存储方式使得按行遍历数组通常比按列遍历更高效。

C语言二维数组的典型使用场景

二维数组在许多实际应用中扮演着重要角色,接下来我们将探讨C语言中二维数组的几个典型使用场景,并提供详细的代码示例来说明其应用。

1. 矩阵运算

矩阵运算是二维数组最常见的应用之一。在数学和科学计算中,矩阵操作如加法、乘法等频繁出现。使用二维数组可以轻松地表示和操作矩阵,下面是一个简单的矩阵加法示例:

#include <stdio.h>

#define ROWS 3
#define COLS 3

void addMatrices(int A[ROWS][COLS], int B[ROWS][COLS], int C[ROWS][COLS]) {
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            C[i][j] = A[i][j] + B[i][j];
        }
    }
}

void printMatrix(int matrix[ROWS][COLS]) {
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int A[ROWS][COLS] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    int B[ROWS][COLS] = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};
    int C[ROWS][COLS];

    addMatrices(A, B, C);

    printf("Matrix A:\n");
    printMatrix(A);
    printf("Matrix B:\n");
    printMatrix(B);
    printf("Result Matrix C (A + B):\n");
    printMatrix(C);

    return 0;
}

这个例子展示了如何使用二维数组表示矩阵,并实现矩阵加法。程序定义了两个 3x3 的矩阵 A 和 B,然后将它们相加得到矩阵 C。

2. 图像处理

在图像处理中,二维数组可以用来表示像素矩阵。每个数组元素代表一个像素的颜色或亮度值。通过操作这个二维数组,我们可以实现各种图像处理技术,如模糊、锐化等。


以下是一个简单的图像反转(负片效果)示例:

#include <stdio.h>

#define WIDTH 5
#define HEIGHT 5
#define MAX_INTENSITY 255

void invertImage(unsigned char image[HEIGHT][WIDTH]) {
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            image[i][j] = MAX_INTENSITY - image[i][j];
        }
    }
}

void printImage(unsigned char image[HEIGHT][WIDTH]) {
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            printf("%3d ", image[i][j]);
        }
        printf("\n");
    }
}

int main() {
    unsigned char image[HEIGHT][WIDTH] = {
        {100, 200, 150, 200, 100},
        {50, 100, 150, 100, 50},
        {0, 50, 100, 50, 0},
        {50, 100, 150, 100, 50},
        {100, 200, 150, 200, 100}
    };

    printf("Original Image:\n");
    printImage(image);

    invertImage(image);

    printf("\nInverted Image:\n");
    printImage(image);

    return 0;
}

这个例子使用一个 5x5 的二维数组来表示一个简单的灰度图像。每个元素的值范围是 0-255,代表像素的亮度。invertImage 函数通过将每个像素值从 255 中减去来实现图像反转。

3. 游戏开发

在游戏开发中,二维数组经常用于表示游戏地图或棋盘。每个数组元素可以代表地图上的一个位置或棋盘上的一个格子。


下面是一个简单的井字游戏棋盘示例:

#include <stdio.h>

#define BOARD_SIZE 3

void initializeBoard(char board[BOARD_SIZE][BOARD_SIZE]) {
    for (int i = 0; i < BOARD_SIZE; i++) {
        for (int j = 0; j < BOARD_SIZE; j++) {
            board[i][j] = ' ';
        }
    }
}

void printBoard(char board[BOARD_SIZE][BOARD_SIZE]) {
    printf(" %c | %c | %c \n", board[0][0], board[0][1], board[0][2]);
    printf("---+---+---\n");
    printf(" %c | %c | %c \n", board[1][0], board[1][1], board[1][2]);
    printf("---+---+---\n");
    printf(" %c | %c | %c \n", board[2][0], board[2][1], board[2][2]);
}

int makeMove(char board[BOARD_SIZE][BOARD_SIZE], int row, int col, char player) {
    if (row < 0 || row >= BOARD_SIZE || col < 0 || col >= BOARD_SIZE || board[row][col] != ' ') {
        return 0;  // Invalid move
    }
    board[row][col] = player;
    return 1;  // Valid move
}

int main() {
    char board[BOARD_SIZE][BOARD_SIZE];
    initializeBoard(board);

    printf("Initial Tic-Tac-Toe board:\n");
    printBoard(board);

    printf("\nMaking moves...\n");
    makeMove(board, 0, 0, 'X');
    makeMove(board, 1, 1, 'O');
    makeMove(board, 2, 2, 'X');

    printf("\nUpdated Tic-Tac-Toe board:\n");
    printBoard(board);

    return 0;
}

这个例子展示了如何使用 3x3 的二维数组来表示井字游戏的棋盘。initializeBoard 函数初始化棋盘,makeMove 函数在棋盘上放置棋子,printBoard 函数打印当前棋盘状态。
 

以上介绍的示例只是二维数组应用的冰山一角,实际上,二维数组的使用场景还有很多,如数据分析、地图表示、表格处理等。


声明:《C语言系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。