【22】C语言 - 二维数组详解

【22】C语言 - 二维数组详解

文章目录

1. 二维数组介绍

一个二维数组可以被直观地理解为一个由组成的表格。

例如,一个2行3列的二维数组可以这样表示:

行/列 列0 列1 列2
行0 [0][0] [0][1] [0][2]
行1 [1][0] [1][1] [1][2]

每个元素通过两个索引(下标)来访问:第一个索引代表行号 ,第二个索引代表列号 。索引总是从0开始。


2. 二维数组的声明

声明一个二维数组需要指定行数列数

语法:

c 复制代码
数据类型 数组名[行数][列数];

示例:

c 复制代码
int matrix[3][4]; // 声明一个3行4列(共12个元素)的整型二维数组
float temperatures[5][7]; // 声明一个5行7列的浮点型二维数组
char chessBoard[8][8]; // 声明一个8行8列的字符型二维数组(如棋盘)

3. 二维数组的初始化

方法一:先声明,再初始化

c 复制代码
#include <stdio.h>

int main(){
    //1.先声明再初始化
    int arr[3][2];
    arr1[0][0] = 1;
    arr1[0][1] = 2;
    arr1[1][0] = 3;
    arr1[1][1] = 4;
    arr1[2][0] = 5;
    arr1[2][1] = 6;
    return 0;
}

方法二:声明的同时,并初始化

c 复制代码
#include <stdio.h>

int main(){
	int matrix[2][3] = {
	    {1, 2, 3},   // 第0行的元素
	    {4, 5, 6}    // 第1行的元素
	};
  return 0;
}

方法三:直接列出所有元素(编译器自动计算行数)

一层大括号自动分配。

c 复制代码
#include <stdio.h>

int main(){
    int arr[2][4] = {1,2,3,4,5,6,7,8};
    return 0;
}

可以省略行数 ,编译器会根据你提供的数据自动计算行数。但列数绝对不能省略

c 复制代码
#include <stdio.h>

int main(){
    int arr4[][3] = {1,2,3,4,5,6};
    return 0;
}

方法四:部分初始化

未显式初始化的元素会被自动设置为0。

c 复制代码
#include <stdio.h>

int main(){
// 只初始化第一行,其余行自动为0
int arr1[3][4] = {{1}, {2, 3}};
/* 结果为:
   行0: 1, 0, 0, 0
   行1: 2, 3, 0, 0
   行2: 0, 0, 0, 0
*/

// 将所有元素初始化为0的最简单方法
int arr2[3][4] = {0};
}

4. 访问二维数组的元素

使用数组名后跟两个方括号 [行索引][列索引] 来访问或修改元素。

示例:

c 复制代码
#include <stdio.h>

int main() {
    int table[2][3] = {
        {10, 20, 30},
        {40, 50, 60}
    };

    // 访问单个元素
    printf("table[0][1] = %d\n", table[0][1]); // 输出:20
    printf("table[1][2] = %d\n", table[1][2]); // 输出:60

    // 修改元素
    table[1][0] = 99;
    printf("修改后 table[1][0] = %d\n", table[1][0]); // 输出:99

    return 0;
}

5. 使用循环遍历二维数组

遍历二维数组通常需要使用两层嵌套的循环

外层循环控制行,内层循环控制列。

示例:打印整个数组

c 复制代码
#include <stdio.h>

int main() {
    int rows = 2, cols = 3;
    int table[2][3] = {{1, 2, 3}, {4, 5, 6}};

    // 遍历打印
    for (int i = 0; i < rows; i++) {       // i 循环行
        for (int j = 0; j < cols; j++) {   // j 循环列
            printf("%d ", table[i][j]);
        }
        printf("\n"); // 打印完一行后换行
    }
    /* 输出:
       1 2 3
       4 5 6
    */

    return 0;
}

6. 内存中的存储方式

这是理解二维数组的关键:二维数组在内存中是按行优先的顺序连续存储的

对于数组 int arr[2][3] = {``{1,2,3}, {4,5,6}};,它在内存中的排列顺序是:

复制代码
行0: 1, 2, 3,
行1: 4, 5, 6

物理地址是连续的:1的地址后面紧跟着2,然后是3,再然后是4,以此类推。

正因为这种连续的线性存储,我们可以用单层循环和指针来遍历它,但更常见的还是用双层循环。


7. 将二维数组传递给函数

将二维数组作为参数传递给函数时,必须指定列的大小

这是因为编译器需要知道一行有多少个元素,才能正确计算内存地址。

函数原型示例:

c 复制代码
// 正确:指定了列数
void printMatrix(int arr[][4], int rows) {
    // ...
}

// 也可以明确写出行列,但行数会被忽略,通常用变量传递
void printMatrix(int arr[][4], int rows) {
    // ...
}

// 错误:没有指定列数
// void printMatrix(int arr[][], int rows, int cols);

完整示例:

c 复制代码
#include <stdio.h>

// 函数定义,必须指定列数(这里是4)
void printArray(int arr[][4], int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 4; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}

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

    printArray(myArray, 3); // 将数组传递给函数

    return 0;
}

8. 总结与要点

特性 说明
本质 一个"数组的数组",是逻辑上的表格,物理上的连续内存块。
声明 type name[rows][cols];
初始化 推荐按行用{}初始化。可以省略行数,但不能省略列数。
访问 array[i][j]i为行索引,j为列索引,都从0开始。
遍历 使用两层嵌套循环,外层循环行,内层循环列。
内存 按"行优先"顺序连续存储。
传参 函数参数中必须指定列数(如int arr[][4])。
相关推荐
云边有个稻草人2 小时前
Rust 借用分割技巧:安全解构复杂数据结构
数据结构·安全·rust
qq_479875432 小时前
Linux time function in C/C++【2】
linux·c语言·c++
TL滕3 小时前
从0开始学算法——第一天(如何高效学习算法)
数据结构·笔记·学习·算法
傻童:CPU3 小时前
DFS迷宫问题
算法·深度优先
B站_计算机毕业设计之家3 小时前
计算机视觉:python车辆行人检测与跟踪系统 YOLO模型 SORT算法 PyQt5界面 目标检测+目标跟踪 深度学习 计算机✅
人工智能·python·深度学习·算法·yolo·目标检测·机器学习
一个不知名程序员www3 小时前
算法学习入门---前缀和(C++)
c++·算法
jackzhuoa3 小时前
Rust API 设计的零成本抽象原则:从语言基石到工程实践
算法·rust
yuuki2332333 小时前
【数据结构】双向链表的实现
c语言·数据结构·后端
ol木子李lo4 小时前
Doxygen入门指南:从注释到自动文档
c语言·c++·windows·编辑器·visual studio code·visual studio·doxygen