精华内容
下载资源
问答
  • C++二维数组的定义及理解

    千次阅读 多人点赞 2020-11-27 17:26:28
    #二维数组的定义方式 #二维数组结构含义与理解 前言 一维数组对于存储和处理一组数据很有用,但是有时候,很有必要使用多维数组。 例如,在统计学生成绩程序中,教师可以将一个学生所有科目考试分数记录在一个...

    一、前言

    一维数组对于存储和处理一组数据很有用,但是有时候,很有必要使用多维数组。

    例如,在统计学生成绩的程序中,教师可以将一个学生的所有科目考试分数记录在一个 double 类型的数组中。如果老师有40 名学生,那就意味着需要 40 个 double 类型数组来记录整个班级的分数。当然,在这里定义 40 个单独的一维数组显然是不合适的,而只要定义一个二维数组就可以了。

    到目前为止,教程中所介绍的数组都只是一维数组,因为它们只能保存一组数据。二维数组,也称为 2D 数组,可以容纳多组数据。最好将二维数组看作具有行和列元素的表,一个二维数组可以被认为是一个带有 x 行和 y 列的表格。如下图 所示:
    在这里插入图片描述
    这张图是以二维数组显示了 3 行 4 列的考试成绩。
    注意:数组的索引(下标)编号是从0开始的,所以3 行的编号为 0〜2, 4 列的编号则为 0〜3。数组中一共有 3*4=12 个元素。

    二、二维数组的内存存储

    一般的我们说的C/C++中的二维数组是定义在栈中的二维数组。比如定义了一个array[3][4],那就指的是定义了一个三行四列的矩阵形状的二维数组,如下图所示。这样的矩阵在内存中是以箭头右边的方式存放的,也就是说实际上我们定义的二维数组在内存中仍然像是一维数组那样连续存储的。可以想象为把一个矩阵一层层伸展铺平。
    在这里插入图片描述

    三、二维数组的定义

    二维数组的定义可以是静态二维数组,可以是动态数组。

    要定义一个二维数组,需要两个大小声明符。第一个是行数,第二个是列数。
    定义方法有:
    下面是一个 3 行 4 列的二维数组定义的例子:

    方法一: 直接确定二维数组的行和列数

    (1)确定二维数组的行和列数,但是不确定数组中的具体元素:

    // 定义一个double类型的2行3列的二维数组,并没有确定数组中的具体元素
    double score[3][4];
    

    (2)不完全确定数组中的具体元素

    // 定义一个int类型的2行3列的二维数组,并没有确定数组中的具体元素
    int a[3][4] = {1,2,3,4,5,6}
    

    (3)确定二维数组的行和列数,并且确定数组中的具体元素:

    a.直接将二维数组铺平,写成一维数组的形式

     //a是一个2行3列的二维数组,并且确定好了里边的元素
    int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};  
    

    b.使用标准的二维数组的初始化方式

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

    方法二: 不用指明二维数组的行数,但要指明列数

    注意:二维数组必须写明列数,行数可以不写明!

    /* 经典的写法
     */
    int array[][4];
     
    /* 一种更帅的写法,本质上是定义了一个数组指针
     */
    int (*array)[4];
    

    方法三: 动态分配的方式,这种写法比较灵活,在定义的时候不需要指明二维矩阵的行数和列数

    /* 使用动态分配内存的形式,用malloc
     */
    int **array // array[M][N]
    array = (int **)malloc(M * sizeof(int *));
    for(int i = 0; i < M; i++) {
        array[i] = (int *)malloc(N * sizeof(int));
    }
     
    // 释放
    for(int i = 0; i < M; i++)
        free(array[i]);
    free(array);
     
    /* 使用动态分配内存的形式,用new
     */
    int **array // array[M][N]
    array = new int*[M];
    for(int i = 0; i < M; i++) {
        array[i] = new int[N];
    }
     
    // 释放
    for(int i = 0; i < M; i++) 
        delete [] array[i];
    delete [] array;
     
    

    不过按照这种形式实现的二维数组本质上已经不是我们之前说的传统的二维数组 了,采用此种方法定义的二维数组的结构如下图所示,这样的二维数组在堆上分配内存。也就是说这样实现的二维数组本质上已经是指针数组了。使用这样的方式分配二维数组空间之后,可以使用array[i][j]进行数组的读写操作没有问题,但是应该知道不同行的内存空间不一定连续。这是因为每一行的数组的内存都是使用malloc分配的,多次使用malloc分配的内存空间并不一定是连续的,这与在栈上分配的二维矩阵有着根本的不同,比如同样的对于顶底的二维数组array[3][4],不能再使用array[0][4]来访问array[1][0]了,这样会导致地址越界,就是因为地址不一定连续了。
    在这里插入图片描述

    参考博客: https://blog.csdn.net/qq_26822029/article/details/85037209

    四、重点)二维数组行、列的理解(代码实践 )

    double ary[][3] = { 0,1,2,3,4,5,6,7,8};
    

    代码说明:以一维数组平铺展开二维数组的定义形式定义了一个二维数组,指明了3列,那么后边的具体元素会默认每三个为一行,共3行

    以标准二维数组定义的方式,则定义为:很清晰的看到每三个元素为一个元素,用“{ }”扩着

    double ary[][3] = { {0,1,2},{3,4,5} ,{6,7,8} }; 
    

    那么这样定义的二维数组,我们在控制台输出看一下结果:

    #include "pch.h"
    #include <iostream>
    using namespace std;
    //二维数组问题
    int main()
    {
    	//初始化二维数组ary,指明列数为3列
    	double ary[][3] = { {0,1,2},{3,4,5} ,{6,7,8} };
    	for (size_t i = 0; i < 3; i++) //输出3行
    	{
    		cout << "第" << i << "行"<<" ";
    		for (size_t j = 0; j < 3; j++) //输出4列
    		{
    			cout << ary[i][j]<<"," ;
    		}
    		cout << endl;
    	}
    }
    
    

    在这里插入图片描述
    通过控制台输出的结果,我们确实看到输出3行3列正好是arr[ ][3]数组。

    二维数组行、列溢出?

    那么,小编的脑袋冒出了小小的疑惑:如果输出的行或者列超出了会产生什么结果?

    a. 行溢出

    在这里插入图片描述

    我们看输出结果,可以发现如果是行溢出,那么多出的两行因为没有确定具体的元素,而产生随机行为,输出随机数。

    原因:
    这涉及到内存分配的问题,二维数组说白了还是一个指针,你声明的时候就相当于和系统说:“嘿,这块地是我的了,不要让别人抢去”
    然后呢,你就可以自由访问了。
    但是呢,别的地方内存还是在的,你硬要访问呢当然还是访问的到的,但是这个地方可能别的程序或者什么东西在用着,虽然有值(计算机总是二进制,总能读出一个数),但是如果你对它做一些修改什么的可能会有一定的安全隐患的。

    这里需要说明的是,在不同的语言中,语法要求有所不同,出现行/列溢出可能不是产生随机行为,而是出现异常。

    b.列溢出

    在这里插入图片描述
    如果列溢出可以发现,第一行多余的两列元素是第二行的元素,第二行的元素是第三行的元素,第三行多余两列元素是随机数,那么为什么是这样呢?
    原因分析:
    这是由于分配内存地址是连续内存的原因,数组长度和数组值是确定的:ary[][3]={0,1,2,3,4,5,6,7,8} 这个二维数组在内存地址中是连续的,所以当第一行列溢出后,会取第二行的存在的数组值,最后一行列溢出时,其实相当于上边的行溢出,直接溢出整个数组所在的内存空间了。

    展开全文
  • 二维数组的排序

    2021-03-12 10:12:20
    对于一个已定义的二位数组a进行如下规则排序,首先按照每一个对应的一维数组第一个元素进行升序排序(即a[][0]),若第一个元素相等,则按照第二个元素进行升序排序(a[][1])。(特别注意,这里的a[][0]或者a[][1]在java...

     

     

    
    //第一种方法:将二维数组转置到一维数组,再对一维数组排序
    int [][]a = new int [5][2];
    
    //定义一个二维数组,其中所包含的一维数组具有两个元素
    
    对于一个已定义的二位数组a进行如下规则排序,首先按照每一个对应的一维数组第一个元素进行升序排序(即a[][0]),若第一个元素相等,则按照第二个元素进行升序排序(a[][1])。(特别注意,这里的a[][0]或者a[][1]在java中是不能这么定义的,这里只是想说明是对于某一个一维数组的第0或1个元素进行排序)
    
    Arrays.sort(a, new Comparator<int[]>() {
    @Override
    public int compare(int[] o1, int[] o2) {
    if (o1[0]==o2[0]) return o1[1]-o2[1];
    return o1[0]-o2[0];
    }
    });
    其中o1[1]-o2[1]表示对于第二个元素进行升序排序如果为o2[1]-o1[1]则表示为降序

     

    展开全文
  • 详解二维数组

    2018-04-14 23:32:51
    二维数组的使用规则一:定义 int arr[3]; int brr[3][4]; 对比一位数组,二维数组具有行和列两个参数,在定义上,与一维数组相似 数据类型 数组名[行][列];二:初始化 同样,对于一维数组初始化,如下示:...

    二维数组的使用规则

    一:定义
       int arr[3];
       int brr[3][4];

       对比一位数组,二维数组具有行和列两个参数,在定义上,与一维数组相似
      数据类型  数组名[行][列];
    二:初始化
      同样,对于一维数组的初始化,如下所示:
      int arr[3] = {1,2,3};
      int arr[3] = {1};//其余默认为0

      那么,二维数组呢?
      二维数组的初始化采用行优先的原则并且,中括号里边只能省略行的值,不能省略列的值。

     三:二维数组的打印
    打印二位数组,两层for循环,遍历行和列,然后进行打印
    直接在主函数中打印:

    利用函数调用,打印:
    在利用函数调用打印二维数组时,一般我们的参数列表为
    void show(int crr[][4],int row,int col)
    在这里要注意,二维数组的数组名不是一个二级指针,因此,不可以将参数列写成
    void show(int **crr,int row,int col)//error
    那么在调用函数中,一维数组的形参列表可以写成(int *arr)指针类型,

    那么二位数组呢,接下来我们对比分析一下两者的异同:

    一维数组,它的定义为:int arr[4];并且我们可以确定的是:

    先来看一维数组,一维数组中的数组名
    arr的数据类型为int *
    arr+1为int *
    arr[0]为int 

    在二维数组中,int brr[3][4];它的数组名以及以下的数据类型分别为:
    brr:         int(*p)[4]
    brr+1:     int(*p)[4]
    brr[0]:      int *
    brr[0]+1:  int *
    brr[0][0]:  int

    也就是说,我们可以将一个二维数组看成是一个一维数组,一行为一个单元格,遵循行优先的原则。
    即brr[0][4]和arr[4]相比较,arr == brr[0],同为一维数组名。
    在此,我们区别以下数组指针和指针数组的含义:
    int (*p)[4];//数组指针:即指向数组的指针
    int *p[4];//指针数组:即保存指针的数组

    因此,利用调用函数时,我们可以将形参列表写成如下:

    对了,在说一个关于二维数组越界的问题,由于我们可以将一个二维数组看成一个一维数组,当二维数组月结某一行时,自动跳转到下一行的起始位置。如下例所示,越界的位置和下一行的起始位置值一致。


    最后附上判断复杂数据类型的方法:
    (一):看符号的优先级
    (二):[]数组       关注数组的格子数和数据类型
                  *指针      关注指针的指向内容
          ()函数     关注函数的参数列表和返回值

    展开全文
  • Java 二维数组排序

    2020-05-19 08:58:30
    //定义一个二维数组,其中包含的一维数组具有两个元素 对于一个已定义的二位数组a进行如下规则排序,首先按照每一个对应的一维数组第一个元素进行升序排序(即a[][0]),若第一个元素相等,则按照第二个元素进行升序...

    int [][]a = new int [5][2];

    //定义一个二维数组,其中所包含的一维数组具有两个元素

    对于一个已定义的二位数组a进行如下规则排序,首先按照每一个对应的一维数组第一个元素进行升序排序(即a[][0]),若第一个元素相等,则按照第二个元素进行升序排序(a[][1])。(特别注意,这里的a[][0]或者a[][1]在java中是不能这么定义的,这里只是想说明是对于某一个一维数组的第0或1个元素进行排序)

    Arrays.sort(a, new Comparator<int[]>() {
    @Override
    public int compare(int[] o1, int[] o2) {
    if (o1[0]==o2[0]) return o1[1]-o2[1];
    return o1[0]-o2[0];
    }
    });
    其中o1[1]-o2[1]表示对于第二个元素进行升序排序如果为o2[1]-o1[1]则表示为降序。

    展开全文
  • •明确要定义的功能最后的结果是什么? •明确在定义该功能的过程中,是否需要未知内容参与运算 示例: •需求:定义一个功能,可以实现两个整数的加法运算。 •分析: •该功能的运算结果是什么?两个数...
  • 二维数组的地址

    2011-04-20 21:38:00
     a代表二维数组首元素地址,该首元素不是一个整型变量,而是由4个整型元素组成一维数组{1,3,5,7},即指向首元素——数组a[0]地址。 a[0]则指向数组{1,3,5,7}首元素地址是a[0][0]地址,也就是&a[0][0]。...
  • //定义一个二维数组,其中包含的一维数组具有两个元素 对于一个已定义的二位数组a经行如下规则排序,首先按照每一个对应的一维数组第一个元素进行升序排序(即a[][0]),若第一个元素相等,则按照第二个元素进行升序...
  • 二维数组与指针(详解)

    千次阅读 多人点赞 2019-04-02 00:00:29
    1.二维数组的定义 int a[3][3]; 在这我们定义了一个二维数组,拥有3行3列共9个int型存储空间大小。 2.二维数组的行地址和各个元素地址表示 int a[3][4]; 对于数组a,我们可以将a[3][4]分为两部分理解a[3]和[4],...
  • 数组指针 1.什么是数组指针: 首先它是一个指针,它指向一个数组,在32位系统下任何类型指针占内存大小都为4个字节,至于它指向数组占多少字节,具体要看数组大小。...(1)对于维数组: int main(void)...
  • //定义一个二维数组,其中包含的一维数组具有两个元素 对于一个已定义的二位数组a经行如下规则排序,首先按照每一个对应的一维数组第一个元素进行升序排序(即a[][0]),若第一个元素相等,则按照第二个元素进行升序...
  • 二维数组的回形格式

    2021-04-12 14:34:44
    1.每一个回形箭头作为一次循环(1→20,21→32),可以看到6×6有3次回形循环,而3×3除去中心点只有1次回形循环,因此我们定义循环次数loop = input/2(如下图示); 2.对于每一条回形路线,可以划分为四小段...
  • 浅挖二维数组指针

    2020-05-26 20:59:30
    从一维数组开始 假设有数组int a[]={1,2,3}, 我们可是通过一系列方式访问它 定义:int *p; p=a; 则p指向了a。此时我们姑且认为a与p等价。 需求 使用 a 使用 p 访问数组第一个元素 a[0] *p 同上 *a p[0...
  • 定义一个二维数组,其中包含一维数组具有两个元素 Arrays.sort(intervals,new Comparator<int[]>)(){ @Override public int compare(int[] a,int[] b){ //其中a[0]-b[0]表示对于第二个元素经行升序,...
  • 关于迪杰斯特拉算法:通俗来讲就是每次从起点(确定、唯一)选...(二维数组对于行营接触不到点本来是想更新,但由于if判断语句不为真所以没更新成,定义域为全体点;vector:由于vector形象存放了与当前点
  • 定义所有负数最大字段和是0,由此定义最优值是: max{ 0, a[i] }; 1.最大字段和问题简单方法(枚举方法) 代码实现: int Summax1(int a[],int n) { int sum=0; for(int i=1;i<=n;i++) { for....
  • int * p = (int *)malloc(sizeof(int)); 这条语句 应该怎么理解啊 对于动态分配我还不是太理解 。从内存角度他是怎么分配的?...这里定义的是int p 所以p指针只能指向int型空间 sizeof(int) 求得int类型占的字节
  • c++动态数组定义

    2020-05-10 12:11:57
    从指针层面理解:二维数组名相当于一个二级指针(在本文对二级指针内存有 东西的定义情况下),因为二级指针存是指针地址(二级指针的定义),使 二级指针内存有指针 地址 指向指针 内存有一串连续...
  • 从上面可以看出,定义了静态数组之后,无论程序如果使这个数组,该数组在内存中占空间大小,位置是确定不变。我们可以得出结论,对于编译器,静态数组的大小和空间是已知,因此编译器可以自动为该数组分配...
  • 数组指针和指针数组

    2012-03-30 17:00:10
    数组指针即指向数组指针变量, 以二维数组为例,它一般说明形式为: 类型说明符 (*指针变量名)[长度]   其中 “类型说明符”为指数组数据类型。 "*"表示其后变量是指针类型。“长度”表示二维数组分解...
  •  通常,对于int a[8][9]这个二维数组,我们可以这样定义一个指向它指针: int (*p)[9]; 这个声明形式跟人们熟悉int *p形式大相庭径,初学者通常会感到迷惑,不理解地方大致有四个: 1。为什么...
  • 严格来说,C++里面没有多维数组。所谓的多维数组就是数组的数组。对于二维数组,为了便于理解,可以把第一层...例如,定义一个int ia[3][4]的二维数组,就可以看成三行四列的一个矩阵。  如何遍历一个多维数组的
  • (19)多维数组

    2016-11-05 22:39:07
    严格来说,C++语言不存在多维数组,通常...对于二维数组来说,常把第一个维度称作行,第二个维度称作列。 多维数组初始化: 允许使用花括号括起来一组值初始化多维数组: int a[2][2]={{1,2}{3,4}};其中内层
  •  通常,对于int a[8][9]这个二维数组,我们可以这样定义一个指向它指针:   int (*p)[9];   这个声明形式跟人们熟悉int *p形式大相庭径,初学者通常会感到迷惑,不理解地方大致有四个:   1。...
  • 定义二维数组的语法: •type[ ] [ ] arrName; TestTwoDimension 我们可以得到一个结论: 二维数组是一维数组,其数组元素是一维数组;三维数组也是一维数组,其数组元素是二维数组;四维数组还是一维数...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 148
精华内容 59
关键字:

对于所定义的二维数组