数组:二维数组

定义

二维数组本质上是数组的数组,即外层数组的每个元素都是一个一维数组,由行和列两部分构成,属于多维数组。可以按照先行后列的方式解读。

二维数组可被视为一个特殊的一维数组,也就是说,当一个数组的每一个元素都是移位数组的时候,那么这个数组就是二维数组。

语法

复制代码
 数据类型 数组名[行容量][列容量]
     //行容量指的是外层数组的数组容量,也就是二维数组中一维数组的个数
     //列容量指的是内层数组的数组容量,也就是二一维数组的元素个数

说明

  • 二维数组在初始化的时候,可以省略行数,系统会通过初始化后的数据自动推断行数。

  • 二维数组和一维数组一样,也可以部分初始化,未初始化的元素使用0进行填充(无论是全局作用域还是局部作用域)

  • 二维数组在初始化的时候,不能省略列数,否则编译报错。

举例

复制代码
 //推荐写法:省略行容量(编译器会自动推断),分行初始化
 int arr[][3]//写法不对,因为未初始化
 int arr[][3] = {{11,12,13},{11,12,13},{11,12,13}};//写法正确,编译器自动推断除行数为3
 //部分初始化未初始化的元素自动补0(二维数组中所有一维数组的大小一致)
 int arr[3][3] = {{1,2},{3,4,5},{6}};//等价于{{1,2,0},{3,4,5},{6,0,0}}
 int arr[][3] = {{1,2},{3,4,5},{6}}};//等价于{{1,2,0},{3,4,5},{6,0,0}}
 //{}空初始化列表,c89标准不支持(编译报错),C99及以上标准支持(静态/全局均会全0初始化)
 int arr[3][3] = {};//等价{{0,0,0},{0,0,0},{0,0,0}}
 int arr[3][3] = {0};//等价{{0,0,0},{0,0,0},{0,0,0}}
 ​
 int arr[][]={{1,2,0},{3,4,5},{6,0,0}};//编译报错

注意:C语言中二维数组按行优先 存储:先连续存储第0行的所有列元素,再存储第1行的所有列元素,以此类推;反映在下标上,行下标(第一维)变化慢,列下标(第二维)变化快(例如arr[2][3]先填满arr[0][0]->arr[0][1]->arr[0][2]再到arr[1][0]->arr[1][1]->arr[1][2]).

内存存储

注:这里的地址仅为了方便区分,实际的地址表示为12位十六进制整数。

应用场合

主要是应用对行列有要求的情况,比如说要存储一个年纪所有班级的学生成绩。

还有字符数组的应用,比如用数组存储学生姓名。

double score[30] = {};

double score[8][30] = {};

double score[6][8][30] = {};

特殊写法

下标可以是整型表达式。如a[2-1][2*2-1]访问的是a[1][3]

下标可以是已经有值的变量或者数组元素。如a[2*x-1][b[3][1]][]中最终需要的是一个>=0且小于数组对应维度容量的整数(下标从0开始)。

数组元素可以出现在表达式中,如b[1][2] = a [2][3]/2(考试用,开发不用)

演示

数组:arr 列0 列1 列2 举例 说明
行0 11 12 13 arr[0][1] 数组arr的0行1列对应的元素
行1 21 22 23 arr[1][2] 数组arr的1行2列对应的元素

注意:使用数组元素的下标应在已定义数组的大小范围内;应注意区别定义数组大小和引用数组元素的区别。

初始化

复制代码
 //分行给二维数组赋初值
 int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}}
 //
 int arr[3][3] = {1,2,3,4,5,6,7,8,9};
 //
 int arr[3][3] = {{1},{2,3},{4}};
 int arr[3][3] = {1,2,3,4};

案例

