一. 实验内容 (1) 运行以下程序, 并从中了解变量的指针和指针变量的概 念。 (2) 运行以下程序,观察&a[0]、&a[i ]和 p 的变化,然后回答以下问题: 1. 程序的功能是什么? 2. 在开始进入循 环体之前,p 指向谁? 3. 循环每增加 一次,p 的值(地址)增加多少?它指 向谁? 4. 退出循环后,p 指向谁? 5. 你是否初步掌握了通过指针变量引用数 组元素的方法? (3) 先分析以下程序的运行结果,然 后上机验证,并通过此例掌握通过指针 变 量引用数组元素的各种方法。 (4) 编写函数,将 n 个数按原来的顺 序的逆序排列(要求用指针实现) , 然后 编写主函数完成: ① 输入 10 个 数; ② 调用此函数进行重排; ③ 输出 重排后的结果。 二. 分析与讨论 (1) 指针的定义方 法,指针和变量的关系。 定义方法: 数据类型 *指针变量名; 如 定义一个指向 int 型变量的指针—— in t *p; 则我们可以继续写如下代码—— int a = 4; p = &a; printf("%d", *p); 在这里,我 们定义了一个变量 a,我们把它理解为 内存空间连续的 4 个字节(int 型占用 4 字节),则这 4 个字节的空间保存着 一个数 4。&是取地址符号,即把变量 a 的地址(即这 4 个字节的首地址)赋 给指针 p (记住指针 p 的类型和变量 a 的类型要保持一致,否则的话,要进行 类型转换)。这样子,指针 p 就保存 着变量 a 的地址。我们如果把指针 p 当做内存空间里面另外一个连续的 4 个 字节,那么这 4 个字节保存的 数就是 变量 a 的地址。printf("%d",*p)和 prin tf("%d",a)的结果是一样的。这里的*是 取变量符号(与& 刚好作用相反,通过 变量的地址找到变量),与定义时 int *p 的*号作用不同(定义时的*表示该 变量是个 指针变量,而非是取它指向 的变量)。 (2) 数组和指针的关系。 指针与数组是 C 语言中很重要的两个概 念,它们之间有着密切的关系,利用这 种关系,可以增强处理数组 的灵活性 ,加快运行速度,本文着重讨论指针与 数组之间的联系及在编程中的应用。 1 .指针与数组的关系 当一个指针变量 被初始化成数组名时,就说该指针变量 指向了数组。如: char str[20], *ptr; ptr=str; ptr 被置为数组 str 的第一个元 素的地址,因为数组名就是该数组的首 地址,也是数组第一个元素的 地址。 此时可以认为指针 ptr 就是数组 str( 反之不成立) ,这样原来对数组的处 理都可以用指针来实现。 如对数组元 素的访问,既可以用下标变量访问,也 可以用指针访问。 2.指向数组元素的 指针 若有如下定义: int a[10], *pa; p a=a; 则 p=&a[0]是将数组第 1 个元素的 地址赋给了指针变量 p。 实际上,C 语 言中数组名就是数组的首地址,所以第 一个元素的地址可以用两种方法获得: p=&a[0]或 p=a。 这两种方法在形式上 相像,其区别在于:pa 是指针变量,a 是数组名。值得注意的是:pa 是一个 可以 变化的指针变量,而 a 是一个常 数。因为数组一经被说明,数组的地址 也就是固定的,因此 a 是不能变化 的 ,不允许使用 a++、++a 或语句 a +=10,而 pa++、++pa、pa+=10 则是正确的。由此可见,此 时指针与 数组融为一体。 3.指针与一维数组 理 解指针与一维数组的关系,首先要了解 在编译系统中,一维数组的存储组织形 式和对数组元素的访 问方法。 一维数 组是一个线形表,它被存放在一片连续 的内存单元中。C 语言对数组的访问是 通过数组名(数 组的起始地址)加上 相对于起始地址的相对量(由下标变量 给出) ,得到要访问的数组元素的单 元地址,然 后再对计算出的单元地址 的内容进行访问。通常把数据类型所占 单元的字节个数称为扩大因子。 实际 上编译系统将数组元素的形式 a[i]转换 成*(a+i), 然后才进行运算。 对于一 般数组元素的形式: <数组名>[<下标 表达式>],编译程序将其转换成:*(< 数组名>+<下标表达式>),其中下标表 达式为:下 标表达式*扩大因子。整 个式子计算结果是一个内存地址,最后 的结果为:*<地址>=<地址所对应单元 的 地址的内容>。由此可见,C 语言对 数组的处理,实际上是转换成指针地址 的运算。 数组与指针暗中结合在一起。因此,任 何能由下标完成的操作,都可以用指针 来实现,一个不带下标 的数组名就是 一个指向该数组的指针。 4.指针与多 维数组 用指针变量可以指向一维数组 ,也可以指向多维数组。但在概念上和 使用上,多维数组的指针比一维 数组 的指针要复杂一些。 例如,在一个三 维数组中,引用元素 c[i][j][k]的地址计 算最终将换成:*(*(*(c+i)+j)+k) 。 了解了多维数组的存储形式和访问 多维数组元素的内部转换公式后,再看 当一个指针变量指向多维数组及 其元 素的情况。 1 指向数组元素的指针变量 若有如下说明: int a[3][4]; int *p; p= a; p 是指向整型变量的指针;p=a 使 p 指向整型二维数组 a 的首地址。 *(*( p+1)+2)表示取 a[1][2]的内容;*p 表示取 a[0][1]的内容,因为 p 是指向 整型变量的指针; p++表示 p 的内容 加 1,即 p 中存放的地址增加一个整型 量的字节数 2,从而使 p 指向下一个整 型量 a[0] [1]。 2 指向由 j 个整数组成 的一维数组的指针变量 当指针变量 p 不是指向整型变量,而是指向一个包含 j 个元素的一维数组。如果 p=a[0],则 p++不 是指向 a[0][1],而是指向 a[1] 。这时 p 的增值以一维数组的长度为单 位。 5.指针与字符数组 C 语言中许多 字符串操作都是由指向字符数组的指针 及指针的运算来实现的。因为对于字符 串来说, 一般都是严格的顺序存取方 式,使用指针可以打破这种存取方式, 更为灵活地处理字符串。 另外由于字 符串以′\0′作为结束符,而′\0′的 ASCII 码是 0,它正好是 C 语言的逻辑假值, 所以 可以直接用它作为判断字符串结 束的条件,而不需要用字符串的长度来 判断。C 语言中类似的字符串处理 函数 都是用指针来完成,使程序运行速度更 快、效率更高,而且更易于理解。
676094398@qq.com!十分抱歉啊!以后有忙帮!帮你补上!