精华内容
下载资源
问答
  • 实际上, 二维数组在主存中的存储方式和一维数组无异, 都是占用一片连续的存储空间. 现在我们需要在逻辑上构造一个m行n列矩阵, 之前使用二维数组进行定义时, 应这样定义 short M[m][n]: 这是一个共有m*n个数据...

         在处理二维数组参数传递的问题时, 如果我们在编写函数时无法确定二维数组第二维的大小(二维数组在做函数形参时, 要求必须给出第二维的大小, 否则程序无法通过编译器的检查), 不妨尝试基于二维数组物理存储结构进行思考. 实际上, 二维数组在主存中的存储方式和一维数组无异, 都是占用一片连续的存储空间.

        现在我们需要在逻辑上构造一个m行n列的矩阵, 之前使用二维数组进行定义时, 应这样定义 short M[m][n]: 这是一个共有m*n个数据元素的数组, 在内存中占用m*n个连续的存储空间. 这里我们使用一维数组实现相同的功能, 直接定义一个长度为m*n的一维数组M. 对于二维数组来说, 其数据元素M[i][j]在位置上的含义为数组M的首地址向后偏移i * n + j个单位. 据此思想, 得到下面的程序. 

    [注]从二维数组到一维数组的转换思想需读者自行体会.

    #include<stdio.h>
    void Init(short *, short, short);
    void Show(short *, short, short);
    int main()
    {
        short m, n;
        scanf("%hd,%hd", &m, &n);
        short M[m * n];
        Init(M, m, n);
        Show(M, m, n);
        /* */
        return 0;
    }
    /* 初始化"二维数组" */
    void Init(short *X, short x, short y)
    {
        short i, j;
        printf("Please input data: \n");
        for(i = 0; i < x; i ++)
        {
            for(j = 0; j < y; j ++)
            {
                /* 运行效果等同于 X[i][j] */
                scanf("%hd", X + y * i + j);
            }
        }
    }
    /* 假设事先无法确定二维数组的第二维长度 */
    /* 将"二维数组"转化为一维数组 */
    void Show(short *X, short x, short y)
    {
        short i, j;
        printf("The matrix is \n");
        for(i = 0; i < x; i ++)
        {
            for(j = 0; j < y; j ++)
            {
                /* 运行效果等同于 X[i][j] */
                printf("%hd ", *(X + y * i + j));
            }
            putchar('\n');
        }
    }
    

    展开全文
  • 首先,我们必须明白二维数组的逻辑结构和物理结构 可以看到,实质上二维数组在物理上是连续存储的,但是分析二维数组指针的时候更应该分析二维数组的逻辑结构,如下所示: 应当看到,二维数组的在逻辑上是多个行数...

    先看一个例子:

    int a[3][4];
    int (*p)[4]=a;
    *(p[0]+2)=2;//这句话是什么意思
    

    首先,我们必须明白二维数组的逻辑结构和物理结构
    这是物理结构
    可以看到,实质上二维数组在物理上是连续存储的,但是分析二维数组指针的时候更应该分析二维数组的逻辑结构,如下所示:
    二维数组逻辑结构
    应当看到,二维数组的在逻辑上是多个行数个一维数组的集合,这种理解方式至关重要。

    在这种观点之下,我们来看一个问题。即a[0]的含义是什么?既然二维数组可以看做行数个一维数组的集合,那么a[0]是不是可以看做是一维数组的数组名?回忆我们用下标来指示数组的方式:a[0][1],是不是就是在a[0]当成数组名?那么我们就又要注意到,如果a[0]的含义是数组名,那么是否也像一维数组那样,可以当做该一维数组的首地址?答案是肯定的。即此刻我们可以认为,在二维数组中,a[i]存放着该行数组的首地址,那么,* (a[0]+2)的含义就很明显了。
    我们可以对 *(a[0]+2)这个式子采用这样的理解方式:我们设定第0行的行数组为数组b,那么此刻a[0]的含义就是b的数组名b,那么原式子可以理解为 *(b+2)。即b这一数组的第三个元素(下标从0开始)即 * (a[0]+2)= * (b+2)=b[2]=a[0][2].
    理解了a[i]是第i行数组的首地址的问题之后,我们再回到开头的那个问题。

    int (*p)[4]=a;
    *(p[0]+2)=2;//这句话是什么意思
    

    首先明确,int (*p)[4]=a;中的p是二维数组指针。与之对应的是指针数组int *p[4]。
    如何区分和记忆?我们记得,[]的优先级是很高的,于是int * p[4]中的p和[4]是密不可分的,这就意味着这里的p是一组数组的名字,而数组的类型是指针;与之对应的是int * §[4],这里p是二维数组的指针。
    二维数组的指针是什么?直观来看,和一维数组类似,用以指向整个二维数组。
    在这里插入图片描述
    就是这个图里的a。但是由于其是一个数组指针,所以要注意,它每次加1的步进值是4个数组单元。这就要回到逻辑上的二维数组结构了。
    在这里插入图片描述

    一般,我们会将二维数组的名字赋给数组指针p。p所指向的正是之前我们提到过的a[0]。而p+i指向的正是a[i]。那么**上面我们说过了,a[i]实质上是对应行的数组名字,也即该数组的地址,也是该行数组的指针。**那么可以看到,**这里p+i是指向第i行数组地址的指针,也就是第i行数组地址的地址。**既然是地址的地址,那么显而易见,需要两次解引用才可以取到数组中的某个元素。
    最常见的用法像是这样:
    *( *(p+i)+j)。我们来分析这个操作。首先是 *(p+i),这里 (p+i)==a[i]。但是注意了,反复强调过a[i]是i行数组的数组名,所以也可以理解为 (p+i)==a[i]=b;其中b是我们假定的第i行的数组名。那么将b代入这个式子可以看到原来的式子为:
    (b+j)。这个式子是不是就很好理解?就是b这个数组的第j号元素嘛。而b这个数组是a的第i行数组,于是很容易知道,绕了半天,( (p+i)+j)=a[i][j]。
    但是我们离开头的问题似乎还是差一点。这个
    (p[0]+2)=2;中的p[0]是什么呢?这里其实可以从两个方面理解,一个,可以将p和a一起来看,那么p[0]==a[0],那么a[0]+2指的就是第0行第2号元素的地址,外面加个解引用的符号即是取第0行的第2号元素。另外一个理解是p[0]等价于 *(p+0),再结合刚才的分析,那么就可以理解了。

    上面说了基本的原理,下面提炼下分辨的要点:

    1. int *p[4]是二维数组指针,表示的实际是二维数组的首地址,也是该二维数组中的一维数组的地址的地址。
    2. int (*p)[4]是指针数组。实质是元素为指针的一维数组。
    3. 分析二维数组时,如果出现了二维数组指针,那么取某个元素的时候要两次解引用,或者利用p[0]这样的形式做一个默认的转换。
    展开全文
  • 一维数组 数组名实际上就是数组首地址,是一个地址常量,本质上是一个数 数组名也可以进行运算,是逻辑运算,并不是直接数字运算 arr[0]*arr是一样 *(arr+1)arr[1]是一样 arr&arr[0]是一样...

    数组的存储

    一维数组

    • 数组名实际上就是数组首地址,是一个地址常量,本质上是一个数
    • 数组名也可以进行运算,是逻辑上的运算,并不是直接的数字运算
    • arr[0]和*arr是一样的
    • *(arr+1)和arr[1]是一样的
    • arr和&arr[0]是一样的
    • 数组存储空间时连续的,是线性的,所以算地址的时候可以用等差数列的公式a[n]地址=a[m]地址+(n-m)*元素占用空间

    例证:

    #include<stdio.h>
    
    int main(void)
    {
    	char arr1[5] = {'a','b','c','d','e'};
    	printf("%d\n",arr1);
    	printf("%d\n",&arr1[0]);
    	printf("%d\n",*arr1);
    	printf("%d\n",arr1[0]);
    	printf("%d\n",arr1 + 1);
    	printf("%d\n",arr1[1]);
    	printf("%d\n",*(arr1 + 1));
    
    	int arr2[5] = {1,2,3,4,5};
    	printf("%d\n",arr2);
    	printf("%d\n",arr2 + 1);
    	printf("%d\n",*(arr2 + 1));
    	printf("%d\n",arr2[1]);
    	return 0;
    }

    二维数组

    • 二维数组就是每个元素都是一维数组,即arr[0],arr[1]都是数组
    • arr[0]表示第一个数组的首地址,arr[1]是第二个数组的首地址
    • 同理arr和arr[0]是一样的;*(arr + 1)和arr[1]是一样的
    • *(arr[0]+1)表示arr[0][1]
    • *(*(arr+1)+1)等价于*(arr[1]+1)等价于arr[1][1]

    例证:

    #include<stdio.h>
    
    int main(void)
    {
    	int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
    	printf("%d\n",arr);
    	printf("%d\n",arr + 1);
    	printf("%d\n",*(*arr + 1));
    	printf("%d\n",*(arr[0] + 1));
    	printf("%d\n",*(*(arr+1) + 1));
    	printf("%d\n",*(arr[1] + 1));
    	return 0;
    }

    数组的存储结构

    一维数组

    数组都是顺序存储的,一个挨着一个,比如int a[5] = {1,2,3,4,5}。int占四个字节,a[0]和a[1]连续,因此差4个字节。根据等差数列通项公式,有

    Loc(a[i]) = Loc(a[j]) + (i-j)*size

    二维数组

    二维数组也是顺序存储的,但是可以按照行存储,也可以按照列存储。算法和上面类似,主要是看差距多少个元素。比如数组a[3][5],那么a[1][1]和a[2][3]差距多少呢?如果按照行存储,也就是一行一行存,那么差2-1=1行,一行5个数,在加上3-1=2,共差7个元素,所以a[2][3]地址等于a[1][1]地址加上7乘以元素size

    特殊矩阵压缩存储

    • 对称矩阵:用一维数组只存放上三角或者下三角矩阵
    • 上三角矩阵或下三角矩阵:用一维数组存
    • 三对角矩阵:一维数组存
    • 稀疏矩阵:用三元组(行标,列号,数值)外加(总行数,总列数,非零元素个数)存

    对称矩阵

    对于一个对称矩阵,假设张下面这样

    因为是对称的,所以只存上三角或者下三角就够了,原来一共n*n个元素,用一维数组存只需要1+2+3+4+...+n个元素就够了。

    假设存下三角区域,那么第i行第j列是一维数组中第几个元素呢?

    第i行第j列(i>=j),1+2+3+4+...+(i-1)+j

    可以这么想,第i行第j列前边有几个元素?第一行1个,第二行2个,第i行第j列,前边有i-1行,所以前边有1+2+3+...(i-1)个,再看本行,前边有j-1个,所以这个元素前边有1+2+3+4+...+(i-1)+j-1个元素,所以这个元素是第1+2+3+4+...+(i-1)+j个,如果数组是从0开始,那么下标就是1+2+3+4+...+(i-1)+j-1,那么i<=j的时候就把i和j交换下就行。

    下三角矩阵

    计算方法和上面类似,一维数组长度是(1+2+3+4+...+n)+1,为啥要加1,因为三角矩阵另一个角是个常数(一般是0,当然也可以是别的)。同理,i>=j时,第i行第j列前边共有1+2+3+4+...+(i-1)+j-1个元素,所以这个元素是第1+2+3+4+...+(i-1)+j个,当i<j时,即上三角区域时,就存放到最后,即第(1+2+3+4+...+n)+1个元素。

    上三角矩阵

    上三角和上面类似,一维数组长度仍然是(1+2+3+4+...+n)+1,只是第一行有n个,第2行有n-1个,第i行有n-i+1个,当i<=j时,前边有[n+(n-1)+(n-2)+...+(n-(i-1)+1)]+(j-i)个元素,所以这个元素是第[n+(n-1)+(n-2)+...+(n-(i-1)+1)]+(j-i)+1个。当i>j时,即是下三角区域,就存到最后,即第(1+2+3+4+...+n)+1个元素。

    稀疏矩阵

    对于稀疏矩阵(大多数元素是0的),只存储非零元素,比如这个矩阵就是这么存的。

    当然,还要存储数组的行数,列数和非零元素个数,如下

    三对角矩阵

    三对角矩阵长这样子:

    只存储主对角线及其上、下两侧次对角线上的元素,其他的零元素一律不存储。对一个n*n的三对角方阵A,元素总数有n*n个,而其中非零的元素共有3*n-2个。因此,存储三对角矩阵时最多只需存储3*n-2个元素。

    这个不是很好找规律,由于是线性的,可以用待定系数法求出。

    展开全文
  • 而今天数据结构老师讲解c数组时,讲到数组我发现用上面结构根本无法带入进去,原来是因为c语言中整个数组都是在栈当中,而多维数组虽然在逻辑结构上是多维,但是在存储结构上依旧是一维数组,这种存储结构...

    之前学习Java时了解到的多维数组的存储是:
    引用在栈当中,而数组则在堆当中,如下图所示

    而今天数据结构老师讲解c的数组时,讲到的数组我发现用上面的结构根本无法带入进去,原来是因为c语言中整个数组都是在栈当中的,而多维数组虽然在逻辑结构上是多维的,但是在存储结构上依旧是一维数组,这种存储结构如下图所示
    在这里插入图片描述

    其实这两者就是下图中的Way 1 和 Way 2 了。Way 1 就是java所采用的存储方式,这个”数组的数组“的描述就很贴切。需要注意的是如果在c语言中使用动态内存分配去使用数组,采用的也是 way 1 的这种方式。而c语言的数组就是 Way 2 这种存储方式。从上面的两张图其实很容易就能够看出这两者的区别,Way 1 相对于 Way 2 来说,增加堆内最上方的那个一维数组,这个一维数组内存储的其实就是下方各个一维数组的地址。而Way 2 则没有这个一维数组,所谓的二维其实就是一个一维数组,通过计算可以得到想要下标的空间内存储的值。
    在这里插入图片描述

    展开全文
  • 一维数组即为线性表, 而二维数组可以定义为“其数据元素为一维数组(线性表)”的线性表。依此类推, 即可得到多维数组的定义。 以二维数组为例,如下图所示。 可以把二维数组看成是一个线性表: A =(α1 ,α2 ,…,αn),...
  • 文章目录指针数组,数组指针,二维数组,二级指针答案答案论证必备知识存储结构...2》数组指针 = = 不需要用(完全可用一维数组和一级指针代替) (*b)[0] 不等于 *b[0],需要用其特有数组指针方式输出 答案论证
  • 多维数组的定义和存储

    千次阅读 2015-08-14 00:47:54
    多维数组广义表是一种... 一维数组(向量)是存储于计算机的连续存储空间中的多个具有统一类型的数据元素。  同一数组的不同元素通过不同的下标标识。  (a1,a2,…,an) 2、二维数组  二维数组Amn可视为由
  • 数据结构之——数组

    2020-07-31 12:06:43
    一维数组的逻辑结构是线性表,多维数组是线性表的拓展。下面就让我们以二维数组为例,说明多维数组的逻辑结构、遍历和存储结构。 1.二维数组的逻辑结构 二维数组是一维数组的扩展,二维数组是“元素为一维数组”的一...
  • 特殊矩阵压缩存储 数组  数组可以看作线性表推广。数组作为一种数据结构其特点是结构元素本身可以是具有某种结构的数据,但属于同一数据类型,数组是一个具有固定格式数量数据有序集,...一维数组即为...
  • 安徽理工大学 第5章 数组和广义表 本章学习导读 数组与广义表可视为线性表的推广其特点是数据元素仍然是个表本章重点讨论二维数组的逻辑结构和存储结构特殊矩阵矩阵的压缩存储以及广义表的逻辑结构和存储结构等 ...
  • 数组

    2019-10-26 15:54:38
    文章目录数组的定义初始化一维数组的定义一维数组的初始化一维数组的访问一维数组的赋值使两个数组值相等数组的逻辑存储结构一维数组:一个下标确定;二维数组:两个下标确定数组的物理存储结构二维数组的定义与...
  • 数据结构(Java)--数组和矩阵

    千次阅读 2017-07-02 18:25:45
     一维数组的逻辑结构是线性表  多维数组是线性表的扩展  2.一维数组  一维数组采用顺序存储结构数组通过下标识别元素,元素地址是下标的线性函数数组是随机存取结构数组一旦创建,其所占据的存储...
  • 通常我们根据不同的结构特性将数组分为三类:一维数组,二维数组多维数组(存储(n-1)维数组的数组,不做过多讨论) 本节中我们主要针对一维数组进行详细讲解,分析数组的应用场景,使用方法及其优缺点。 一维...
  • 数据结构--多维数组

    2020-12-30 22:37:50
    逻辑结构上看,多维数组可以认为是一维数组的扩展,从物理结构上看,一维数组是多维数组的特例。 我本人是这样构想的,比如看待二维数组:一维数组中的每个元素都是一维数组。 多维数组的逻辑特征是:一个元素...
  • ② 从逻辑结构上看,数组可以看成是一般线性表扩充。 二维数组视作线性表 ① 把矩阵Am×n看成n个列向量线性表: A=(α1,α2…αj…αn), αj=(a1j,a2j, …,amj),(1 ≤ j ≤ n)本身也是个线性表,称为列向量。 ...
  • [数据结构]非线性结构——多维数组

    千次阅读 2015-07-09 21:25:51
    多维数组广义表是一种复杂的非线性结构,它们的逻辑特征是:一个数据元素可能有多个直接前驱多个直接后继。 多维数组 1、一维数组(向量)——常用数据类型 一维数组(向量)是存储于计算机的连续存储空间中的...
  • 这里讨论多维数组的逻辑结构和存储结构,特殊矩阵和矩阵的压缩存储,广义表的逻辑结构、存储结构和基本运算。 8.2.1 数组 1、数组的定义及基本运算 1)数组的定义 数组是定义长线性表在数上...
  • 数组和链表区别

    2020-07-08 19:21:21
    链表: 链表是物理存储结构上非连续,非顺序的存储结构,数据元素的逻辑结构通过链表中的指针连接次序实现。 类型: 1.单向,双向 2.带头,不带头 3.循环,非循环 区别 (联系: 线性表分为顺序表
  • 线性结构就是把所有结点用一根直线穿起来,常用线性结构有:线性表,栈,队列,循环队列,一维数组。线性表中包括顺序表、链表等,其中,栈队列只是属于逻辑概念,实际中不存在,仅仅是一种思想,一种理念...
  • 一维数组即为线性表,二维数组可以看作是元素为一维数组的(线性表的)线性表,以此类推n维数组为元素为n-1维数组的线性表。 行主映射列主映射 数组的应用需要我们将数组元素序列化,即按一维数组排列 。令n是一...
  • 5.1 多维数组

    2015-05-16 14:12:00
    本章讨论多维数组的逻辑结构和存储结构、特殊矩阵、矩阵的压缩存储、广义表的逻辑结构和存储结构等。 5.1.1 数组的逻辑结构 数组是我们很熟悉的种数据结构,它可以看作线性表的推广。数组作为种数据结构其...
  • 非线性结构-多维数组

    2014-08-18 15:18:08
     一维数组(向量)是存储于计算机的连续存储空间中的多个具有统一类型的数据元素。  同一数组的不同元素通过不同的下标标识。 (a1,a2,…,an) 2、二维数组  二维数组Amn可视为由m个行向量组成的向量,或由n...
  • 顺序存储结构特点:数据元素的存储对应一块连续的存储空间,数据元素之间的前驱后续关系...java中是以一维数组和对象的引用的基础上去讨论实现数据的存储结构。 线性表和数组的逻辑结构是不一样的:线性表是数据...
  • 【数据结构数组

    2016-06-25 22:09:06
    一 数组的创建方式 数组是表数据结构的一种实现方式,具有以下基本特性: 1)数组元素按顺序存储。 2)元素下标从0开始,而非人为逻辑的从1开始。... * 一维数组的创建使用 * @author yihong...
  • 1,数组的逻辑结构定义,特点; (1)数组一旦被定义,它的维界就不再改变。 (2)除了结构的初始化销毁之外,数组只有存取元素修改元素值的操作。 2,数据的存储结构;数组的顺序表示实现 类型...
  • 链表和数组的区别

    2010-10-14 22:22:52
    链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。...数组有一维数组和多维数组(数组的数组、数组的数组的数组.....) 。       数组链表的...
  • 4.1多维数组

    2017-08-14 10:37:05
    一维数组的数据存储按照顺序存储逻辑地址物理地址都是连续的。 二维数组在顺序存储时一般有两种: 行优先顺序:存储是先按行从小到大的顺序存储,在每一行中按列号从小到大存储 列优先顺序:存储
  • 多维数组的地址转换

    千次阅读 2014-11-05 13:05:31
     多维数组广义表是一种复杂... 一维数组(向量)是存储于计算机的连续存储空间中的多个具有统一类型的数据元素。  同一数组的不同元素通过不同的下标标识。  (a1,a2,…,an) 2、二维数组  二维数组Amn
  • 数据结构中线性结构也就是“线性表”是逻辑结构,现在可以肯定栈与队列都是存储结构,栈与队列都是线性表,顺序表链表也是线性表,一维数组和顺序表又基本上是一回事,那么顺序表链表也是存储结构吗?...
  • 多维数组

    2016-05-25 17:35:00
     一维数组(向量)是存储于计算机的连续存储空间中的多个具有统一类型的数据元素。 同一数组的不同元素通过不同的下标标识。 (a1,a2,…,an) 2、二维数组  二维数组Amn可视为由m个行向量组成的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 382
精华内容 152
关键字:

一维数组的逻辑结构和存储结构