4.10 练习
部分练习题的答案可以在本书的电子文档“Annotated Solution Guide for Thinking in C++”中找到,只需支付很少的费用就可以从http://www.BruceEckel.com得到这个电子文档。
4-1 在标准C库中,函数puts()能显示字符数组到控制台上(所以能写puts(“hello”)。试写一个C语言程序,这个程序使用puts(),但不包含<stdio.h>,也不声明这个函数。用C编译器编译这个程序。(有些C++编译器并不与它们的C编译器分开;在这种情况下,可能需要使用一个强制C编译的命令行标记。)然后再用C++编译器对它编译,注意它们之间的区别。
4-2 创建一个struct声明,它有单个成员函数,然后为这个成员函数创建定义。创建这个新数据类型的对象,再调用这个成员函数。
4-3 改变练习2的答案,使得struct在合适的“防护”头文件中声明,同时,它的定义在一个cpp文件中,main()在另一个文件中。
4-4 创建一个struct,它有一个int数据成员,再创建两个全局函数,每个函数都接受一个指向该struct的指针。第一个函数有第二个int参数,并设置这个struct的int为它的参数值,第二个函数显示来自这个struct的int。测试这两个函数。
4-5 重写练习4,将两个函数改为这个struct的成员函数,再次测试。
4-6 创建一个类,它使用this关键字(冗余地)执行数据成员选择和成员函数调用。(this表示当前对象的地址)。
4-7 让Stash存放double,存入25个double值,然后把它们显示到控制台上。
4-8 用Stack重写练习7。
4-9 创建一个文件,包含以int为参数的函数f(),用<stdio.h>中的printf()函数将参数int的值显示到控制台上,即写printf(“%d\n”,i),这里i是希望显示的int。创建另外一个单独的文件,它包含main(),在该文件中声明f()接受float参数。从main()中调用f()。尝试用C++编译器编译和连接这个程序,看看会发生什么事情。再用C编译器编译和连接这个程序,观察运行时会发生什么事情。解释这里的行为。
4-10 发现如何由你的C编译器和C++编译器产生汇编语言。用C写一个函数和用C++写一个带有一个成员函数的struct。由每一个编译器产生汇编语言,找出由你的C函数和C++成员函数产生的函数名,这样,你能看到什么样的名字修饰出现在编译器内部。
4-11 写一个main()中有条件编译代码的程序,使得当预处理器的值被定义时打印一条消息,而不被定义时则打印另外一条消息。编译这一代码段在程序中有#define的试验代码,然后找出你的编译器在命令行上定义预处理器的方法,对它进行试验。
4-12 写一个程序,它带有参数总是为假(零)的assert(),当运行时看发生什么现象。现在用#define NDEBUG编译它,再次运行它,看有什么不同。
4-13 创建一个抽象数据类型,它表示录像带租赁店中的录像带,试考虑在录像带租赁管理系统中为使录像带(Video)类型运作良好而必须的所有数据与运算。包含一个能显示录像带Video信息的print()的成员函数。
4-14 创建一个Stack对象,能存放练习13中的Video对象。创建几个Video对象,把它们存放在Stack中,然后用Video:print()显示它们。
4-15 写一个程序,使用sizeof打印出你的编译器的所有基本数据类型的长度。
4-16 修改Stash,使用vector<char>作为它的底层数据结构。
4-17 使用new动态创建下面类型的存储块:int、long、一个能存放100个char的数组、一个能存放100个float的数组。打印它们的地址,然后用delete释放这些存储。
4-18 写一个带有char*参数的函数。用new动态申请一个char数组,长度与传给这个函数的char数组同。使用数组下标,从参数中拷贝字符到这个动态申请的数组中(不要忘记null终结符)并且返回拷贝的指针。在main()中,通过传递静态引用字符数组,测试这个函数。然后取这个结果,再传回这个函数。打印这两个字符串和这两个指针,这样我们可以看到它们是不同的存储。使用delete,清除所有的动态存储。
4-19 显示在一个结构中声明另一个结构的例子(嵌套结构),声明这两个struct的数据成员,声明和定义这两个struct的成员函数。写一个main(),测试这两个新类型。
4-20 结构有多大?写一段代码,打印几个结构的长度。创建几个只有数据成员的结构和几个既有数据成员又有函数成员的结构,然后创建一个完全没有成员的结构。打印出所有这些结构的长度。解释产生完全没有成员的结构的长度结果的原因。
4-21 C++自动创建struct的typedef的等价物,正如在本章中看到的。对于枚举和联合类型也是如此。写一个小程序来证明这一点。
4-22 创建一个存放Stash的Stack,每个Stash存放来自输入文件的5行。使用new创建Stash,读文件进入Stack,然后从这个Stack中提取并按原来的形式打印出来。
4-23 修改练习22,使得创建一个struct,它封装几个Stash的Stack。用户只能通过成员函数添加和得到一行,在这个覆盖下,struct使用Stash的Stack。
4-24 创建一个struct,它存放一个int和一个指向相同struct的另一个实例的指针。写一个函数,它能取这些struct的地址,并且能取一个表示被创建的表的长度的int。这个函数产生这些struct的一个完整链(链表),链表的头指针是这个函数的参数,struct中的指针指向下一个struct。用new产生一些新struct,将计数(对象数目)放在这个int中,对这个链表的最后一个struct的指针栏置零值,表示链表结束。写第二个函数,它取这个链表的头指针,并且向后移动到最后,打印出每个struct的指针值和int值。
4-25 重复练习24,但是将这些函数放在一个struct内部,而不是用“原始”的struct和函数。