2010年自学考试《高级语言程序设计》习题
内有各章节典型题、模拟测试题、重点部分指针章节详细讲解 一、选择 1.链式存储结构中,每个数据的存储结点里 D 指向邻接存储结点的指针,用以反映数据间的逻辑关系。 A.只能有1个 B.只能有2个 C.只能有3个 D.可以有多个 2.有下面的算法段: for (i=0; i 其时间复杂度为 B 。 A.O(1) B.O(n) C.O(log2n) D.O(n2) 四、应用 1.给出下面3个算法段的时间复杂度: (1)x++; (2)for (j=1; j for (k=1; k<=m; k++) x++; 答:(1)的时间复杂度为O(1); (2)的时间复杂度O(n); (3)的时间复杂度是O(n2)。 第2部分 线性表 一、填空 1.以顺序存储结构实现的线性表,被称为 顺序表 。 2.以链式存储结构实现的线性表,被称为 链表 。 3.不带表头结点的链表,是指该链表的表头指针直接指向该链表的 起始结点 。 4.顺序表Sq = (a1,a2,a3,?,an)(n≥1)中,每个数据元素需要占用w个存储单元。若m为元素a1的起始地址,那么元素an的存储地址是 m+(n-1)*w 。 5.当线性表的数据元素个数基本稳定、很少进行插入和删除操作,但却要求以最快的 - 1 - 习题解答 速度存取表中的元素时,我们应该对该表采用 顺序 存储结构。 二、选择 1.下面,对非空线性表特点的论述, C 是正确的。 A.所有结点有且只有一个直接前驱 B.所有结点有且只有一个直接后继 C.每个结点至多只有一个直接前驱,至多只有一个直接后继 D.结点间是按照1对多的邻接关系来维系其逻辑关系的 2.带表头结点的单链表Lk_h为空的判定条件是 B 。 A.Lk_h == NULL B.Lk_h->Next == NULL C.Lk_h->Next == Lk_h D.Lk_h != NULL 3.往一个顺序表的任一结点前插入一个新数据结点时,平均而言,需要移动 B 个结点。 A.n B.n/2 C.n+1 D.(n+1)/2 4.在一个单链表中,已知qtr所指结点是ptr所指结点的直接前驱。现要在qtr所指结点和ptr所指结点之间插入一个rtr所指的结点,要执行的操作应该是 C 。 A.rtr->Next = ptr->Next; ptr->Next = rtr; B.ptr->Next = rtr->Next; C.qtr->Next = rtr; rtr->Next = ptr; D.ptr->Next = rtr; rtr->Next = qtr->Next; 5.在一个单链表中,若现在要删除ptr指针所指结点的直接后继结点,则需要执行的操作是 A 。 A.ptr->Next = ptr->Next->Next ; B.ptr = ptr->Next; ptr->Next = ptr->Next->Next ; C.ptr = ptr->Next->Next ; D.ptr->Next= ptr ; 6.在长度为n的顺序表中,往其第i个元素(1≤i≤n)之前插入一个新的元素时,需要往后移动 B 个元素。 A.n-i B.n-i+1 C.n-i-1 D.i 7.在长度为n的顺序表中,删除第i个元素(1≤i≤n)时,需要往前移动 A 个元素。 A.n-i B.n-i+1 C.n-i-1 D.i 8.设tail是指向一个非空带表头结点的循环单链表的尾指针。那么,删除链表起始结点的操作应该是 D 。 A.ptr = tail ; B.tail = tail->Next ; tail = tail->Next ; free (tail) ; free (ptr); C.tail = tail->Next->Next ; D.ptr = tail->Next->Next ; Free (tail); tail->Next->Next = ptr->Next ; - 2 - 习题解答 Free (ptr); free (ptr); 9.在单链表中,如果指针ptr所指结点不是链表的尾结点,那么在ptr之后插入由指针qtr所指结点的操作应该是 B 。 A.qtr->Next = ptr ; B.qtr->Next = ptr->Next ; ptr->Next = qtr ; ptr->Next = qtr ; C.qtr->Next = ptr->Next ; D.ptr->Next = qtr ; ptr = qtr ; qtr->Next = ptr ; 四、应用 1.设计一个计算带表头结点的单链表L的长度(即结点个数)的算法。 typedef struct node *link ; typedef struct node{ ListItem element ; link next; }Node; 答:算法设计如下: int Length (link L) { Link p=L->next; int sum=0; while (p) { sum++; p = p->next ; } return (sum) ; } 2、已知一个带表头结点的无序单链表L。试编写一个算法,功能是从表中找出最大值和最小值。 typedef struct node{ ListItem element ; struct node next;}Node,*link; viod maxmin(link L) { int max,min; link p=L->next; if(p) { max=p->element; min=p->element; p=p->next; - 3 - 习题解答 while (p) { if(max printf(\} 3.已知一个带表头结点的无序单链表L,不同结点的Data域值有可能相同。编写一个算法,功能是计算出Data域值为x的结点的个数。 typedef struct node *link ; typedef struct node{ ListItem data; link next;}Node; 答: int Count (link L, int x) { n = 0 ; link p=L->next; while (p) { if (p->data = = x) n ++ ; p= p->next } return (n) ; } 第3部分 栈与队列 一、填空 1.限定插入和删除操作只能在一端进行的线性表,被称为是 栈 。 2.如果在顺序栈满时仍打算进行进栈操作,就称为发生了“ 上溢 ”出错。 3.如果在顺序栈空时仍打算进行出栈操作,就称为发生了“ 下溢 ”出错。 4.在具有n个数据结点的循环队列中,队满时共有 n-1 个数据元素。 5.如果操作顺序是先让字母A、B、C进栈,做两次出栈;再让字母D、E、F进栈,做一次出栈;最后让字母G进栈,做三次出栈。最终这个堆栈从栈顶到栈底的余留元素应该是 A 。 6.队列中,允许进行删除的一端称为 队首 。 二、选择 1.一个栈的元素进栈序列是a、b、c、d、e,那么下面的 C 不能做为一个出栈序列。 A.e、d、c、b、a B.d、e、c、b、a C.d、c、e、a、b. D.a、b、c、d、e 2.判定一个顺序队列Qs(最多有n个元素)为空的条件是 C 。 - 4 - 习题解答 A.Qs_rear-Qs_front == n*size B.Qs_rear-Qs_front+1 == n*size C.Qs_front == Qs_rear D.Qs_front == Qs_rear+size 3.链栈与顺序栈相比,一个较为明显的优点是 D 。 A.通常不会出现栈空的情形 B.插入操作更加便利 C.删除操作更加便利 D.通常不会出现栈满的情形 4.一个循环队列的最大容量为m+1,front为队首指针,rear为队尾指针。那么进队操作时求队位号应该使用公式 D 。 A.Cq_front = (Cq_front+1)%m B.Cq_front = (Cq_front+1)%(m+1) C.Cq_rear = (Cq_rear+1)%m D.Cq_rear = (Cq_rear+1)%(m+1) 5.在一个循环顺序队列里,队首指针Cq_front总是指向 A 。 A.队首元素 B.队首元素的前一个队位 C.任意位置 D.队首元素的后一个队位 6.若一个栈的进栈序列是1、2、3、4,那么要求出栈序列为3、2、1、4时,进、出栈操作的顺序应该是 A 。(注:所给顺序中,I表示进栈操作,O表示出栈操作) A.IIIOOOIO B.IOIOIOIO C.IIOOIOIO D.IOIIIOOO 第4部分 树 一、填空 1.树中结点的度,是指结点拥有 孩子 的个数。 2.树中除根结点外,其他结点有且只有 一个 前驱结点,但可以有 零个或多个 后继结点。 3.在数据结构中,把n(n≥0)棵互不相交的树的集合称为 森林 。 4.在如图6-21所示的树中,,结点H的祖先是 A、D、G 。 图6-21 树示例 图6-22 树示例 5.在树中,一个结点的孩子个数,称为该结点的 度 。 6.一棵树的形状如图6-22所示。它的根结点是 A ,叶结点是 E、G、I、J、K、L、N、O、P、Q、R ,这棵树的度是 4 ,这棵树的深度是 5 ,结点F的孩子结点是 J、K ,结点G的父结点是 C ,结点 M、H、D、A 是结点R的祖先。 7.结点数为7的二叉树的高度最矮是 3 ,最高是 7 。 - 5 - 习题解答 8.如果一棵满二叉树的深度为6,那么它共有 63 个结点,有 32 个叶结点。 9.由n个带权值的叶结点生成的哈夫曼树,最终共有 2n-1 个结点。 10.将一棵完全二叉树按层次进行编号。那么,对编号为i的结点,如果有左孩子,则左孩子的编号应该是 2i ;如果有右孩子,则右孩子的编号应该是 2i+1 。 11.若二叉树共有n个结点,采用二叉链表存储结构。那么在所有存储结点里,一共会有 2n 个指针域,其中有 n+1 个指针域是空的。 12.深度为5的二叉树,至多有 31 个结点。 二、选择 1.已知一棵单右支的二叉树,如下左图所示。把它还原成森林,应该是 D 。 A. B. C. D. 2.将一棵树Tr转换成相应的二叉树Bt,那么对Tr的先序遍历是对Bt的 A 。 A.先序遍历 B.中序遍历 C.后序遍历 D.无法确定 3.将一棵树Tr转换成相应的二叉树Bt,那么对Tr的后序遍历是对Bt的 B 。 A.先序遍历 B.中序遍历 C.后序遍历 D.无法确定 4.设森林F中有3棵树,依次有结点n1、n2、n3个。把该森林转换成对应的二叉树后,该二叉树的右子树上的结点个数是 D 。 A.n1 B.n1+n2 C.n3 D.n2+n3 5.设有由三棵树T1、T2、T3组成的森林,其结点个数分别为n1、n2、n3。与该森林相应的二叉树为Bt。则该二叉树根结点的左子树中应该有结点 A 个。 A.n1-1 B.n1 C.n1+1 D.n1+n2 6.一棵有n个结点的树,在把它转换成对应的二叉树之后,该二叉树根结点的左子树上共有 B 个结点。 A.n-2 B.n-1 C.n+1 D.n+2 7.一棵有n个结点的树,在把它转换成对应的二叉树之后,该二叉树根结点的右子树上共有 A 个结点。 A.0 B.n C.n+1 D.n+2 8.下列说法中,正确的是 A 。 A.树的先序遍历序列与其对应的二叉树的先序遍历序列相同 B.树的先序遍历序列与其对应的二叉树的后序遍历序列相同 C.树的后序遍历序列与其对应的二叉树的先序遍历序列相同 D.树的后序遍历序列与其对应的二叉树的后序遍历序列相同 9.在所给的4棵二叉树中, C 不是完全二叉树。 10.设有一棵5个结点的二叉树,其先序遍历序列为:A-B-C-D-E,中序遍历序列为:B-A-D-C-E,那么它的后序遍历序列为 B 。 A.A-B-D-E-C B.B-D-E-C-A - 6 - 习题解答 C.D-E-C-A-B D.A-B-C-D-E 11.将一棵有50个结点的完全二叉树按层编号,那么编号为25的结点是 B 。 A.无左、右孩子 B.有左孩子,无右孩子 C.有右孩子,无左孩子 D.有左、右孩子 12.深度为6的二叉树,最多可以有 A 个结点。 A.63 B.64 C.127 D.128 13.在一棵非空二叉树的中序遍历序列里,根结点的右边 D 结点。 A.只有左子树上的部分 B.只有左子树上的所有 C.只有右子树上的部分 D.只有右子树上的所有 14.在任何一棵二叉树的各种遍历序列中,叶结点的相对次序是 A 。 A.不发生变化 B.发生变化 C.不能确定 D.以上都不对 15.权值为1、2、6、8的四个结点,所构造的哈夫曼树的带权路径长度是 D 。 A.18 B.28 C.19 D.29 16.一棵二叉树度2的结点数为7,度1的结点数为6。那么它的叶结点数是 C 。 A.6 B.7 C.8 D.9 17.在一棵二叉树中,第5层上的结点数最多是 C 个。 A.8 B.15 C.16 D.32 四、应用 1.将图6-26所示的二叉树转换成相应的森林。 图6-26 二叉树示例 图6-27 树示例 答:转换成的森林如下图所示。 2.给出如图6-27所示树的先序遍历序列和后序遍历序列。 答:该树的先序遍历序列为:A-B-E-F-K-L-M-C-G-D-H-I-J; 该树的后序遍历序列是:E-K-M-L-F-B-G-C-H-I-J-D-A。 - 7 - 习题解答 3.将图6-28所示的森林转换成对应的二叉树。 图6-28 森林示例 图6-29 树示例 答:对应的二叉树如下图所示。 4.将图6-29所示的树转换成相对应的二叉树。 答:对应的二叉树如下图所示 5.分别写出如图5-32所示二叉树的先序、中序、后序遍历序列。 图5-32 二叉树示例 - 8 - 习题解答 答:先序遍历序列为:A-B-C-D-F-G-H-E, 中序遍历序列为:B-A-D-G-F-H-C-E, 后序遍历序列为:B-G-H-F-D-E-C-A。 6.权值序列为:10、16、20、6、30、24,请用图示来表达构造一棵哈夫曼树的全过程。 答:构造这棵哈夫曼树的全过程如下所示。 第5部分 图 一、填空 1.在一个具有4个顶点的无向图中,要连通全部顶点,,至少需要 3 条边。 2.在无向图中,若顶点vi和vj之间有一条边(vi,vj)存在,那么则称顶点vi和vj互为 邻接 点。 3.图中顶点vi的“度”,是指与它 相邻接 的顶点的个数,并记为D(vi)。 4.在有向图中,把从顶点vi到顶点vj的弧记为 < vi,vj > ,而把从顶点vj到顶点vi的弧记为 < vj,vi > ,这是两条不同的弧。 5.对于一个无向图,其邻接矩阵中第i行(或第i列)里非零或非∞元素的个数,正好是第i个顶点vi的 度 。 6.对于一个有向图,其邻接矩阵中第i行里非零或非∞元素的个数,正好是第i个顶点vi的 出度 ;其邻接矩阵中第i列里非零或非∞元素的个数,正好是第i个顶点vi的 入度 。 7.在无向图中,若从顶点vi到顶点vj之间有 路径 存在,则称vi与vj是连通的。 8.如果无向图G中 任意 一对顶点之间都是连通的,则称该图G为连通图,否则是非连通图。 9.在无向图G中,尽可能多地从集合V及E里收集顶点和边,使它们成为该图的一个极大的连通子图,这个子图就被称为是无向图G的一个 连通分量 。 - 9 - 习题解答 二、选择 1.在一个有n个顶点的无向图中,要连通全部顶点,至少需要 C 条边。 A.n B.n+1 C.n-1 D.n/2 2.对于一个无向完全图来说,它的每个不同顶点对之间,都存在有一条边。因此,有n个顶点的无向完全图包含有 C 条边。 A.n(n-1) B.n(n+1) C.n(n-1)/2 D.n(n+1)/2 3.对于一个有向完全图来说,它的每个不同顶点对之间,都存在有两条弧。因此,有n个顶点的有向完全图包含有 A 条边。 A.n(n-1) B.n(n+1) C.n(n-1)/2 D.n(n+1)/2 4.在一个无向图中,所有顶点的度数之和,是其所有边数之和的 C 倍。 A.1/2 B.1 C.2 D.4 5.在一个有向图中,所有顶点的入度之和 B 所有顶点的出度之和。 A.二分之一于 B.等于 C.两倍于 D.四倍于 6.一个无向连通网图的最小生成树 A 。 A.有一棵或多棵 B.只有一棵 C.一定有多棵 D.可能不存在 7.一个无向图有n个顶点,那么该图拥有的边数至少可以是 D 。 A.2n B.n C.n/2 D.0 8.一个有n个顶点的无向连通网图,其生成树里含有 C 条边。 A.4n-1 B.2n-1 C.n-1 D.n/2 9.下面关于图的存储的叙述中,正确的是 C 。 A.用邻接表存储图,所用存储空间大小只与图中顶点个数有关,与边数无关 B.用邻接表存储图,所用存储空间大小只与图中边数有关,与顶点个数无关 C.用邻接矩阵存储图,所用存储空间大小只与图中顶点个数有关,与边数无关. D.用邻接矩阵存储图,所用存储空间大小只与图中边数有关,与顶点个数无关 10.对如图7-21所示的无向图实施深度优先搜索遍历,可能的遍历序列是 B 。 10.包含无向连通图G的所有n个顶点在内的极小连通子图,是这个图的 生成树 。 11.只要在无向连通图的生成树里减少任意一条边,它就成为了一个 非连通图 。 12.对图的广度优先搜索,类似于对树进行 按层次 遍历。 图7-21 无向图示例 三、问答 - 10 - 习题解答 图7-23 无向图示例 1.有如图7-23所示的一个无向图,给出它的邻接矩阵以及从顶点v1出发的深度优先遍历序列。 答:它的邻接矩阵如图所示。从顶点v1出发的深度优先遍历序列为: v1->v2->v4->v5->v7->v6->v3 注意,该序列是不唯一的。 2.对图7-24回答下列问题: (1)顶点集合V; (2)边集合E; (4)一个长度为5的路径; (6)图的一个生成树; (7)邻接矩阵; (3)每个顶点x的度D(x); (5)一个长度为4的回路; (8)邻接表。 图7-24 图示例 答:(1)顶点集合V={v1, v2, v3, v4, v5, v6}。 (2)边集合E={< v1, v2>, < v2, v3>, < v2, v4>, < v3, v4>, < v3, v5>, < v4, v5>, < v3, v6>, < v4, v6>}。 (3)每个顶点的度:D(v1)=1,D(v2)=3,D(v3)=D(v4)=4,D(v5)=D(v6)=2。 (4)一个长度为5的路径是:v1-> v2-> v3-> v6-> v4-> v5。 (5)一个长度为4的回路是:v2-> v3-> v5-> v4-> v2。 (6)如下图(a)所示。 (7)如下图(b)所示。 (8)如下图(c)所示。 - 11 - 习题解答 问答5的(6)~(8)答案 第6部分 二叉排序树与散列表 一、填空 1.在散列查找中使用的函数,称为“ 散列函数 ”。在散列法中的查找表,称为散列表或哈希表。 2.散列法中,如果两个不同的关键字经过散列函数的计算后,得到了相同的索引地址,那么这种现象被称作“ 冲突 ”。 3.散列法中,计算后得到相同索引地址的那些不同关键字,被称作“ 同义词 ”。 二、选择 1.在对线性表进行折半查找时,要求线性表必须 B 。 A.以顺序方式存储 B.以顺序方式存储,且结点按关键字有序排列 C.以链式方式存储 D.以链式方式存储,且结点按关键字有序排列 2.采用顺序查找法查找长度为n的线性表时,其平均查找长度为 C 。 A.n B.n/2 C.(n+1)/2 D.(n-1)/2 3.设散列表长m=14,散列函数h(key)=key。表中已有四个记录,关键字分别为15、38、61、84,采用二次探测法解决冲突。那么关键字为49的记录的散列地址为 D 。 A.1 B.3 C.5 D.9 4.在下列各种查找方法中,只有 A 查找法的平均查找长度与表长n无关。 A.散列查找 B.二叉查找树 C.折半查找 D.分块查找 - 12 - 习题解答 四、应用 1.有关键字序列:20、10、30、15、25、5、35、12、27,请一步步画出构造二叉查找树的过程。 答:构造二叉查找树的过程如下: 2.给出如图8-21所示的一棵二叉查找树,在其基础上分别做操作:(1)删除关键字为15的记录;(2)插入关键字为20的记录。画出这两个操作完成后该树的形态。 图8-21 二叉查找树示例 答:1)删除关键字为15的记录后,该树的形态如图(a)所示 (2)插入关键字为20的记录后,该树的形态如图(c)所示。 - 13 - 习题解答 第7部分 选择与排序 一、填空 1.若经过某种排序之后,那些有相同关键字值的记录间的相对位置保持不变,那么称这种排序方法是 稳定 的。 2. 选择 排序方法是从未排序的序列中挑选出元素,然后将其依次放入排好序的序列的一端。 3. 快速 排序方法是通过适当的位置交换,把序列中的元素一次性地放到了它的最终位置上。 4.对关键字序列22、86、19、49、12、30、65、35、18做一趟排序后,得到的结果是18、12、19、22、49、30、65、35、86。因此,可以认为采用的排序方法是 快速排序 。 二、选择 1.在下面给出的各种排序算法中,只有 A 是稳定排序算法。 A.冒泡排序 B.快速排序 C.直接选择排序 D.堆排序 2.在下面给出的各种排序算法中,只有 B 不是稳定排序算法。 A.冒泡排序 B.快速排序 C.直接插入排序 D.折半插入排序 3.对关键字序列:46、79、56、38、40、84采用快速排序方法。若以46为枢轴,那么一次划分后的结果应该是 D 。 A.38,40,46,79,56,84 B.38,40,46,84,56,79 C.40,38,46,79,84,56 D.40,38,46,56,79,84 4.从待排序序列中依次取出元素与已排好序的序列里的元素进行比较,并存放到已排序序列的正确位置上,这种排序方法是 A 。 A.直接插入排序 B.交换排序 C.冒泡排序 D.选择排序 5.具有24个记录的待排序列,采用冒泡排序时,最少需要进行的比较次数是 B 。 A.1 B.23 C.24 D.512 6.用某种排序方法对序列:24、84、21、47、16、28、66、35、20进行排序,序列的变化情况为: 24,84,21,47,16,28,66,35,20 20,16,21,24,47,28,66,35,84 16,20,21,24,35,28,47,66,84 16,20,21,24,28,35,47,66,84 那么,这里采用的排序方法是 C 。 A.直接插入排序 B.冒泡排序 C.快速排序 D.选择排序 【自考365 - 自学考试(自考)】 /*输出100~999间的所有水仙花数。如:153=1*1*1+5*5*5+3*3*3,153就是水仙花数*/ #include main() - 14 - 习题解答 { int i,a,b,c; for(i=100;i<1000;i++) { a=i; b=( (i-a) % 100 ) / 10; c=( i-a-b*10 ) /100; if( i == a*a*a+b*b*b+c*c*c ) printf(\,i); } } /*输出100~200间既是3的倍数又是5的倍数的所有数。*/ #include main() { int i; for(i=100;i<201;i++) if( i%3==0 && i%5==0) printf(\,i); } /*从键盘上输入10个任意整数,如果有3的倍数,求其平均数*/ #include main() { int i,n,s,d; n=0; - 15 - 习题解答 s=0; for(i=1;i<=10;i++) { scanf(\,&d); if( d%3 == 0) { n++; s+=d; } } if(n>0) printf(\,s/n); else printf(\); } /*输出100~200间的所有素数。*/ #include main() { int i,j,n; for(i=100;i<=200;i++) { for(j=2;j if(i%j ==0) break; if(j == i) - 16 - 习题解答 printf(\,i); } } /*从键盘输入10个任意整数,输出其中的最大数*/ #include main() { int i,max,d; scanf(\,&d); max=d; for(i=2;i<=10;i++) { scanf(\,&d); if(d>max) max=d; } printf(\,max); } /*编程序计算1*2*3*4*??*10的值。*/ #include main() { int i,s; s=1; for(i=1;i<=10;i++) - 17 - 习题解答 s=s*i; printf(\,s); } /*从键盘上接收任意一串字符,然后倒序输出。*/ #include main() { char a??,c; int i=0; c=0; while(c!=10 && c!=13 && i<200) { scanf(\,& &c); a=c; i++; } i——; while(i>=0) { printf(\,a; i——; } } /*从键盘输入10个数,找出最大数,并指出它是第几个数。*/ #include - 18 - 习题解答 main() { int i,d,max,n; scanf(\,&d); max=d; n=1; for(i=2;i<=10;i++) { scanf(\,&d); if(d>max) { max=d; n=i; } } printf(\,n,max); } /*从键盘输入10个任意整数,输出其平方和*/ #include main() { int i,s,d; for(i=1;i<=10;i++) { scanf(\,&d); s+=d*d; } - 19 - 习题解答 printf(\,s); } /*从键盘上接收任意一串字符,统计其中字母a出现的个数。*/ #include main() { char c; int i; c=0; i=0; while(c!=10 && c!=13) { scanf(\,&c); if(c=='a') i++; } printf(\,i); 模拟题 一、是非题(下列各题,你认为正确的,请在题干的括号内打“√”,错的打“×”。每题1分,共10分) 1、实型是有序类型。 A。正确 B。不正确 2、保留字具有特定含义,不能挪作它用。 A。正确 B。不正确 3、true<false之值为false。 A。正确 - 20 - 习题解答 printf(“\\n”); } } 程序产生如下形式的二项式系数三角形: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 1O 5 1 1 6 15 20 15 6 1 1 7 21 35 35 21 7 1 2.多级指针 当指针变量pp所指的变量ip又是一种指针时,呷就是一种指向指针的指针,称指针变量如是一种多级指针。定义指向指针变量的指针变量的一般形式为 数据类型 * *指针变量名; 例如, int * *pp,*ip ,i ; ip=&i; pp=&ip; 定义说明pp是指向指针的指针变量;它能指向的是这样一种指针对象,该指针对象是能指向int型的指针变量。如上述代码让pp指向指针变量ip,中指向整型变量i. 多级指针与指针数组有密切的关系。若有指针数组: - 36 - 习题解答 char * lines[ ]= {“ADA”,“ALGOL”,“C”,“C++”,“FORTRAN”,“PASCAL” }; 则lines指针数组的每个元素分别指向以上字符串常量的首字符。在这里数组名lines可以作为它的首元素lines[0]的指针,lines+k是元素 lines[k]的指针,由于lines[k] 本身也是指针,所以表达式 lines+k的值是一种指针的指针。如有必要还可引入指针变量cp,让它指向数组lines的某元素,如cp=&lines[k].这样,cp就是指向指针型数据的指针变量。在这里,cp是指向字符指针的指针变量,它应被定义成: char * *cp;为了定义这样的 cp,它的前面有两个*号。由于*自右向左结合,首先是“* cp”表示 cp是指针变量,再有**cp表示cp能指向的是某种指针类型,最后“char * *cp”表示指针变量cp能 指向字符指针数据对象。如果有赋值cp=& lines[l],让它指向数组元素lines[1],则* cp引用 lines[1],是一个指针,指向字符串“ALGOL”的首字符。* *cp引用lines[1][0],其值是字符'A'.下面的代码实现顺序输出指针数组lines各元素所指字符串: for(c=lines;cp Printf(“%s\\n”,*cp); 设有数组a[]和指针数组pt[]有以下代码所示的关系: int a[]= {2,4,6,8,10 }; int *pt[]={&a[3],&a[2],a[4],&a[0],&[1]}; int * *p; 下面的代码利用指针数组pt[]和指针的指针p,遍历数组a[]: for( p=pt; p printf(“%d\\t”,* *p); - 37 - 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库2010年自学考试《高级语言程序设计》习题在线全文阅读。
相关推荐: