专题九 指针(讲义)-《编程语言基础—C语言》(高教版第五版)高考备考讲练测(山东省)

2024-08-02
| 9页
| 175人阅读
| 4人下载
精品

内容正文:

专题九 指针(讲义) ---《编程语言基础—C语言》专题复习讲练测 [考纲要求] 1:理解指针变量的定义及引用。 2:掌握指向数组的指针变量。 [课时安排] 2课时 [知识梳理] 一:指针变量的定义 内存地址概念: 在C语言中,内存地址是计算机内存中存储数据的每个字节的位置标识。简单来说,内存地址可以看作是数据在内存中的"家",每个数据项都有一个唯一的地址,这样程序就可以找到并访问它。 在C语言中,指针变量是一种特殊的变量,它存储的是另一个变量的内存地址。基本语法如下: 1.  指针类型 *指针变量名称; · 指针类型是指针指向的数据类型,可以是任何有效的C数据类型,例如 int, char, float 等。 · * 是解引用操作符,用来声明一个指针变量。 · 指针变量名称是为指针变量指定的名称。 例如:定义指向int类型的指针变量 1. int *pInt; 这行代码声明了一个名为 pInt 的指针变量,它可以存储一个整数的内存地址。 定义一个指向字符的指针: 1. char *pChar; 这行代码声明了一个名为 pChar 的指针变量,它可以存储一个字符的内存地址。 同类型的指针变量可以相互赋值 指针变量在使用前通常需要被初始化,即赋予它一个有效的内存地址。这可以通过取地址操作符 & 来实现,例如: 1. int var = 10; 2. int *pInt = &var; // pInt 现在存储了 var 的地址 var 是一个整数变量,pInt 是一个指向整数的指针,通过 &var 我们获取了 var 的内存地址,并将其赋给 pInt。 在C语言中,存储空间的访问主要有两种形式:直接访问和间接访问。 · 直接访问 直接访问是指直接使用变量名来访问存储空间。这种方式下,程序直接操作变量的值,而不需要通过指针。 例如,对于一个整型变量 int a = 10;,我们可以直接通过变量名 a 来访问和修改它的值。 1. int directVar = 100; // 声明一个整型变量 2. directVar = 200;    // 直接修改变量的值 3. printf("%d", directVar); // 输出变量的值 · 间接访问 间接访问是通过指针来实现的。这种方式下,程序首先操作指针变量,然后通过指针来访问或修改它所指向的存储空间中的数据。 例如,如果我们有一个整型变量 int b = 20; 和一个指向它的指针 int *ptr = &b;,我们可以通过指针 *ptr 来访问 b 的值,或者通过修改 *ptr 来改变 b 的值。 1. int indirectVar = 300; // 声明一个整型变量 2. int *ptr = &indirectVar; // 声明一个指向该变量的指针 3. *ptr = 400;              // 通过指针修改变量的值 4. printf("%d", *ptr);     // 通过指针访问变量的值 二:指针变量的引用 声明指针变量时,需要指定其类型,然后可以将其初始化为一个地址或 NULL。 1. int *ptr = NULL; // 初始化为NULL 2. int var = 10; 3. int *ptr = &var; // 初始化为var的地址 · 取地址运算符(&): 用于获取变量的内存地址。 例如:int var = 10; int *ptr = &var; 这里 &var 获取了 var 的内存地址,并将其赋给指针 ptr。 · 解引用运算符(*): 用于访问指针指向的内存地址中存储的数据。 例如:int value = *ptr; 这里 *ptr 访问了 ptr 指向的内存地址中存储的值,并将其赋给 value。 · 指针递增运算符(++): 将指针向前移动到下一个逻辑存储单元。对于数组元素,这通常意味着移动到下一个数组元素的地址。 例如:ptr++; 如果 ptr 指向一个 int 数组的元素,ptr++ 会将 ptr 移动到下一个 int 元素的地址。 · 指针递减运算符(--): 将指针向后移动到上一个逻辑存储单元。 例如:ptr--; 如果 ptr 指向一个 int 数组的元素,ptr-- 会将 ptr 移动到上一个 int 元素的地址。 · 指针加法运算符(+): 将整数加到指针上,结果是一个新的指针,它指向原始指针加上整数倍的元素大小的内存地址。 例如:ptr + 3; 如果 ptr 指向一个 int 数组的元素,ptr + 3 将指向数组中的第四个元素。 · 指针减法运算符(-): 从指针中减去整数,结果是一个新的指针,它指向原始指针减去整数倍的元素大小的内存地址。 例如:ptr - 2; 如果 ptr 指向一个 int 数组的元素,ptr - 2 将指向数组中的前两个元素之前的位置。 三:指向数组的指针变量 在C语言中,数组和指针有着紧密的联系。数组名本身就是一个指向数组首元素的指针。 · 指向一维数组的指针变量 指向一维数组的指针变量在C语言中是一种常见的用法,它允许你通过指针来访问和操作数组元素。 1. int *ptr; 2. int arr[] = {10, 20, 30, 40, 50}; 3. int *ptr = arr; // ptr现在指向数组arr的首元素 声明一个指针变量时,需要指定它指向的数据类型,将指针变量初始化为数组的首地址。 1. printf("%d ", *ptr); // 输出数组第一个元素,即10 使用指针变量和解引用操作符 * 来访问数组元素。 1. for (int i = 0; i < 5; i++) { 2.     printf("%d ", *(ptr + i)); // 等价于printf("%d ", arr[i]); 3. } 通过改变指针的值来遍历数组。 · 指向二维数组的指针变量 在C语言中,二维数组可以被视为一个数组的数组,即每个元素本身也是一个数组。 二维数组在内存中是按行连续存储的。例如,int arr[3][4]; 在内存中会连续存储为 3 行,每行有 4 个 int 类型的元素。 二维数组的指针实际上是一个指向指针的指针。声明时,使用 int (*)[4] 表示一个指向有 4 个 int 元素数组的指针。 声明指向二维数组的指针: 声明一个指向二维数组的指针,需要使用两个星号(**)。第一个星号表示这是一个指针,第二个星号表示这个指针指向的是一个数组。 1. int **ptr; 将这个指针初始化为指向一个已经存在的二维数组。 1. int arr[4][5] = { 2.     {1, 2, 3, 4, 5}, 3.     {6, 7, 8, 9, 10}, 4.     {11, 12, 13, 14, 15}, 5.     {16, 17, 18, 19, 20} 6. }; 7. int (*ptr)[5] = arr; // ptr是一个指向有5个int元素的数组的指针 使用指向二维数组的指针访问元素有两种主要方式: ① 通过指针直接访问: 使用指针的数组索引来访问特定的行,然后使用下标访问该行的元素。 1. printf("%d ", (*ptr)[1]); // 输出第二列的第一个元素,即2 ② 通过指针加法访问: 使用指针加法来移动到特定的行,然后解引用访问该行的元素。 1. printf("%d ", *(ptr[1] + 2)); // 等价于上面的操作,输出第二列的第三个元素,即8 遍历二维数组 使用指向二维数组的指针遍历数组,可以通过嵌套循环实现: 1. for (int i = 0; i < 4; i++) { 2.     for (int j = 0; j < 5; j++) { 3.         printf("%d ", (*(ptr + i))[j]); 4.     } 5.     printf(" "); 6. } [限时练习] 1.以下程序输出结果是( )。 int main() { int a[] = {4, 5, 6, 7, 8}; int *p = a; *p++ += 100; printf(" %d %d ", *p, *(p++)); return 0; } A.105 6 B.5 5 C.6 5 D.106 5 【答案】B 【解析】int a[] = {4, 5, 6, 7, 8}; 定义一个整型数组 a 并初始化。int *p = a; 定义一个整型指针 p 并初始化为指向数组 a 的首地址。*p++ += 100; 执行以下操作:*p(即 a[0])的值增加 100,变为 104。然后 p 递增,现在指向 a[1]。printf(" %d %d ", *p, *(p++)); 执行以下操作:打印 *p,即 a[1] 的值,为 5。p 递增,指向 a[2],然后打印 *(p++) 的值,这是递增前 p 指向的值,也是 5。所以,输出结果是 5 5。 2.若定义:int a[2][3]={1,3,5,7,9,11},以下描述正确的是( )。 A.*(a+1)为元素7的地址 B.(a[1]+1)的值是5 C.**(a +1)+2值是11 D.a[0]和a不同 【答案】A 【解析】a 是一个二维数组的名,它代表数组首行的地址。a+1 则代表下一行的地址,即第二行的首地址。在二维数组 a[2][3] 中,*(a+1) 实际上是指向第二行的首元素的指针,即元素 7 的地址。因此,选项 A 正确。 3.变量的指针其含义是指该变量的( )。 A.值 B.地址 C.名 D.一个标志 【答案】B 【解析】指针变量存储的是它所指向变量的内存地址。在C语言中,可以通过使用取地址符 & 来获取一个变量的地址,并将这个地址赋给一个指针变量。 4.若有说明;int *p,m=5,n;以下正确的程序段的是( )。 A.p=&n; B.p=&n; scanf("%d",&p); scanf("%d",*p); C.scanf("%d",&n); D.p = &n; *p=n; scanf("%d", p); 【答案】D 【解析】程序段首先将指针 p 初始化为变量 n 的地址,然后使用 scanf 通过指针 p 来读取一个值并存储到 n 中。 5.下列程序的运行结果是( )。 main() { int x[] = {-1, 1, 2, 3, 4, 5, 6, 7, 8, 9}, s, i, *p; s = 0; p = &x[0]; for (i = 1; i < 10; i += 2) s += *(p + i); printf("sum = % d ", s); } A.25 B.20 C.15 D.10 【答案】A 【解析】数组 x 的元素是 {-1, 1, 2, 3, 4, 5, 6, 7, 8, 9}。指针 p 初始化为指向数组 x 的第一个元素的地址。循环从 i = 1 开始,并且 i 的增量是 2,这意味着它将累加索引为奇数(1, 3, 5, 7, 9)的元素。累加的元素值是:x[1]、x[3]、x[5]、x[7]、x[9]。计算这些值的和:1 + 3 + 5 + 7 + 9 = 25。 6.若有一下定义和语句则对a数组元素地址的正确使用为( )。 int a[2][3],(*p)[3]; p=a; A. *(p+2) B.p[2] C.p[1]+1 D.(p+1)+2 【答案】C 【解析】p[1] 正确地访问了 p 指向的第二个数组(即 a[1]),+1 是对数组名的偏移,它指向 a[1][1] 的地址。这是正确的使用方式。 7.以下程序的输出结果是( )。 main() { int a[5] = {2, 4, 6, 8, 10}, *p, **k; p = a; k = &p; printf("%d", *p++); printf("%d ", **k); } A.44 B.22 C.24 D.46 【答案】C 【解析】p = a; 指针 p 指向数组 a 的第一个元素,即 a[0],值为 2。k = &p; 指针 k 指向指针 p,即 k 存储 p 的地址。printf("%d", *p++); 打印 p 指向的元素的值,然后 p 递增,指向下一个元素。初始时 *p 的值为 2,打印后 p 指向 a[1]。printf("%d ", **k); 打印 k 指向的指针 p 所指向的元素的值。由于 p 已经递增,现在指向 a[1],所以 **k 的值为 4。 8.用指针完成下述程序功能:输入a,b,按从小到大的顺序输出 【答案】 #include <stdio.h> int main() { int a, b; int *p1, *p2, temp; // 用指针接收用户输入 printf("请输入两个整数,用空格分隔:"); scanf("%d %d", &a, &b); p1 = &a; // p1 指向变量 a 的地址 p2 = &b; // p2 指向变量 b 的地址 // 比较两个数的大小,使用临时变量进行交换 if (*p1 > *p2) { temp = *p1; // 暂存 a 的值 *p1 = *p2; // 将 b 的值赋给 a *p2 = temp; // 将暂存的 a 值赋给 b } // 输出结果 printf("从小到大的顺序为:%d %d ", a, b); return 0; } 9.用指针完成下述程序功能:从键盘输入10个整数,放入一堆数组a中,然后将该数组中的元素值依次输出。 【答案】 #include <stdio.h> int main() { int a[10]; // 定义一个整型数组,可以存储10个整数 int *p; // 定义一个整型指针 int i; // 辅助变量,用于循环 // 使用指针从键盘输入10个整数 printf("请输入10个整数: "); for (p = a, i = 0; i < 10; p++, i++) { scanf("%d", p); } // 重新将指针指向数组的开始 p = a; // 使用指针依次输出数组中的元素 printf("您输入的整数为: "); for (i = 0; i < 10; i++) { printf("%d ", *(p + i)); } printf(" "); return 0; } 【归纳小结】 C语言指针是直接操作内存地址的变量,允许低层次的内存控制和数据操作。它们常用于数组遍历、动态内存分配、字符串处理、函数参数传递,以及构建复杂的数据结构。正确使用指针可以提高程序效率,但也需要避免野指针和内存泄漏。 学科网(北京)股份有限公司 $$

资源预览图

专题九 指针(讲义)-《编程语言基础—C语言》(高教版第五版)高考备考讲练测(山东省)
1
专题九 指针(讲义)-《编程语言基础—C语言》(高教版第五版)高考备考讲练测(山东省)
2
专题九 指针(讲义)-《编程语言基础—C语言》(高教版第五版)高考备考讲练测(山东省)
3
所属专辑
由于学科网是一个信息分享及获取的平台,不确保部分用户上传资料的 来源及知识产权归属。如您发现相关资料侵犯您的合法权益,请联系学科网,我们核实后将及时进行处理。