精华篇:数组指针

精华篇:数组指针一.数组指针1.定义:数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。例:int(*p)[10];p即为指向数组的指针,又称数组指针。2.特性:…

大家好,又见面了,我是你们的朋友全栈君。

一.数组指针

1.定义:

         数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。

         例:int (*p)[10]; p即为指向数组的指针,又称数组指针。

2.特性:

         数组指针用于指向一个数组,其本质为指针;

         ()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长也 就 是说执 行p+1时,p要跨过n个整型数据的长度。

         数组指针也叫行指针

3.二维数组指针:

         int (*p)[5]

         p是一个指针变量,它指向包含5个int元素的一维数组,此时p的增量以它所指向的一维数组长度为单位;

        *(p+i)是一维数组a[i][0]的地址;

        *(p+2)+3表示a[2][3]地址(第一行为0行,第一列为0列),*(*(p+2)+3)表示a[2][3]的值。

4.用法用例:

(1).一维数组指针

#include<stdio.h>

int main(){
    
    int a[12] = {10,20,30,40,50,60,70,80,90,100,110,120};
    
    int (*p_array)[12] = &a;                //指向一维数组的数组指针
                                            //a 是一个int [12] 类型的数组, 取它的地址初始化p_array. 值得注意的是此时数组名array不再表示数组首元素的地址.
    int *p = a;                                //指向一维数组元素的指针
    
    printf(“%d\n”,p[0]);
    printf(“%d\n”,*p_array[0]);
    
    printf(“%d\n”,a[1]);
    printf(“%d\n”,*(p + 1));
    printf(“%d\n”,p[1]);
    printf(“%d\n”,(*p_array)[1]);    
    printf(“%d\n”,p_array[0][1]);    
                                            /*
                                            (1) 二维数组实际上就是元素为一维数组的数组
                                            (2) 二维数组名可以看做指向其第一个元素(一维数组)的指针
                                            (3) 现在我们将array看作一个只有一个元素的二维数组,
                                            并且该二维数组的元素是 int [5] 类型的,
                                            显然arrayptr指向了该二维数组的第一个元素(相当于二维数组名)
                                            所以我们可以通过下标运算符 arrayptr[0]
                                            获得二维数组的第一个元素(实际上就是array数组),
                                            然后再次利用下标运算符 arrayptr[0][0] 获取array数组的第一个元素.
                                            注意到无法使用 arrayptr[1]是错误的, 因为该二维数组只有一个元素.
                                            */
    
    return 0;
}

 

<span role="heading" aria-level="2">精华篇:数组指针

(2).二维数组指针

#include<stdio.h>

int main(){
    
    int a[3][4] = {10,20,30,40,50,60,70,80,90,100,110,120};
    
    printf(“%d\n”,a[0][1]);
    int (*p_array)[4] = a;                //指向一维数组的数组指针 ,此时p_array指向的是a数组的第一个元素(元素是数组)
                                        //等价与 int* p_array = &a[0]
    printf(“%d\n”,p_array[0][1]);       //同理,p_array【0】指向的是 a[0][]这个数组
    printf(“%d\n”,(*p_array)[1]);       //[]的优先级要比*要高,所以要加括号
                                        /*在一维数组中,
                                        数组名表示的是数组第一个元素的地址,
                                        那么二维数组呢?
                                        a 表示的是元素 a[0][0] 的地址吗?
                                        不是!我们说过,二维数组就是一维数组,
                                        二维数组 a[3][4] 就是有三个元素 a[0]、a[1]、a[2] 的一维数组,
                                        所以数组 a 的第一个元素不是 a[0][0],
                                        而是 a[0],所以数组名 a 表示的不是元素 a[0][0] 的地址,而
                                        是 a[0] 的地址*/
                                        
    printf(“%d\n”,*((*p_array) + 1));   //a[0][]的地址的下一个地址自然就是a[0][1]了
    
                                        //那么我们要如何访问a[2][1]这个元素呢
                                        
    printf(“%d\n”,a[2][1]);
    printf(“%d\n”,p_array[2][1]);
    printf(“%d\n”,(*p_array)[9]);                        //从p_array[0][0]开始,第十个元素就是a[2][1] (2 * 4 + 2 = 10)
    printf(“%d\n”,*((*p_array) + 9));                     //等价上面的代码
    printf(“%d\n”,p_array[0][9]);                        //等价上面的代码
    printf(“%d\n”,(*(p_array + 2))[1]);                   //注意数组指针是行指针,他得改变是针对一个一维数组改变的
    printf(“%d\n”,*(*(p_array + 2) + 1));                 //*(p_array + 2)他表示的是a[2][0]的地址,它的下一个地址自然就是a[2][1]了
                                                        //从上面的代码中我们可以看得出,访问数组元素,要么用下标法,即[],要么用指针法
    printf(“%d\n”,((p_array + 1)[1])[1]);               //(p_array + 1)[1])等价与p_array[2]
    printf(“%d\n”,((p_array + 1) + 1)[0][1]);             //p_array + 2等价于a[2],第一个[0]位于内层数组标号,
                                                        //还是按行指针加法规则,意思是相对于a[2][]偏移0个行指针,即还是a[2][],
                                                        //第二个下标[1]    是行指针内的元素
    
    printf(“%d\n”,(*((p_array + 1) + 1))[1]);             //因为是行指针,所以最内层的p_array每加一按一个数组的长度加(即到了第三个数组,下标为2)
                                                        //等价与上面代码
    
    
    return 0;
}

 

<span role="heading" aria-level="2">精华篇:数组指针

关于指针数组,我们只需掌握一个规则:

(1).访问数组元素,要么用下标法 [],要么用指针*.

(2).一维数组用一个下标,二维数组用两个下标

