C语言学习笔记五(二维数组)

一、二维数组的基本概念

  1. 定义:二维数组是数组的数组,可以看作是由行和列组成的表格

  2. 特点

    • 所有元素具有相同的数据类型

    • 在内存中按行优先顺序连续存储

    • 通过两个下标(行索引和列索引)访问元素,都从0开始

 强调:定义数组时必须指定数据类型,不允许auto关键字(C新特性)由初始值的列表推新类型。

二、二维数组的声明和初始化

1. 数组声明

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

示例:

int matrix[3][4];      // 3行4列的整型二维数组
float grid[5][5];      // 5行5列的浮点型二维数组
char board[8][8];      // 8行8列的字符型二维数组

2. 数组初始化

(1) 完全初始化(按行):

int matrix[2][3] = {
    {1, 2, 3},
    {4, 5, 6}
};

(2) 线性初始化(编译器自动填充):

int matrix[2][3] = {1, 2, 3, 4, 5, 6};

(3) 部分初始化(未初始化的元素自动设为0):

int matrix[3][4] = {
    {1},
    {2, 3},
    {4, 5, 6}
};

(4) 不指定行数初始化(编译器自动计算行数):

int matrix[][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};  // 自动确定为3行

(5) C99新增的指定初始化方式:

int matrix[3][3] = {
    [0][0] = 1, [1][1] = 5, [2][2] = 9
};

强调:一些编译器支持数组赋值,即编译器扩展,但是好避免使用非标准特性,应为可能导致在其它原编译器无法工作。

 

三、二维数组元素的访问

  1. 通过行列下标访问:

    int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int x = matrix[0][1];  // 访问第1行第2列元素,x=2
    matrix[1][2] = 10;     // 修改第2行第3列元素为10

 

  1. 2.下标范围:

    • 行下标:0到(行数-1)

    • 列下标:0到(列数-1)

    • 越界访问是未定义行为

 

四、二维数组在内存中的存储

  1. 行优先存储:C语言中二维数组按行顺序连续存储

    • 例如int a[2][3]在内存中的顺序是:a[0][0], a[0][1], a[0][2], a[1][0], a[1][1], a[1][2]

  2. 计算数组大小:

    int matrix[3][4];
    size_t total_size = sizeof(matrix);             // 整个数组的字节大小
    size_t row_size = sizeof(matrix[0]);            // 一行的字节大小
    size_t element_size = sizeof(matrix[0][0]);     // 单个元素的字节大小
    int rows = sizeof(matrix) / sizeof(matrix[0]);  // 行数
    int cols = sizeof(matrix[0]) / sizeof(matrix[0][0]); // 列数
    

五、二维数组与指针的关系

  1. 二维数组名是指向第一行的指针

  2. 二维数组可以看作是一维数组的数组

  3. 指针表示法:

    int matrix[3][4];
    int (*ptr)[4] = matrix;  // 指向包含4个int的数组的指针
    
  4. 使用指针访问元素:

    printf("%d", *(*(matrix + 1) + 2));  // 等价于matrix[1][2]
    

六、二维数组作为函数参数

  1. 传递方式:

    // 方式1:明确指定列数
    void func(int arr[][4], int rows);
    
    // 方式2:使用指针形式
    void func(int (*arr)[4], int rows);
  2. 调用示例:

    int matrix[3][4] = {...};
    func(matrix, 3);
    
  3. 重要限制:必须指定列数(除第一维外其他维必须指定)

七、常见二维数组操作

1. 遍历二维数组

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

2. 矩阵转置

void transpose(int src[][3], int dest[][3], int size) {
    for(int i = 0; i < size; i++) {
        for(int j = 0; j < size; j++) {
            dest[j][i] = src[i][j];
        }
    }
}

 3. 矩阵乘法

void matrixMultiply(int a[][N], int b[][M], int result[][M], int rows) {
    for(int i = 0; i < rows; i++) {
        for(int j = 0; j < M; j++) {
            result[i][j] = 0;
            for(int k = 0; k < N; k++) {
                result[i][j] += a[i][k] * b[k][j];
            }
        }
    }
}

4. 查找最大元素及其位置

void findMax(int arr[][4], int rows, int *max, int *row, int *col) {
    *max = arr[0][0];
    *row = 0;
    *col = 0;
    for(int i = 0; i < rows; i++) {
        for(int j = 0; j < 4; j++) {
            if(arr[i][j] > *max) {
                *max = arr[i][j];
                *row = i;
                *col = j;
            }
        }
    }
}

八、多维数组的概念

  1. C语言支持更高维度的数组(三维、四维等)

  2. 声明方式:

    int cube[3][3][3];  // 三维数组

九、注意

  1. 内存布局:理解行优先存储方式对性能优化很重要

  2. 参数传递:函数参数中必须指定除第一维外的所有维度

  3. 指针类型:指向二维数组的指针类型与指向一维数组的指针不同

  4. 数组与指针

    • matrix的类型是"指向包含4个int的数组的指针"

    • matrix[0]的类型是"指向int的指针"

  5. 越界访问:C语言不检查多维数组的下标越界

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值