C++编程思想 答案 第四章 其他章节请点击用户名找 thinking in C++ annotated solution guide(charpter 4).doc_第1页
C++编程思想 答案 第四章 其他章节请点击用户名找 thinking in C++ annotated solution guide(charpter 4).doc_第2页
C++编程思想 答案 第四章 其他章节请点击用户名找 thinking in C++ annotated solution guide(charpter 4).doc_第3页
C++编程思想 答案 第四章 其他章节请点击用户名找 thinking in C++ annotated solution guide(charpter 4).doc_第4页
C++编程思想 答案 第四章 其他章节请点击用户名找 thinking in C++ annotated solution guide(charpter 4).doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Viewing Hints Book Home Page Free Newsletter Seminars Seminars on CD ROM Consulting Annotated Solution GuideRevision 1.0for Thinking in C+, 2nd edition, Volume 1by Chuck Allison2001 MindView, Inc. All Rights Reserved. Previous Chapter Table of Contents Next Chapter Chapter 44-1In the Standard C library, the function puts( ) prints a char array to the console (so you can say puts(hello). Write a C program that uses puts( )but does not include or otherwise declare the function. Compile this program with your C compiler. (Some C+ compilers are not distinct from their C compilers; in this case you may need to discover a command-line flag that forces a C compilation.) Now compile it with the C+ compiler and note the difference.(Left to the reader)4-2Create a struct declaration with a single member function, then create a definition for that member function. Create an object of your new data type, and call the member function.(see the next exercise)4-3Change your solution to Exercise 2 so the struct is declared in a properly “guarded” header file, with the definition in one cpp file and your main( ) in another.Solution:/: S04:MyStruct.h#ifndef MYSTRUCT_H#define MYSTRUCT_Hstruct MyStruct void f();#endif /:/: S04:MyStruct.cpp O#include MyStruct.h#include using namespace std;void MyStruct:f() cout MyStruct:fn; /:/: S04:Exercise3.cpp/L MyStruct#include MyStruct.hint main() MyStruct m; m.f();/:The #ifndef statement in MyStruct.h guarantees that the file will not be included more than once in any compilation, which isnt an issue here, but in large projects its not unusual for header files to be logically included multiple times. The defined preprocessor operator provides an alternate means of checking for defined preprocessor symbols, as follows:#if !defined(MYSTRUCT_H) This form allows multiple conditions to be tested with logical connectives such as |and &.4-4Create a struct with a single int data member, and two global functions, each of which takes a pointer to that struct. The first function has a second int argument and sets the structs int to the argument value, the second displays the int from the struct. Test the functions.(see the next exercise.)4-5Repeat Exercise 4 but move the functions so they are member functions of the struct, and test again.Solution:/: S04:GetSet.cpp#include using namespace std;struct HasInt int x; void setInt(int newX) x = newX; int getInt() return x; ;int main() HasInt h; h.setInt(5); cout h.getInt() endl; / 5/:It is very common for a class to have such get- and set-members like this one does. In this example I could have separated the class definition and the member function implementation like I did in exercise number 3 above, but I didnt for two reasons: 1) Im lazy, and 2) I wanted to remind you that when you define member function bodies in situ like this (i.e., inside the class definition), they are implicitly inline functions.4-6Create a class that (redundantly) performs data member selection and a member function call using the this keyword (which refers to the address of the current object).Solution:/: S04:UsesThis.cpp#include using namespace std;struct HasInt int x; void setInt(int x) this-x = x; int getInt() return this-x; void display() cout getInt() endl; ;int main() HasInt h; h.setInt(5); h.display(); / 5/:This is a variation on the previous exercise. The use of this is actually necessary in HasInt:setInt to disambiguate the parameter x from the member x.4-7Make a Stash that holds doubles. Fill it with 25 double values, then print them out to the console.(Left to the reader)4-8Repeat Exercise 7 with Stack.(Left to the reader)4-9Create a file containing a function f( ) that takes an int argument and prints it to the console using the printf( ) function in by saying: printf(“%dn”, i) in which i is the int you wish to print. Create a separate file containing main( ), and in this file declare f( ) to take a float argument. Call f( ) from inside main( ). Try to compile and link your program with the C+ compiler and see what happens. Now compile and link the program using the C compiler, and see what happens when it runs. Explain the behavior.Solution:This exercise illustrates type-safe linkage. In C+ function name are decorated (aka mangled) to include information about their arguments. The consequence is that the name the linker sees is actually quite different than what you see. For example, f(int) might appear to the linker as f_F1i (a function taking one int), say, and f(double) as f_F1d. Since the names are distinct, you get a linker error. In C the names are the same, allowing you to call f(double) with an int, which is an error.4-10Find out how to produce assembly language from your C and C+ compilers. Write a function in C and a struct with a single member function in C+. Produce assembly language from each and find the function names that are produced by your C function and your C+ member function, so you can see what sort of name decoration occurs inside the compiler.Solution:For f(int) one compiler generated the name ?fYAXHZ, and ?fYAXNZ for f(double). Go figure.4-11Write a program with conditionally-compiled code in main( ), so that when a preprocessor value is defined one message is printed, but when it is not defined another message is printed. Compile this code experimenting with a #define within the program, then discover the way your compiler takes preprocessor definitions on the command line and experiment with that.(Left to the reader)4-12Write a program that uses assert( ) with an argument that is always false (zero) to see what happens when you run it. Now compile it with #define NDEBUG and run it again to see the difference.(Left to the reader)4-13Create an abstract data type that represents a videotape in a video rental store. Try to consider all the data and operations that may be necessary for the Videotype to work well within the video rental management system. Include a print( ) member function that displays information about the Video.(Left to the reader)4-14Create a Stack object to hold the Video objects from Exercise 13. Create several Video objects, store them in the Stack, then display them using Video:print( ).(Left to the reader)4-15Write a program that prints out all the sizes for the fundamental data types on your computer using sizeof( ).Solution:/: S04:Sizeof.cpp#include int main() using namespace std; cout sizeof(char) endl; cout sizeof(short) endl; cout sizeof(int) endl; cout sizeof(long) endl; cout sizeof(float) endl; cout sizeof(double) endl; cout sizeof(long double) endl;/* Output:1244488*/:As you can see above, this particular (32-bit) compiler uses the same size for int and long, and for double and long double. Another compiler I have uses 10 bytes for a long double, giving greater precision for numeric calculations.4-16Modify Stash to use a vector as its underlying data structure.(Left to the reader)4-17Dynamically create pieces of storage of the following types, using new: int, long, an array of 100 chars, an array of 100 floats. Print the addresses of these and then free the storage using delete.Solution:/: S04:Storage.cpp#include int main() using namespace std; int* p_int = new int; long* p_long = new long; char* p_chars = new char100; float* p_floats = new float100; cout p_int = p_int endl; cout p_long = p_long endl; cout p_chars = static_cast(p_chars) endl; cout p_floats = p_floats endl; delete p_int; delete p_long; delete p_chars; delete p_floats;/* Output:/ Compiler A:p_int = 00673384p_long = 00673394p_chars = 006733A4p_floats = 0067340C/ Compiler B:p_int = 00770950p_long = 00770940p_chars = 007708D0p_floats = 00770630*/:The static_cast above is necessary because the output stream insertion operator is overloaded to treat a char* as a null-terminated string. All other pointers have their addresses printed out in hexadecimal. Dont forget to use the brackets with delete for arrays. Notice that the way a compiler allocates things on the stack is its business dont count on any common behavior across platforms.4-18Write a function that takes a char*argument. Using new, dynamically allocate an array of charthat is the size of the char array thats passed to the function. Using array indexing, copy the characters from the argument to the dynamically allocated array (dont forget the null terminator) and return the pointer to the copy. In your main( ), test the function by passing a static quoted character array, then take the result of that and pass it back into the function. Print both strings and both pointers so you can see they are different storage. Using delete, clean up all the dynamic storage.Solution:/: S04:StringCopy.cpp#include #include #include / For size_tusing namespace std;char* copy(char* s1) size_t len = strlen(s1); char* s2 = new charlen + 1; strcpy(s2, s1); return s2; int main() char* first = Read my lips; char* second = copy(first); cout first = first at static_cast(first) endl; cout second = second at static_cast(second) endl; delete second;/* Output:first = Read my lips at 0041914Csecond = Read my lips at 00673384*/:The copy function above uses two library functions defined in : strlen to determine the length of the incoming string, and strcpy to copy one string to another (including the null terminator). size_t is an unsigned integer type (usually unsigned int) defined in various places, including , and is the return type of strlen. See the previous exercise for an explanation of the casts used.4-19Show an example of a structure declared within another structure (a nested structure). Declare data members in both structs, and declare and define member functions in both structs. Write a main( ) that tests your new types.Solution:/: S04:Nested.cpp#include struct Outer int o; void setO(int n) o = n; int getO() return o; struct Inner int i; void setI(int n) i = n; int getI() return i; ;int main() using namespace std; Outer o; o.setO(1); cout o.getO() endl; Outer:Inner i; i.setI(2); cout i.getI() endl;/* Output:12*/:Declaring a struct within a struct places the inner in the scope of the outer. For this reason I have to use the expression Outer:Inner above. Nesting structures in this fashion shows an ownership relationship between types and also minimizes the chance of name conflict in the global namespace.4-20How big is a structure? Write a piece of code that prints the size of various structures. Create structures that have data members only and ones that have data members and function members. Then create a structure that has no members at all. Print out the sizes of all these. Explain the reason for the result of the structure with no data members at all.Solution:/: S04:StructSize.cpp#include struct DataOnly int x;struct Both int x; void setX(int); int getX();struct Nothing ;int main() using namespace std; cout sizeof(DataOnly) endl; cout sizeof(Both) endl; cout sizeof(Nothing) endl;/* Output:441*/:As you can see in this program, the presence of a (non-virtual) member function does not affect the size of a struct. (NOTE: this is only true for classes with no virtual functions see Chapter 15). The standard requires all structs to have non-zero size, even if they have no members. This is so that distinct objects of any type will have distinct memory addresses.4-21C+ automatically creates the equivalent of a typedef for structs, as youve seen in this chapter. It also does this for enumerations and unions. Write a small program that demonstrates this.(Left to the reader)4-22Create a Stack that holds Stashes. Each Stash will hold five lines from an input file. Create the Stashes using new. Read a file into your Stack, then reprint it in its original form by extracting it from the Stack.(Left to the reader)4-23Modify Exercise 22 so that you create a struct that encapsulates the Stack of Stashes. The user should only add and get lines via member functions, but under the covers the structhappens to use a Stack of Stashes.(Left to the reader)4-24Create a struct that holds an int and a pointer to another instance of the same struct. Write a function that takes the address of one of these structs and an int indicating the length of the list you want created. This function will make a whole chain of these structs (a linked list), starting from the argument (the head of the list), with each one pointing to the next. Make the new structs using new, and put the count (which object number this is) in the int. In the last structin the list, put a zero value in the pointer to indicate that its the end. Write a second function that takes the head of your list and moves through to the end, printing out both the pointer value and the int value for each one.(Left to the reader)4-25Repeat Exercise 24, but put the functions inside a struct instead of using “raw” structs and functions.Solution:/: S04:LinkedList.cpp#include #include using namespace std;struct Node int val; Node* next;void create(Node* head, int howMany) assert(head); Node* p1 = head; for (int i = 1; i val = i; p1-next = p2; p1 = p2; p1-next = 0;void display(Node* node) assert(node); while (node) cout val (at node next; void cleanup(Node* node) if (node) cleanup(node-next); cout deleting Node at node val = 0; create(head, 10); display(head); cleanup(head);/* Output:0 (at 00770950)1 (at 00770940)2 (at 00770930)3 (at 00770920)4 (at 00770910)5 (at 00770900

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论