二维数组含义,用法总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28090573/article/details/86431357

 由于 int 类型和指针的大小相同,都是4字节,所以会产生理解误导;故尽量选择其他大小的变量,该例使用的是2字节的short

#include<stdio.h>
#include<stdlib.h>

#define N 5

int func1(short a[N][N])
{
    int i,j;
    for(i=0; i<N; i++)
    {
        for(j=0; j<N; j++)
        {
            printf("%4d",a[i][j]);
        }
        printf("\n");
    }

    return 0;
}

/*重点:一个二维数组a[5][4],数组名a代表他的一级成员取地址,详情见PS
*    故a+1的地址向前前进2个字节,遍历其实就是对一个连续内存的逐个遍历
*/
int func2(short *a, int height, int width)
{
    int i=0,j=0;
    printf("_a: %p\n", a);
    printf("_a+1 :%p\n", a+1);
    printf("_a+3 :%p\n", a+3);

    for(i=0; i<height; i++)
    {
        for(j=0; j<width; j++)
        {
            printf("%4d", *(a+i*height+j));
            //printf("%4d", );
        }
        printf("\n");
    }
}
/*重点:一个二维数组a[5][4],数组名a代表他的一级成员取地址,详情见PS
*    单纯传一个二维数组的变量名,传的是一个数组指针,该数组是一个一级成员的地址
*/
int func3(short (*a)[N],int height, int width)
{
    int i=0,j=0;
    printf("_a: %p\n", a);                // 0xbfbd07d6
    printf("_a+1: %p\n", a+1);            // 0xbfbd07e0
    printf("_a+2: %p\n", a+2);            // 0xbfbd07ea
    printf("_a+3: %p\n", a+3);            // 0xbfbd07f4

    printf("_(*(a+1)+1): %p\n", *(a+1)+1); // 0xbfbd07e2
    printf("_(*(a+1)+2): %p\n", *(a+1)+2); // 0xbfbd07e4


    for(i=0; i<height; i++)
    {
        for(j=0; j<width; j++)
        {
            printf("%4d", *(*(a+i)+j));
        }
        printf("\n");
    }
}

int allAndOne(short a[N][N])
{
    int i,j;
    for(i=0; i<N; i++)
    {
        for(j=0; j<N; j++)
        {
            a[i][j]++;
        }
    }
}


int main()
{
    int i,j = 0;
    short a[N][N] = {
        {1,2,3,4,5},
        {6,7,8,9,10},
        {11,12,13,14,15},
        {16,17,18,19,20},
        {21,22,23,24,25}
    };
    printf("===================original array=================\n");
    for(i=0; i<N; i++)
    {
        for(j=0; j<N; j++)
        {
            printf("%4d",a[i][j]);
        }
        printf("\n");
    }
    printf("\nsizeof(a): %d\n", sizeof(a));

    printf("===================func1 array=================\n");
    func1(a);
    printf("===================func2 array=================\n");
    func2(*a,N,N);
    printf("===================func3 array=================\n");
    func3(a,N,N);
    printf("===================out paramter=================\n");
    allAndOne(a);
    func1(a);
}
 

运行结果如下:

===================original array=================
   1   2   3   4   5
   6   7   8   9  10
  11  12  13  14  15
  16  17  18  19  20
  21  22  23  24  25

sizeof(a): 50
===================func1 array=================
   1   2   3   4   5
   6   7   8   9  10
  11  12  13  14  15
  16  17  18  19  20
  21  22  23  24  25
===================func2 array=================
_a: 0xbff53cf6
_a+1 :0xbff53cf8
_a+3 :0xbff53cfc
   1   2   3   4   5
   6   7   8   9  10
  11  12  13  14  15
  16  17  18  19  20
  21  22  23  24  25
===================func3 array=================
_a: 0xbff53cf6
_a+1: 0xbff53d00
_a+2: 0xbff53d0a
_a+3: 0xbff53d14
_(*(a+1)+1): 0xbff53d02
_(*(a+1)+2): 0xbff53d04
   1   2   3   4   5
   6   7   8   9  10
  11  12  13  14  15
  16  17  18  19  20
  21  22  23  24  25
===================out paramter=================
   2   3   4   5   6
   7   8   9  10  11
  12  13  14  15  16
  17  18  19  20  21
  22  23  24  25  26
 

下面从一维数组说起:(定义:int a[4])

(1)一维数组名a是个地址,地址类型为:int *

(2)一维数组名取地址&a是个地址,地址类型同:int (*p)[4], 也即&a指向含4个int元素的一维数组

再看二维数组b[3][4],这个二维数组也可以可以看成一个含3个成员的一维数组,每一个成员含有4个int元素,依次,仿照一维数组的结论,有:

(1)b[0]是个一维数组名,也是个地址,地址类型为:int *

(2)&b[0]是个地址,地址类型同:int (*p)[4], 也即&b[0]指向含4个int元素的一维数组

更进一步:

(3)b是个地址,地址类型同:int (*p)[4],也即b指向含4个int元素的一维数组

(4)&b是个地址,地址类型同:int (*p)[3][4],也即&b指向含3x4个int元素的2维数组

注意:尤其注意上面的(3),这条结论指出了:二维数组名实际上是一维数组的地址!

总结:

① 数组名,是指向它的第一个一级成员的指针

② 数组名取地址,是指向整个数组的指针

PS:所谓一级成员,举个例子,int a[5],那么数组a的一级成员就是int型变量;int b[2][5],数组b的一级成员是int [5]的一维数组

补充一个memcpy复制二维数组的demo:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define H 3
#define W 5

int func1(short a[H][W])
{
    int i,j;
    for(i=0; i<H; i++)
    {   
        for(j=0; j<W; j++)
        {   
            printf("%4d",a[i][j]);
        }   
        printf("\n");
    }   
    return 0;
}


int main()
{
    int i,j;
    short a[H][W] = {0};
    short b[H][W] = {0};
    for(i=0; i<H; i++)
    {
        for(j=0; j<W; j++)
        {
            a[i][j] = i+j;
        }
    }

    printf("===========Array A================\n");
    func1(a);
    printf("===========Array B================\n");
    printf("sizeof(a): %d\n",sizeof(a));
    memcpy(b, a, sizeof(a));
    func1(b);


    return 0;
}
 

运行结果如下:

===========Array A================
   0   1   2   3   4
   1   2   3   4   5
   2   3   4   5   6
===========Array B================
sizeof(a): 30
   0   1   2   3   4
   1   2   3   4   5
   2   3   4   5   6

猜你喜欢

转载自blog.csdn.net/qq_28090573/article/details/86431357