• 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

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

  • 相关阅读:
    bootstrap 菜鸟笔记
    OOCSS待解疑惑
    sass 菜鸟笔记
    WOW.js – 让页面滚动更有趣 初学者使用教程
    JAVA8 十大新特性详解
    数据库事务的四大特性以及事务的隔离级别
    java基础--泛型
    java基础之 泛型
    springboot的文件路径,配置文件
    maven使用心得
  • 原文地址:https://www.cnblogs.com/httpcc/p/15514600.html
Copyright © 2020-2023  润新知