C语言----指针与二维数组(高阶篇三十一)

 

  数组的特殊情况

    ※数组在定义时可以省略下标:

      int ai[]={1,2,3};

    编译器会自动算出此数组在初始化时有3个元素,自动定义成int ai[3]={1,2,3};

 

    这种方法经常用在字符串上:

      char str[]={“string”};

 

    ※二维数组初始化时,只有第一维下标可以省略:

      int ai[][3]={{1,2,3},{4,5,6}};

 

    ※也可以用一维数组的形式初始化二维数组:

      int ai[][3]={1,2,3,4,5,6};

    缺胳膊少腿也行:

      int ai[][3]={1,2,3,4};

    元素ai[1][1]和ai[1][2]会自动初始化为0

 

    ※无论多少维数组,它的内存都连成一片,我们可以用通过指针的移动来指向数组中的任何一个元素。

      int ai[][3]={1,2,3,4,5,6};

      int *pi=&ai[0][0];

      pi+=3;

      这时pi指向ai[1][0];

 

    注意以下写法都是错误的:

      ※int ai[][3]={{1,2,3}{4,5,6}};

      少了中间的逗号

 

      ※int ai[][3]={{1,2,3},{}};

      不能用空花括号初始化,一维数组也一样

 

      ※int ai[0];

      不能定义只有0个元素的数组

 

      ※int ai[3][]={{1,2,3},{4,5,6}};

      除第一维下标外,其它维的下标都不能省略

  二维数组与指针

    在学二维数组与指针之前,我们先回顾下一维数组与指针的关系。   

      a[3]等价于*(a+3)

      a[0]等价于*(a+0)等价于*a

 

   二维数组可当成是“数组的数组”,假设二维数组定义如下:

      int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}}

      a是个数组名,包含3个元素:a[0],a[1],a[2],每个元素又是一个数组,包含4个元素a[0][0],a[0][1],a[0][2],a[0][3]。

 

   从一维数组的知识得知:a[2]相当于*(a+2),但是它只能取到下一维数组的地址,即&a[2][0]。那么如何取到a[1][2]的内容呢?用如下方法:

        *(*(a+1)+2)

      它等价于

        a[1][2]

 

    ※一般在没有&影响的情况下,n维数组中有n个*就会取到数据,小于n个*,只能取到地址。

 

      通过以上表达式,我们可以推出另外几个表达式:

 

        a[0][1]等价于*(*(a+0)+1)等价于*(*a+1)

 

        a[1][0]等价于*(*(a+1)+0)等价于**(a+1)

 

        a[0][0]等价于*(*(a+0)+0)等价于**(a+0)

 

    题目讲解:

      已知数组int x[5][4]={0};中x的地址为0x0AFD0100,求**(x+3)+2、*x+3、*(*(x+3)+2)的地址或值。

      参考答案:2      0x0AFD010C     0

 

      说明:  一、**(x+3)+2相当于*(*(x+3)+0)+2相当于x[3][0]+2=2

 

           二、*x+3 相当于*(x+0)+3相当于x[0]+3相当于x[0][3]的地址&x[0][3],等于0x0AFD0100+3*4等于0x0AFD0100+C=0x0AFD010C。

 

           三、*(*(x+3)+2)相当于x[3][2]=0

 

    程序1

      二维数组与指针的关系

 

// 31-1二维数组与指针的关系.c


#include <stdio.h>

main()
{
    int a[2][3] = { 1,3,5,7,9,11 };    //定义二维数组

    printf("%d \n", &a);   
    printf("%d,%d \n", a, *a);
    printf("%d,%d \n", a[0], *(a + 0));
    printf("%d,%d \n", &a[0], &a[0][0]);
    printf("%d,%d \n", a[1], *(a + 1));
    printf("%d,%d \n", &a[1], a + 1);
    printf("%d,%d \n", &a[1][2], *(*(a + 1) + 2));
    printf("%d,%d \n", a[1][0], *(*(a + 1) + 0));
}

    测试结果:

 

 

  多维数组

    多维数组地址换算

 

 

 

     ※上图分析是通过元素个数来是计算地址:例子

      求  a[1][2][1] 的地址:

      a[1][2][1] =  2116 + (1 * 3 * 2 + 2 *2 + 1) *4 =  2160

    ※内存是线性结构,数组维数再多,也要通过公式转换为线性地址将数据存储在内存中。

 

posted @ 2021-11-06 17:46  httpcc  阅读(376)  评论(0编辑  收藏  举报