二维数组中的指针类型(行指针和列指针)

1.二维数组在内存中的布局

一般我们都会把二维数组看做是排列在一张表格中的一行行的一维数组,但是事实上系统是决不允许程序按照这样的方式存储数据的。单个元素的存储和引用实际上是以线性的方式排列在内存中的。

数组下标操作符在C中是内置操作符,它的规则告诉我们如何去解析int p[i]和int a[i][j],实际上编译器会将数组的下标解析为解引用()操作符。例如:int p[i]解析为”(p+i)”,即首地址为p的第i个元素;int a[i][j]解析为“((a+i)+j)”,例如在一个二维数组int a[3][4] ;中,a[i][j]在内存中的地址为a+4*i+j+1,即相对于首地址a的线性偏移为4*i+j+1。

2.行指针与列指针

define N 4 ; // N为这个二维数组中每一行的元素书目。

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

p++操作会使p指向下一行的首地址,这是因为p是行指针,指向的是一行。我们可以用sizeof(*p)测试p指向的内容的大小:

    int (*p) [3] ;
    printf("%d\n" , sizeof(*p) ) ;

在32位系统,vc 6.0下运行结果为:12 。

那么我们可以知道列指针指向的内容一共是一行,一行3个int类型的数据,一共12个字节。所以p++跳跃的大小为一行就不奇怪了,因为指针的加1实质上加的是该指针指向的数据类型的大小。例如:char * p ; p+操作会使p移动一个char类型大小(2个字节)。类推可以有进一步的理解。罗嗦了。。。

那么定义的int (*p)[3] ;的p指针到底是个什么类型的指针呢?

首先从p开始,先与*结合,那么p是一个指针,再与[]结合,说明指针指向的内容是一个数组,然后与int结合,说明数组里的元素的类型是int型,所以p是一个指向元素为整型的数组的指针。

关于行指针的操作:

    int a[3][3] = { 1,2,3,4,5,6,7,8,9 } ;


    int (*p) [3] ;   // **p是一个指向有4个元素的一维数组,可以视为是一个行指针**
    int s = 0 ;
    int i ;
    int k = 0 ;

    for( p = a ; p < a + 3 ; p++ )
    {
        for( i = 0 ; i < k  ; i++ )
        {
            s += (*p)[i] ;
        }
        i =  0 ;
        k++ ;
    }

    printf("%d\n" , s ) ;

这段代码输出的是这个3*3矩阵的下三角数据之和。自己结合以上说明体会一下。

**int *q = a[0] ;
那么q就是一个列指针,这个列指针指向的元素是一个整型,q++操作会使q指针移动一个int大小的距离,也就是移动一列,故曰列指针。**

    int a[3][3] = { 1,2,3,4,5,6,7,8,9 } ;

        int s = 0 ;
    for( int * p = a[0] ; p < a[0] + 9 ; p++ )
    {
        s += *p  ;
    }

    printf("%d\n" , s ) ;

这段代码执行的操作是输出这个3*3矩阵所有元素的代码之和。

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值