址值)。如果源串sourceStr的长度小于subStr子字符串的长度,或者源串sourceStr中根本就不出现subStr子字符串的话,返回空指针值NULL。findLast函数则要返回源串sourceStr中最后一次出现subStr子字符串的头字符位置。且要求实现程序中不可使用“string.h”头文件内有关寻找子串的标准库函数。
提示:findFirst函数中,首先把subStr子串的头位置j0=0(j0表示subStr字符数组的下标)与sourceStr源串的头位置j1=0(j1表示sourceStr字符数组的下标)“对齐”,而后逐字符地对两个串进行比较(从左到右),若一直比到了子串的结束各字符均相同时,则意味着在源串中找到了子串,此时返回子串在源串中的头字符位置(地址值);若逐字符进行比较时发现有不相同,则要进一步将subStr子串的头位置j0=0与sourceStr的新头位置j1=1“对齐”,而后又一次逐字符地对两个串进行比较(相当于子串整体“右平移”一个字符后再一次比较),如此等等。findLast则要首先将子串与源串的右后部“对齐”进行比较,而后子串逐步整体“左平移”。 7. 编程序,含有如下形式的循环语句,用于理解并测试new与delete的功能。 double *p; unsigned long n; cin>>n; for (int i=0; i 当输入不同的n时,输出结果有什么不同吗?若将循环改写为“for (int i=0; ; i++){…}”即改成为无限循环的话,程序会无限循环而永不停止吗? 进一步,将其中的“delete p;”语句删除掉后再执行,输出的结果会有什么不同?再进一步,不仅删除delete,而且改为无限循环的话,又会出现什么情况呢? 提示:若删除delete且将for语句改成为无限循环的话,程序最终是会出现错误的。其原因是,由于总通过new分配新内存空间,但又从不归还它们,所以迟早会出现再也没有动态存储空间可供分配的时候(此时通过new返回的指针值为NULL),那时将会出现运行错误。 注意:程序中凡通过new动态申请的存储空间,都应该在使用结束后,用相应的delete将它们释放掉(归还给系统),否则就有可能产生所谓的“内存泄漏”。 8. 下面的程序片段首先通过指针配合new运算符生成了一个动态的二维数组a(其行数lin及列数col通过cin临时输入),而后又为数组各元素赋了值。请在此基础上编制完整程序并上机进行调试运行,并输出结果。 int lin,col,i,j; cin>>lin>>col; //任意输入行数lin及列数col int **a; a = new int*[lin]; //lin(行数)个int* 指针 for(i=0;i b[i]=new int[col]; //每行有col(列数)个int数 for(i=0;i //注意a[i][j]等同于*(a[i]+j),又等同于*( *(a+i)+j) 点评:C++对数组的说明(定义)必须是静态(固定)大小的,而通过本题提供的方法则可实现动态大小的数组。如,试图通过“int n; cin>>n; int a[n];”来说明(定义)动态大小之数组a的方法是错误的(语法错,要求n必须是常量)! 9. 编程序,按如下方法求A矩阵的转置矩阵B:输入两个正整数m和n,而后通过使用指针配合new运算符生成一个m行n列的二维动态数组A以及另一个n行m列的二维动态数组B,之后为A输入数据(A矩阵数据),进而求出其转置矩阵B(数据放动态数组B中)并输出结果。 10. 编程序,按如下要求来求解n元一次线性方程组(假设方程组具有唯一解)。 (1)方程个数n之值由用户通过键盘输入; (2)方程组存放在“增广矩阵”A之中,而n行n+1列的A存储空间通过new来动态分配,且A的各元素值也由用户通过键盘输入; (3)方程组的解存放于“向量”B之中,而具有n个元素的B存储空间也通过new来动态分配。 提示:将整个求解任务(总任务)进行“分解”,设计出多个各负其责的自定义函数以完成各子任务。 求解n元一次线性方程组,实际上是要对增广矩阵A进行“同解变换”,并最终将求出的解存放于B数组之中。而所谓的“同解变换”主要使用如下的变换方法:“将某一行的各数据乘以适当的倍数加到另一行的对应各元素上去”,从而可首先将系数矩阵消为“上三角”,而后再进行所谓的“回代过程”,最后完成求解任务。 11. 编程序,按如下要求来求解任意阶数满秩矩阵的逆矩阵。 (1) 矩阵行数(阶数)n之值由用户通过键盘输入; (2) 将欲求逆的“原始矩阵”另加一个“单位矩阵”存放在于数组A之中,而n行2n列的A存储空间通过new来动态分配,且“原始矩阵”的各元素值也由用户通过键盘输入; (3)利用行初等变换设法将A左半的“原始矩阵”化为“单位矩阵”,此时,右半的原“单位矩阵”则变成了欲求的结果逆矩阵。 提示:将整个求解任务(总任务)进行“分解”,设计出多个各负其责的自定义函数以完成各子任务。 求取逆矩阵的主要工作是:利用行初等变换(如将某一行的各数据乘以适当的倍数加到另一行的对应各元素上去),设法将A左半的“原始矩阵”化为“单位矩阵”(首先将“左半”消为“上三角”;又将“左半”主对角线消为1;最后将“左半”消为单位矩阵),此时,右半的原“单位矩阵”则变成了欲求的逆矩阵。 12. 使用如下的complex结构类型以及随后的main“骨架”程序,来完成5对复数的加法运算并输出计算结果。 struct complex { double r; double i; }; void main() { complex c0={1,2}, cA[5]={ {3,6}, {-3,-2}, {2,-8}, {-5,-8}, {1,0} }; for(int i=0; i<5; i++) … //求出c0与各cA[i]的和并输出 } 如,程序执行后,可显示如下结果: (4,8); (-2,0); (3,-6); (-4,-6); (2,2); 13. 从键盘输入n个int型数据表示n个“学号”,又输入n个double型数据表示n个“成绩”(其中n为有名常量);而后求出n个成绩中的最大者,并输出其学号与成绩。 要求按照如下两种形式的数据结构来存放输入数据并编制两个不同的程序来实现。 数据形式一(对应于程序一): const int n=6; struct myStruType1 { //具有两个数组分量的结构类型myStruType1 int regNum[n]; //分量为int型数组(用来存放n个“学号”) double score[n]; //分量为double型数组(用来存放n个“成绩”) }; myStruType1 a; //结构变量a,在a中存放要处理的所有数据 数据形式二(对应于程序二): const int n=6; struct myStruType2 { //具有两个简单分量的结构类型myStruType2 int regNum; //int型的分量regNum double score; //double型的分量score }; myStruType2 a[n]; //具有n个分量的数组a,每一个分量a[i]都为一个myStruType2类型 //的结构,在a数组的各分量中存放要处理的数据 例如,程序执行后,屏幕显示结果可为: Input 6 regNums: 1001 1002 1003 1004 1005 1006 Input 6 scores: 88.5 79 91.5 86 89 80 regNum=1003 maxScore=91.5 14. 使用如下的complex结构类型以及随后的自定义函数和main“骨架”程序, 来完成5对复数的加法运算并输出计算结果。 struct complex { double r; double i; }; complex add(complex c1, complex c2); //自定义函数add,求出c1、c2的和并返回 void out(complex& c); //自定义函数out,按格式输出复数c void main() { complex tmp, c0={1,2}, cA[5]={ {3,6}, {-3,-2}, {2,-8}, {-5,-8}, {1,0} }; for(int i=0; i<5; i++) //通过调用add和out,求出c0与各cA[i]的和并输出 … } 使程序执行后,可显示出如下结果: (4,8); (-2,0); (3,-6); (-4,-6); (2,2); 15. 程序通过使用如下类型的结构来形成动态链表: struct item { //结构类型,用于形成链表项 int data; //存放数据 item * next; //指向本结构的指针,由它“串联”起后项 }; 而后从键盘输入10个int型数据,并将它们存放在通过指针和new而动态生成的各链表项之中(总是将新链表项“插入”到当前已有链表的头位置处);最后再从链表中取出各数据(后放入的必然先取出)并显示在屏幕上(从而实现了反序输出问题)。 16. 修改“6.5.2 构建人员档案链表”一节中program6_3.cpp的程序,使其执行时,若用户一上来就输入“*”,也将立即正确结束而不会出现任何错误。 17. 进一步修改“6.5.2 构建人员档案链表”一节中program6_3.cpp的程序,使它完成以下4项具体工作: 1) 读入若干个人员的档案资料(读入“*”符号时结束输入),动态生成链表项,并将输入的档案资料存放于链表项之中,而后总将新链表项加入到原链表的末尾; 2) 遍历链表,输出整个链表的各项内容; 3) 在链表首加入一项,其name=\,age=20,sex='M'; 4) 统计出当前链表中共有多少男士,并计算出他们的平均年龄。 18. 编程序,使用链表来实现如下问题:有12人围坐成一圈(沿顺时针方向依次编号为1到12),按规则淘汰其中11人后(沿顺时针方向每当数到k时,那一人员就被“淘汰出局”),输出最后所剩那一个人的编号,并输出淘汰过程的“中间结果数据”。 提示:使用环形链表形式(末项的后继为首项)来存放各数据(人员编号),并参看第4章练习题35的数组实现方法。 点评:若将人数12改为10(或其他正整数)的话,则可以对10(或其他指定个数)人的情况进行处理。 19. 按下述方法设计一个排序程序:使用由结构形成的链表来存放数据;总保障,在把第i个数据插入到链表以前,链表中当前已有的i-1个数据已经是有序的(i=1,2,…,即是说,每次总是在原有有序链表的适当位置插入新数据,而保障插入后的链表仍有序。注意i=1时,链表为“空”显然满足条件)。 提示:可定义如下的数据结构以及指针变量first与last,而后从键盘输入n个数据,依次“插入”到以first指向其首、以last指向其末的有序链表之中,最终实现n个int型数据的从小到大排序,并输出排序结果。 struct item { //使用item结构来形成链表项 int dat; //放欲排序的数据 item* next; //指向其后项,“串联”成为链表 }; item* first=NULL, *last=NULL; // first指向链表首项,last指向链表末项 //赋予初值NULL意味着起始时链表为“空”。 思考:假设已经有两个都按升序排列的有序链表,现要将两者合并后形成一个新的有序链表(仍按升序排列,且保持原有的两个有序链表不被破坏)。则可考虑利用上述形成有序链表的方法以及“二路归并”的技术来实现。 20. 利用由结构类型chNode形成的“链表”来存储字符串(串中的每一个字符占用一个链表项,字符本身存放在链表项的c分量中,而使用链表项的next分量去“串接”后继项)。 struct chNode { char c; //存放一个字符 chNode* next; //“串接”后继项 }; 并编制具有如下功能的函数,对此种不同链表中的字符串进行处理。 (1) void catStr (char* a, chNode* p); 将a字符串中的所有字符“串接”到以p指向其首的“链串”的后面(尾部)。 (2) void displayStr (chNode* p); 屏幕输出以p指向其首的“链串”中的所有字符(一个字符串)。 (3) void getStr (char *b, chNode* p); 将以p指向其首的“链串”中的所有字符(一个字符串)取出放入字符数组b之中。 点评:使用这种方式可以存放任意长度的字符串。但要对存储在上述这种链表结构中的字符串进行处理,总要涉及到对链表的所谓“遍历”过程(因为只有从链首“走到”链尾才能找出那一个字符串的所有各字符,才能对它们进行规定的处理)。 思考:可增加其他自定义函数,用于实现另外关心的字符串处理功能。 21. 读下述程序,其中使用了引用型参数以及返回引用的函数,请给出程序执行后的输出结果。 #include void f1(int a, int& b) { cout<<\ a+=10; b+=10; } int& f2(int& a, int& b) { cout<<\ if( (a+b) %2 ==0 ) return a; else return b; } void main() { int x=1, y=2, z=3, w=0; f1(x,y); cout<<\ cout<<\ w=f2(z,k)++; cout<<\ w=f2(z,k)++; cout<<\} 注释:引用参数是其对应实参变量的“替身”,函数中对引用参数值的使用与更改就是对其对应实参变量值的使用与更改。若函数的返回值为引用,则返回的不仅是一个值,而且还代表一个可以作为“左值”的存储空间,从而可在函数调用结果上直接进行诸如“f2(z,k)++”这样的运算。 通过引用参数与指针参数都可以实现主调函数与被调函数间数据的所谓“双向传值”,但引用参数更“直接” — 它是实参变量的一个“替身”,而指针形参则是“间接”的 — 被调函数中要更改形参指针所指向的变量值(而并不是更改形参指针变量本身的值)。 第七章 输入输出流 思 考 题 1. C++语言的流类库和C语言的I/O输出语句相比有什么优点? 2. 流类库是通过什么机制使得I/0变得简单明了? 3. 什么是类型安全?类型安全是怎样实现的? 4. 流类库是怎样实现易于扩充性的? 5. 详述文件的概念,文件的种类有几种?程序中的文件概念和普通文件的概念有什么不同? 6. 什么是流?流的概念和文件的概念有什么异同? 7. C++中为流定义了哪些类?它们之间的继承关系是什么? 8. C++为用户预定义了那几个标准流(类对象)?分别代表什么含义? 9. 通常如何对自定义类重载插入与提取运算符(“<<”与“>>”)?为什么要对它们进行重载? 百度搜索“70edu”或“70教育网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,70教育网,提供经典综合文库第一章 绪论(5)在线全文阅读。
相关推荐: