【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])。
相关推荐
lizz317 分钟前
C++操作符重载深度解析
java·c++·算法
阿拉斯攀登12 分钟前
电子签名:笔迹特征比对核心算法详解
人工智能·算法·机器学习·电子签名·汉王
ytttr87315 分钟前
matlab进行利用遗传算法对天线阵列进行优化
开发语言·算法·matlab
一招定胜负16 分钟前
机器学习算法三:决策树
算法·决策树·机器学习
无限进步_17 分钟前
【C语言】队列(Queue)数据结构的实现与分析
c语言·开发语言·数据结构·c++·算法·链表·visual studio
李余博睿(新疆)27 分钟前
c++经典练习题-分支练习(2)
c++·算法
Dev7z28 分钟前
基于中心先验的全局对比度显著性检测算法
人工智能·算法·计算机视觉
重生之我是Java开发战士31 分钟前
【算法日记】排序算法:原理、实现、性能与应用
数据结构·算法·排序算法
superman超哥33 分钟前
仓颉语言中网络套接字封装的深度剖析与工程实践
c语言·开发语言·c++·python·仓颉
啊阿狸不会拉杆42 分钟前
《数字图像处理》第 5 章-图像复原与重建
图像处理·人工智能·算法·matlab·数字图像处理