C语言指针操作(三)通过指针引用数组 指针操作系列文章: C语言指针操作(一)地址,指针,指针变量是什么 C语言指针操作(二)指针变量作为函数参数 C语言指针操作(三)通过指针引用数组 C语言指针操作(四)用数组名作函数参数 C语言指针操作(五)通过指针引用多维数组 C语言指针操作(六)通过指针引用字符串 C语言指针操作(七)指向函数的指针 C语言指针操作(八)返回指针值的函数 C语言指针操作(九)指针数组和多重指针 C语言指针操作(十)动态内存分配与指向它的指针变量 C语言指针操作(十一)有关指针的小结 通过指针引用数组的几种方法的原理和差异;以及利用指针引用数组素的技巧 关于地址,指针,指针变量可以参考这篇文章: C语言指针操作(一)地址,指针,指针变量是什么 关于指针变量作为函数参数可以参考这篇文章: C语言指针操作(二)指针变量作为函数参数 目录 一、数组素的指针 1.1引入 1.2实例 二、在引用数组素时指针的运算 2.1引入 2.2实例 2.3详细说明 三、通过指针引用数组素 3.1引入 3.2举例说明 3.3拓展 一、数组素的指针 1.1引入 一个数组包含若干素,每个数组素都占用存储单,所以他们都有相应的地址,所谓数组素的指针就是数组素的地址。 1.2实例 下面用指针变量指向一个数组素 以上是将指针变量 p 指向 a 数组的第 0 号素。
引用数组素可以使用下标法,也可以使用指针法,即通过指向数组素的指针找到所需的素,使用指针法能使目标程序质量高(占内存少,运行速度快)。 在 C 语言中,数组名(不包含形参数组名)代表数组中首素(即序号为 0 的素)的地址,所以下面两个语句等价 注意:数组名不代表整个数组,只代表数组首素的地址。 二、在引用数组素时指针的运算 2.1引入 可以对数值型数据进行算数运算,那么可以对指针型数据进行算数运算吗?指针就是地址,显然对地址进行乘和除是没有意义的,只有在一定条件下进行的加和减才有意义。 当指针指向数组素的时候,能够对指针进行加和减运算;例如指针变量 p 指向数组素 a[0],则 p+1表示指向下一个数组素 a[1]。 2.2实例 在指针已指向一个数组素时,可以对指针进行以下运算: ①加一个整数( p + i ),如 p += 1; ②减一个整数( p – i ),如 p -= 1; ③自加运算,如 p++ ④自减运算,如 p– ⑤两个指针相减,如 p1 – p2 (只有p1和p2都指向同一个数组中的素时才有意义) 2.3详细说明 (1)如果指针变量 p 已指向数组中的一个素,则 p+1 指向同一数组中的下一个素,p-1 指向同一数组中的上一个素。执行 p+1 时并不是将 p 的值(地址)简单地加 1 ,而是加上一个数组素所占用的字节数。例如,数组素是 float 型,每个素占4个字节,则 p+1 意味着使 p 的值(地址)加4个字节,以使它指向下一素。p+1所代表的地址实际上是 p+1×d ,d 是一个数组素所占的字节数(在Visual C++ 中,对 int 型,d=4;对 float 和 long 型,d=4;对 char 型,d=1 )。若 p 的值是2000,则 p+1的值不是2001,而是2004。 那么系统怎么知道要把这个 1 转换为 4,然后与 p 的值相加呢?因为在定义指针变量时必须要指定基类型,如:float* p。 (2)如果 p 的初值为 &a[0],则 p+i 和 a+i 就是数组素 a[i] 的地址,或者说,它们指向 a 数组序号为 i 的素。 a 代表数组首素的地址,a+1 也是地址,它的计算方法同 p+1 ,实际地址为 a+1× d。例如,p+9 和 a+9 的值是 &a[9],它指向a[9]。
(3)*(p+i) 或 *(a+i) 是 p+i 或 a+i 所指向的数组素,即 a[i],例如 *(p+5),*(a+5) 和 a[5] 三者等价,实际上,在编译时,对数组素 a[i] 就是按 *(a+i) 处理的,即按数组首素的地址加上相对位移量得到要找素的地址,然后取出存储单中的内容。 [ ]实际上是变址运算符,即将 a[i] 按 a+i 计算地址,然后找出此地址单中的值。 (4)如果指针变量 p1 和 p2 都指向同一数组中的素,如执行 p2 – p1,结果是 p2 – p1 的值(两个地址之差)除以该数组素类型所占的字节长度。假设,p2 指向实型数组素 a[5],p2 的值为2020;p1 指向 a[3],其值为2012,则 p2-p1 的结果是 (2020-2012)/4 = 2 。这个结果是有意义的,表示 p1 所指向的素与 p2 所指的素之间差 2 个素。这样就不需要具体地知道p1和 p2的值,然后去计算它们的相对位置,而是直接用 p2-p1 就可知道它们所指素的相对距离。 两个地址不能相加,如 p1+p2 是无实际意义的。 三、通过指针引用数组素 3.1引入 引用数组素,存在下面两种方法: ①下标法,如 a[i] ; ②指针法(数组名法和指针变量法),如 *(a+i) 或 *(p+i) ,其中 a 是数组名,p 是指向数组素的指针变量,其初值为 p=a; 3.2举例说明 有一个整型数组 a,有10个素,要求输出数组的全部素 (1)下标法 (2)通过数组名和素序号计算数组素的地址 (3)用指针变量指向数组素 三种方法的比较: ①第(1)和第(2)种方法的执行效率是相同的,编译系统将 a[i] 转换为 *a[i+1] 处理的,第(3)种方法比前面两种更快,用指针直接指向素,不必每次都重新计算地址,大大提高执行效率。 ②用下标法比较直观,能直接知道是第几个素;用地址法或指针变量的方法不直观,难以很快的判断出当前处理的是哪一个素。 需要注意的是:不能通过改变数组名a的方式(例如:a++ )来改变所指向的变量,因为 a 代表的是数组首素的地址,他是一个指针型常量,它的值是固定不变的。 3.3拓展 (1)指向数组素的指针变量也可以带下标,如 p[i] ;因为程序在编译时,对下标的处理方法是转换为地址,p[i] 处理成 *(p+i) ,需要注意的是此时 p[i] 的指向,若 p 指向 a[0],则 p[2] 代表 a[2],若 p[i] 指向 a[3],则 p[2] 代表 a[5],建议少用,容易出错。 (2)利用指针引用数组素,比较灵活方便,可以使用一些技巧使程序更加简洁。 ① *p++ :由于++和 * 同优先级,结合方向为自右而左,因此它等价于 *(p++),即先引用p的值,实现 *p 的运算,然后再使 p 自加1。
② *(p++) 和 *(++p) 的作用不相同,前者先取 *p 的值,然后再自加 1,后者先使 p+1,再取 *p 的值。
后着因为没有定义数组 b 的第 4 个素 b[4],所以指向了一个不确定的位置。 ③ (*p)++ 和 ++(*p) 作用不相同,但都是先得到 (*p) 所指向素的值,前者先把 (*p) 所指向的素值作为表达式的值后,再自加 1;后着是自加 1 后再作为表达式的值。但需要注意的是:他们都是使 p 所指向的素加 1 ,而不是使指针 p 的值加 1 。
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/43329.html