C PRIMER PLUS——第6-2节:二维数组与多维数组

目录

一、二维数组

[1. 二维数组的定义](#1. 二维数组的定义)

[2. 二维数组的初始化](#2. 二维数组的初始化)

(1)部分初始化

(2)完全初始化

(3)省略行数初始化

[3. 二维数组的访问](#3. 二维数组的访问)

[4. 二维数组的存储方式](#4. 二维数组的存储方式)

[5. 二维数组作为函数参数](#5. 二维数组作为函数参数)

(1)指定行数和列数

(2)省略行数但指定列数

[6. 二维数组的遍历](#6. 二维数组的遍历)

[7. 动态分配二维数组](#7. 动态分配二维数组)

二、多维数组

1.三维数组

[2. 多维数组的访问](#2. 多维数组的访问)

[3. 多维数组作为函数参数](#3. 多维数组作为函数参数)

[4. 多维数组的内存布局](#4. 多维数组的内存布局)

[5. 多维数组的注意事项](#5. 多维数组的注意事项)


一、二维数组

1. 二维数组的定义

二维数组可以看作是数组的数组,即一个一维数组的每个元素又是一个一维数组。定义二维数组的一般形式为:

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

示例:

int matrix34; // 定义一个3行4列的二维整型数组

这里,matrix 是一个二维数组,它有 3 行 4 列,总共包含 12 个整型元素。


2. 二维数组的初始化

(1)部分初始化

int matrix34 = {

{1, 2},

{5, 6, 7},

{9}

};

在这个例子中,没有明确初始化的元素会被自动初始化为 0。

(2)完全初始化

int matrix34 = {

{1, 2, 3, 4},

{5, 6, 7, 8},

{9, 10, 11, 12}

};

这里,所有的元素都被明确赋值。

(3)省略行数初始化

int matrix 4 = {

{1, 2, 3, 4},

{5, 6, 7, 8},

{9, 10, 11, 12}

};

在初始化时可以省略行数,但列数不能省略,编译器会根据初始化列表自动确定行数。


3. 二维数组的访问

可以使用两个下标来访问二维数组中的元素,第一个下标表示行,第二个下标表示列,下标从 0 开始。

复制代码
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    int element = matrix[1][2];  // 访问第2行第3列的元素,结果为7
    printf("The element at row 1, column 2 is: %d\n", element);//The element at row 1, column 2 is: 7
    return 0;
}

4. 二维数组的存储方式

在内存中,二维数组是按行优先顺序存储的,即先存储第一行的所有元素,再存储第二行的元素,依此类推。


5. 二维数组作为函数参数

(1)指定行数和列数

复制代码
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

// 函数接收一个3行4列的二维数组
void printMatrix(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");
    }
}

int main() {
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    printMatrix(matrix);
    return 0;
}
//结果:
//1 2 3 4
//5 6 7 8
//9 10 11 12

(2)省略行数但指定列数

复制代码
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

// 函数接收一个列数为4的二维数组
void printMatrix(int matrix[][4], int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 4; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    printMatrix(matrix, 3);
    return 0;
}
//结果:
//1 2 3 4
//5 6 7 8
//9 10 11 12

6. 二维数组的遍历

可以使用嵌套的 for 循环来遍历二维数组的所有元素。

复制代码
#define  _CRT_SECURE_NO_WARNINGS
#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

7. 动态分配二维数组

在 C 语言中,可以使用指针和 malloc 函数动态分配二维数组。

复制代码
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main() {
    int rows = 3;
    int cols = 4;
    // 分配一个包含rows个指针的数组
    int** matrix = (int**)malloc(rows * sizeof(int*));
    for (int i = 0; i < rows; i++) {
        // 为每一行分配内存
        matrix[i] = (int*)malloc(cols * sizeof(int));
    }
    // 初始化数组
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = i * cols + j + 1;
        }
    }
    // 打印数组
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
    // 释放内存
    for (int i = 0; i < rows; i++) {
        free(matrix[i]);
    }
    free(matrix);
    return 0;
}
//结果:
//1 2 3 4
//5 6 7 8
//9 10 11 12

使用完动态分配的内存后,需要使用 free 函数释放内存,以避免内存泄漏。


二、多维数组

多维数组其实就是数组的数组。最常见的多维数组为二维数组,当然也存在三维数组、四维数组等更高维度的数组。

1.三维数组

// 定义一个2个二维数组,每个二维数组有3行4列的三维数组

int arr4234;

// 初始化三维数组

int arr5234 = {

{ {1, 2, 3, 4},

{5, 6, 7, 8},

{9, 10, 11, 12}

},

{

{13, 14, 15, 16},

{17, 18, 19, 20},

{21, 22, 23, 24}

}

};


2. 多维数组的访问

三维数组的访问

复制代码
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
    int arr[2][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}
        }
    };

    // 访问第1个二维数组中第2行第3列的元素
    int element = arr[0][1][2];
    printf("Element at [0][1][2]: %d\n", element);//Element at [0][1][2]: 7

    return 0;
}

3. 多维数组作为函数参数

多维数组能够作为函数参数传递。在函数声明时,除了第一维的大小可以省略,其余维度的大小必须明确指定。

复制代码
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

// 二维数组作为函数参数
void print_2d_array(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");
    }
}

// 三维数组作为函数参数
void print_3d_array(int arr[][3][4], int num_2d_arrays) {
    for (int i = 0; i < num_2d_arrays; i++) {
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 4; k++) {
                printf("%d ", arr[i][j][k]);
            }
            printf("\n");
        }
        printf("\n");
    }
}

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

    int arr_3d[2][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}
        }
    };

    printf("2D Array:\n");
    print_2d_array(arr_2d, 3);

    printf("\n3D Array:\n");
    print_3d_array(arr_3d, 2);

    return 0;
}
//结果:
//2D Array :
//1 2 3 4
//5 6 7 8
//9 10 11 12
//
//3D Array :
//1 2 3 4
//5 6 7 8
//9 10 11 12
//
//13 14 15 16
//17 18 19 20
//21 22 23 24