(3).指针指向数组元素时,指针表示数组元素的地址,用 * 对这个地址运算就求出了这个地址(即数组元素)的值

(4).指针数组指向二维数组时,因为它本身是个指向数组的指针,所以它的内层每加一,就相当于下一个数组

          如 array[m][n],int (*p)[n] = a

          本来p是指向 a[0][] 这个数组的,*p 本身就相当于a[0],p[0]

          p + 1 就指向了二维数组的分数组的下一个数组,实际是 m + 1,即 p + 1 >> m + 1,*(p + 1) >> a[m + 1]

          而,如果想让数组指针指向当前分数组的下一个元素,我们需要让它的 n + 1

          即 (* p) + 1 == &a[0][1], *((*p) + 1) == a[0][1]

(5),我们回想一下,在

         int a[3][4]   ,int(*p)[4] = a

         中 a 代表 a分数组的第一个数组的地址,即 a >> &a[0],  而a[0] >> &a[0][0]

         所以  a 间接 与 &a[0][0],实际效果是相同的,但我们不能说它们等价,因为等价的意思是符号表达的意义是相同的

         但这里它们意义是不相同的,只能说它们的值相等

         而 我们说过,指针数组是指向数组首地址的指针,所以

         p >> a ,而 a >> &a[0], 所以, p >> &a[0]

         所以很自然的我们能够得出

         p[m] >> a[m], *p >> a[0] >> *a

         *(p + m) >> a[m] >> *(a + m),

         *(*(p + m) + n) >> (*(p + m))[n] >> a[m][n] >> p[m][n]

         <1>.第一步中的m,对于a来说,是a总数组的第m个分数组,

         但对于p来说,它是指指向当前数组的下m个数组的首地址,虽然它们等价,

         但是这实际上是因为沾了(数组内存是连续)的光,如果二维数组的分数组地址是不连续的,

         那么这个结论自然也就不成立,

         所以,即使它们等价,我们还是要理解的它们实际意义的区别

         <2>.从第一步以后的推论,我们可以发现一个重要的事情:

         p >> a

         即,是p的地方,我们就可以换成a

         是a的地方,我们就能换成p

         这是因为

         a 代表 &a[0],  p指向a中第一个分数组的首地址,即&a[0],

         注意是数组的首地址,不是数组第一个元素的首地址,即使它们的地址是相同的

         综上所述,虽然 p >> a,而且是完全等价,但是,我们还是要理解它们的区别

         因为对于

         a[m][n], int(*p)[n] = a

         这一切都是 a >> &a[0] 造成的影响

         若写成 p = &a[m], 你还懂么?

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155794.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 示波器的trigger_示波器trigger原理

    示波器的trigger_示波器trigger原理很多时候只进行上述两项调整的话,是能看到一个波形,但这个波形却很不稳定,左右乱颤,相互重叠,导致看不清楚,如图5所示。图5 示波器触发电平调整不当的示意图  这就是因为示波器的触发没有调整好的缘故,那么什么是触发呢?简单点理解,所谓触发就是设定一个基准,让波形的采集和显示都围绕这个基准来。最常用的触发设置是基于电平的(也可基于时间等其它量,道理相同),大家看下上面的几张波形图,在左侧总

    2022年10月12日
  • 关于W25Q128地址的定义

    1.W25Q128将16M的内存分为256个块,每个块是64K;又将一个块分为16个扇区,一个扇区是4K;又将一个扇区分为16个页,一个页是256字节地址。话不多说,上图:2.在图上右边的红框中可以看到Block0(块0)的地址是000000-00FFFF,再看到左边红框中Block0的16个扇区,地址范围对应的就是Block0的地址范围了,第一个扇区的起始地址就是0000,终止地址是0F…

    2022年4月6日
  • 10万字208道Java经典面试题总结(附答案)

    1、JDK和JRE有什么区别?JDK(JavaDevelopmentKit),Java开发工具包JRE(JavaRuntimeEnvironment),Java运行环境JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM,lib就是JVM工作所需要的类库。2、==和equals的区别是什么?对于基本类型,==比较的是值; 对于引用类型,==比较的是地址; equals不能用于基本类型的比较; 如果没有重写equa

    2022年4月9日
  • c语言程序设计和python_c语言和python区别是什么

    c语言程序设计和python_c语言和python区别是什么c语言是编译型语言,经过编译后再运行,执行速度快,不能跨平台,一般用于操作系统,驱动等底层开发。Python大致上可以理解为解释型语言,Python是可以跨平台的,Python高度集成适合于软件的快速开发。c语言和python的区别1、语言类型不同Python是一种动态类型语言,又是强类型语言。它们确定一个变量的类型是在您第一次给它赋值的时候。c是静态类型语言,一种在编译期间就确定数据类型的语言。…

    2022年10月28日
  • IDEA设置JVM运行参数[通俗易懂]

    IDEA设置JVM运行参数[通俗易懂]前言有时候我们需要在程序运行的时候对程序设置环境变量,恰巧我也遇到了这个问题,所以在此记录一下IDEA是如何设置环境变量的。作用-Dproperty=Value该参数通常用于设置系统级全局变量值,如配置文件路径,保证该属性在程序中任何地方都可访问。当然,也可以通过在程序中使用System.setProperty进行设置。注意:…

    2022年10月31日
  • html设置背景音乐循环播放_html背景音乐循环播放

    html设置背景音乐循环播放_html背景音乐循环播放本文实例讲述了js控制网页背景音乐播放与停止的方法。分享给大家供大家参考。具体实现方法如下:js控制背景音乐bgsound的方法(开始与停止)varbg_sound=document.createElement_x(“bgsound”);//创建背景音乐bg_sound.id=”i_bg”//设置id属性document.body.appendChild(bg_sound);//body中添加背…

    2022年9月24日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号