登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[学习笔记] C语言之指针二(二维数组)

[复制链接]
发表于 2018-2-4 18:45:09 | 显示全部楼层 |阅读模式
学习笔记
学习科目: C语言之指针二(二维数组)
学习安排: 针对昨天继续补充的指针与数组,打算明天说一下指向指针的指针。周一周二会发表函数的内容到时候补充指针系列第三块(指针变量作函数参数)
开始时间: 2018-02-03
结束时间: 2018-02-04
本帖最后由 ryop123 于 2018-2-4 18:45 编辑

昨天写了指针的简单理解和一维数组与指针C语言之指针一 附链接
http://bbs.hpuedd.com/forum.php?mod=viewthread&tid=1295&fromuid=633
(出处: 电开社区)
今天来聊聊二维数组
1.二维数组在内存中的布局
      一般我们都会把二维数组看做是排列在一张表格中的一行行的一维数组,但是事实上系统是决不允许程序按照这样的方式存储数据的。单个元素的存储和引用实际上是以线性的方式排列在内存中的。
      数组下标操作符在C中是内置操作符,它的规则告诉我们如何去解析int p和int a[j],实际上编译器会将数组的下标解析为解引用(*)操作符。例如:int p解析为"*(p+i)",即首地址为p的第i个元素;int a[j]解析为“*(*(a+i)+j)",例如在一个二维数组a[3][2],我们要定义一个 int (*p) [2]的指针。首先我们来分析一下这个指针的类型。它也等价于这种形式:int [2] *p。意思是定义一个指向两个int类型变量的指针。当你学了结构体,你就对这种数据类型的定义方式不陌生了。但没有学过结构体,(函数发表完后我会写写结构体)就有点抽象了。我先举个简单的例子:例如我定义一个数组int a[10],其实它也可以表示成另一种形式:int [10] a。意思是定义一个变量a,它是int [10]类型的,即它是一个拥有10个int变量长度的变量,即是数组。那对于二维数组a[3][2],为什么要定义一个指向两个int变量的指针呢?按照前面对一维数组的分析,我们可以把这个二维数组看作是三个数组,每个数组有两个元素。指向该二维数组的指针在进行移动时,它指向的是一整个数组,即两个int类型,所以需要定义int [2] 类型的指针变量。

由此我们可以总结规律,指向二维数组a[j]的指针类型必然是 int [j] *类型。

2.二维数组实例表示

二维数组的行指针类型为int (*p)[N] ;因为[]运算符的优先级比*大,所以必须要有一个括号;要不然写成 int *p[N] ;这就成了一个指针数组了,这个指针数组存储N个指向整型数据的指针。p++操作会使p指向下一行的首地址,这是因为p是行指针,指向的是一行。

敲个代码理解下哈
# include <stdio.h>
int main(void) {
     int   a[4][3] = {{1,2,3},{5,6,7},{0,1,5},{6,7,8}};
     int   (*p) [3];  //因为[]运算符的优先级比*大
     int   i,j;
     p = a;   

            for ( i = 0; i < 4; i++)      
                  for ( j = 0; j < 3; j++)//二维数组用for双循环表示           
    printf ("%d ",* p++);   
    return 0;
}
特别说明:
1.对上述二维数组a,虽然a[0]、a都是数组首地址,但二者指向的对象不同,a[0]是一维数组的名字,它指向的是a[0]数组的首元素,对其进行“*”运算,得到的是一个数组元素值,即a[0]数组首元素值,因此,*a[0]与a[0][0]是同一个值;而a是一个二维数组的名字,它指向的是它所属元素的首元素,它的每一个元素都是一个行数组,因此,它的指针移动单位是“行”,所以a+i指向的是第i个行数组,即指向a。对a进行“*”运算,得到的是一维数组a[0]的首地址,即*a与a[0]是同一个值。当用int *p;定义指针p时,p的指向是一个int型数据,而不是一个地址,因此,用a[0]对p赋值是正确的,而用a对p赋值是错误的。这一点请读者务必注意。
2. 用二维数组名作地址表示数组元素。
另外,由上述说明,我们还可以得到二维数组元素的一种表示方法:
对于二维数组a,其a[0]数组由a指向,a[1]数组则由a+1指向,a[2]数组由a+2指向,以此类推。因此,*a与a[0]等价、*(a+1)与a[1]等价、*(a+2)与a[2]等价,┅,即对于a数组,由*(a+i)指向。由此,对于数组元素a[j],用数组名a的表示形式为:*(*(a+i)+j)指向该元素的指针为:*(a+i)+j

举例:
若有二维数组:a[x][y],则有:
(1)a=&a[0]
(2)a[0]=&a[0][0]=*a
(3)&a=整个二维数组的起始地址
(4)a+1=&a[0]+1=a[1]=&a[1][0]
(5)a[0]+1=&a[0][0]+1=&a[0][1]
总之&a[x][y]就是第x行y列的元素的地址
附加:不要用**p表示以前一直有种误解:二维数组的是数组的数组,所以数组的首地址是指向第一个元素指针,而这个元素又是一个数组,所以把数组首地址理解为指向指针的指针。一定一定记住一点, 指针和变量一样,也是有地址的,只不过变量的值被解释成一个值,而指针的值被解释成一个地址。

啊哦,其实这块学的迷迷糊糊的,以上内容皆为本人观点,欢迎大家提出批评和指导,我们一起探讨!大家有什么见解之类的欢迎留言
吃饭啦土豆白






好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表