4. 多维数组的内存布局

在 C 语言中,多维数组在内存里是按行优先的顺序存储的。也就是说,先存储第一行的所有元素,接着存储第二行的所有元素,依此类推。

例如,对于一个二维数组int arr[3][4],其内存布局如下:

arr00 -> arr01 -> arr02 -> arr03 ->

arr10 -> arr11 -> arr12 -> arr13 ->

arr20 -> arr21 -> arr22 -> arr23


5. 多维数组的注意事项

  • 数组越界:访问多维数组时,要保证下标在合法范围内,防止出现数组越界的情况。

  • 初始化:若对多维数组进行部分初始化,未初始化的元素会被自动初始化为 0。

  • 内存占用:多维数组会占用大量的内存,使用时要注意内存的使用情况。

相关推荐
北域码匠6 分钟前
SHA-1算法:安全哈希原理与应用解析
算法·c#·哈希算法
努力小周9 分钟前
STM32智能安防系统
c语言·stm32·单片机·嵌入式硬件·物联网·计算机网络·pcb工艺
skylar012 分钟前
小白1分钟安装flash-attn
开发语言·python
默子昂20 分钟前
ollama 自定义ui
开发语言·python·ui
fofantasy21 分钟前
MCM06050H05K00高刚性重载模组选型指南
经验分享·规格说明书
手写码匠1 小时前
手写 GraphRAG:从零实现图增强检索增强生成系统
人工智能·深度学习·算法·aigc
BomanGe11 小时前
NSK重载高刚性滚珠丝杠技术详解
经验分享·算法·规格说明书
星栈独行1 小时前
Makepad 应用如何读文件、调接口、保存数据
前端·程序人生·ui·rust·github
fofantasy1 小时前
NSK LH12AN 微型导轨技术手册
运维·网络·数据库·经验分享·规格说明书
赴生-2 小时前
C++进阶 C++11(下)
开发语言·c++