案例1:二维数组的遍历

  • 分析:

    • 二维数组本质上属于行列式,遍历的时候需要借助嵌套的for循环,外层for负责行的遍历,内层for负责列的遍历。

    • 取值

      复制代码
       数组名[行下标][列下标];
    • 赋值

      复制代码
       数组名[行下标][列下标] = 值;
    • 行和列的容量计算

      复制代码
       //计算行的大小
       int row_len = sizeof(arr) / sizeof(arr[行下标0]);
       //计算列的大小
       int col_len = sizeof(arr[行下标0]) / sizeof(arr[行下标0][列下标0]);
    • 代码

      复制代码
      ​ #include <stdio.h>
       ​
       int main(int argc,char *argv[])
       {
           int arr[3][3] = {1,2,3,4,5,6,7,8,9};
           int arr_row = sizeof(arr) / sizeof(arr[0]);
           int arr_col = sizeof(arr[0]) / sizeof(arr[0][0]);
       ​
           for(int i = 0; i < arr_row; i++)
           {
               for(int j = 0; j < arr_col; j++)
               {
                   printf("%-4d",arr[i][j]);
               }
               printf("\n");
           }
           printf("\n");
       ​
           return 0;
       }
    • 结果

案例2:矩阵的转置

  • 分析

    • 所谓的转置,就是原本的列变行,行变列
  • 代码

    复制代码
     #include <stdio.h>
     ​
     //定义行列宏
     #define ROW 2
     #define COL 3
     ​
     int main(int argc,char *argv[])
     {
         int i, j;//定义循环变量
     ​
         //准备2个数组,用来存放转置前后的数据
         int arr_before[ROW][COL] = {11,12,13,21,22,23};
         int arr_after[COL][ROW] = {0};
         //计算数组的大小
         int arr_before_row = sizeof(arr_before) / sizeof(arr_before[0]);
         int arr_before_col = sizeof(arr_before[0]) / sizeof(arr_before[0][0]);
         int arr_after_row = sizeof(arr_after) / sizeof(arr_after[0]);
         int arr_after_col = sizeof(arr_after[0]) / sizeof(arr_after[0][0]);
     ​
         //循环遍历二维数组
         printf("\n转置前:\n");
         for(i = 0; i < arr_before_row; i++)
         {
             for(j = 0; j < arr_before_col; j++)
             {
                 //打印转置前的数据
                 printf("%-4d",arr_before[i][j]);
                 //转置:行变列,列变行
                 arr_after[j][i] = arr_before[i][j];
             }
                 printf("\n");
         }
     ​
         printf("\n转置后:\n");
         for(i = 0; i < arr_after_row; i++)
         {
             for(j = 0; j < arr_after_col; j++)
             {
                 printf("%-4d",arr_after[i][j]);
             }
             printf("\n");
         }
         printf("\n");
     ​
     ​
     ​
         return 0;
     }
     ​
  • 结果

课堂练习

  • 需求:求一个3行3列的矩阵对角线元素相
相关推荐
vx-程序开发3 小时前
springboot在线装修管理系统-计算机毕业设计源码56278
java·c语言·spring boot·python·spring·django·php
大傻^3 小时前
Spring AI Alibaba 可观测性实践:AI应用监控与链路追踪
java·人工智能·后端·spring·springaialibaba
Dxy12393102163 小时前
js如何把字符串转数字
开发语言·前端·javascript
云烟成雨TD3 小时前
Spring AI Alibaba 1.x 系列【1】阿里巴巴 AI 生态
java·人工智能·spring
佑白雪乐3 小时前
LCR 175. 计算二叉树的深度
算法·深度优先
诗人不写诗3 小时前
spring是如何组织切面的
java·后端·spring
爱写bug的野原新之助3 小时前
爬虫之补环境:加载原型链
前端·javascript·爬虫
阿Y加油吧3 小时前
力扣打卡day07——最大子数组和、合并区间
算法
想吃火锅10053 小时前
【leetcode】105. 从前序与中序遍历序列构造二叉树
算法·leetcode·职场和发展