1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > C程序设计语言现代方法12:指针和数组

C程序设计语言现代方法12:指针和数组

时间:2022-02-21 18:14:11

相关推荐

C程序设计语言现代方法12:指针和数组

目录

1. 指针的算术运算

1.1 概述

1.2 C语言支持的算术运算类型

2. 指针的比较

3. 指针用于数组处理

4. 数组名与指针

4.1 用数组名作指针

4.2 数组取下标操作

4.3 惯用法

4.4 数组型实际参数

4.5 用指针作数组名

5. 指针和多维数组

5.1 正确理解二维数组的数组名

5.1.1 数组名可以被解释为指向数组第一个元素的指针

5.1.2 如果p指向对象x,那么*p就是对象x

5.1.3 如果x 是对象,那么&x得到指向该对象的指针

5.1.4 指针的算术计算以其指向的对象类型为单位

5.2 二维数组的降维处理

1. 指针的算术运算

1.1 概述

当指针指向数组元素时,C语言允许对指针进行算术运算(加法和减法)。通过这种运算可以用指针代替数组下标对数组进行访问

1.2 C语言支持的算术运算类型

C语言只支持3种格式的指针算术运算

① 指针加上整数

p 指向a[i],p + j 指向a[i + j]

② 指针减去整数

p 指向a[i],p - j 指向a[i - j]

③ 两个指针相减

当两个指针相减时,结果为指针之间的距离(用数组元素的个数来度量)

显然,只有两个指针指向同一个数组时,把他们相减才有意义

说明:这里需要强调,C语言只支持这3种运算,其余均报错。请看如下示例,

由于不能将两个指针相加,上述方法是不能取得数组中间位置元素的。需要做如下改进,

2. 指针的比较

只有在两个指针指向同一数组时,用关系运算符进行的指针比较才有意义,一般用于for循环遍历数组时

3. 指针用于数组处理

在用指针处理数组元素的语句中经常组合使用*(间接寻址)运算符和++运算符

4. 数组名与指针

4.1 用数组名作指针

可以用数组名作为指向数组第一个元素的指针

说明1:数组名被解释为指针常量,本质是因为系统没有为数组名分配存储空间。所以如下的代码是错误的,

int a[10];++a; // 错误!!!

说明2:从技术上说,数组的名字不是指针,C语言编译器会在需要的时候(表达式中的数组名)把数组名转换为指针

区别示例:对数组名用sizeof运算符和对指针用sizeof运算符

4.2 数组取下标操作

通常情况下,a + i 等同于&a[i],*(a + i)等价于a[i]

说明:数组的取下标操作可以看成是指针算术运算的一种形式,所以a[i] 和i[a] 是一样的

// 中间转换,像普通加法一样,指针和整数相加也是可交换的a[i] <---> *(a + i) <---> *(i + a) <---> i[a]

4.3 惯用法

for (p = a; p < a + N; ++p)sum += *p;

4.4 数组型实际参数

数组型实际参数的关键是没有复制数组本身

① 给函数传递数组所需的时间与数组的大小无关(因为只传递了地址值)

② 可以把数组型形式参数声明为指针

int find_largest(int a[], int n);int find_largest(int *a, int n);

特别注意:对于形式参数,声明为数组跟声明为指针是一样的,但是对变量而言,声明为数组跟声明为指针是不同的,示例如下,

int a[10];int *a;

③ 可以给形式参数为数组的函数传递数组的"片段",所谓片段是指连续的数组元素组成的序列。也就是说,在find_largest函数中,第一个参数指定的是要处理的数组元素的起始地址,第二个参数指定的是要处理的数组元素个数

4.5 用指针作数组名

int a[10];int *p = a;p[1] = 0;

本质:数组取下标只是一种地址计算方式

5. 指针和多维数组

5.1 正确理解二维数组的数组名

设有int a[NUM_ROWS][NUM_COLS];

我们结合上一章节中总结的指针变量4句圣经来解释二维数组的数组名

5.1.1 数组名可以被解释为指向数组第一个元素的指针

二维数组的元素是一维数组,所以二维数组名指向二维数组的第一行。其指针基类型为int (*)[NUM_COLS],在对其进行算术运算时,单位为一行

5.1.2 如果p指向对象x,那么*p就是对象x

因为二维数组的数组名a 指向其中的第一个一维数组,即指向第一行。所以*a 就是第一行这个一维数组,又因为一位数组名解释为指向其第一个元素的指针,所以*a 的类型为int *。考虑到*(a + i) 和a[i] 都是等价的地址计算方式,所以*(a + i) 和a[i] 均表示第i 行一维数组,类型均为int *

实验时间:为什么说*a 就是一维数组而不是一个简单的指针变量?

我们通过sizeof 运算符作用于数组名和指针变量时的不同行为来验证

sizeof(*a) 的结果是12 而不是4,正说明*a 表示的是一个一维数组名,而不是一个简单指针

5.1.3 如果x 是对象,那么&x得到指向该对象的指针

因为*(a + i) 和a[i] 均表示第i 行一维数组,所以&*(a + i) 和&a[i] 均为指向第i 行一维数组的指针,其类型为int (*) [NUM_COL]

5.1.4 指针的算术计算以其指向的对象类型为单位

a:指向二维数组的第一行一维数组,类型int (*)[NUM_COLS]

a[0] 或*a:指向第一行一维数组的第一个元素,类型为int *

在进行算术计算时, a + 1 越过一行,而a[0] + 1 越过一个int 型数据

5.2 二维数组的降维处理

处理一维数组的函数也可以处理二维数组的一行,进而扩展了这类函数的使用范围

设有int find_largest(int *a, int n)函数,用于求得一维数组中的最大元素,如果想求二维数组中的最大元素,可做如下调用,

find_largest(*a, NUM_ROWS * NUM_COLS);

本质:*a指针类型为int *

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。