c 第10.11.12章作业(部分)
- 格式:doc
- 大小:549.50 KB
- 文档页数:9
新标准C++程序设计教材11-20章课后题答案第11章:1.简述结构化程序设计有什么不足,面向对象的程序如何改进这些不足。
答案:结构化程序设计的缺点:(1)用户要求难以在系统分析阶段准确定义,致使系统在交付使用时产生许多问题。
(2)用系统开发每个阶段的成果来进行控制,不适应事物变化的要求。
(3)系统的开发周期长。
面向对象的程序设计如何改进这些不足:面向对象程序设计技术汲取了结构忧程序设计中好的思想,并将这些思想与一些新的、强大的理念相结台,从而蛤程序设计工作提供了一种全新的方法。
通常,在面向对象的程序设计风格中,会将一个问题分解为一些相互关联的子集,每个子集内部都包含了相关的数据与函数。
同时会以某种方式将这些子集分为不同等级,而一个对象就就是已定义的某个类型的变量。
2.以下说怯正确的就是( )。
A、每个对象内部都有成员函数的实现代码B、一个类的私有成员函数内部不能访问本类的私有成员变量C、类的成员函数之间可以互相调用D、编写一个类时,至少要编写一个成员函数答案:C3.以下对类A的定义正确的就是( )。
A.class A{B.class A{private: int v; int v; A * next;public: void Func() {} void Func() {}} };C.class A{ D、class A{int v; int v;public: public:void Func(); A next;}; void Func() {}A::void Func() { } };答案:B4.假设有以下类A:class A{public:int func(int a) { return a * a; }};以下程序段不正确的就是( )。
A.A a; a、func(5);B.A * p = new A; p->func(5);C.A a; A&r =a ; r、func(5);D.A a,b; if(a!=b) a、func(5);答案:D5.以下程序段不正确的就是(A)。
[ 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 Allison©2001 MindView, Inc. All Rights Reserved.[ Previous Chapter ] [ Table of Contents ] [ Next Chapter ] Chapter 1111-1Turn the “bird & rock”code fragment at the beginning of this chapter into a C program (using struct s for the data types), and show that it compiles. Now try to compile it with the C++ compiler and see what happens.(Left to the reader)11-2Take the code fragments in the beginning of the section titled “References in C++”and put them into a main( ). Add statements to print output so that you can prove to yourself that references are like pointers that are automatically dereferenced.(Left to the reader)11-3Write a program in which you try to (1) Create a reference that is not initialized when it is created. (2) Change a reference to refer to another object after it is initialized. (3) Create a NULL reference.(Left to the reader)11-4Write a function that takes a pointer argument, modifies what the pointer points to, and then returns the destination of the pointer as a reference.(Left to the reader)11-5Create a class with some member functions, and make that the object that is pointed to by the argument of Exercise 4. Make the pointer a const and make some of the member functions const and prove that you can only call the const member functions inside your function. Make the argument to your function a reference instead of a pointer.(Left to the reader)11-6Take the code fragments at the beginning of the section titled “Pointer references”and turn them into a program.(Left to the reader)11-7Create a function that takes an argument of a reference to a pointer to a pointerand modifies that argument. In main( ), call the function.(Left to the reader)11-8Create a function that takes a char& argument and modifies that argument. In main( ), print out a char variable, call your function for that variable, and print it out again to prove to yourself that it has been changed. How does this affect program readability?Solution://: S11:CallByRef.cpp#include <iostream>void nextc(char& c) {static char letter = 'a';c = letter++;}int main() {using namespace std;char c = 'z';cout << "c == " << c << endl;nextc(c);cout << "c == " << c << endl;nextc(c);cout << "c == " << c << endl;}/* Output:c == zc == ac == b*////:~A C programmer will find it very strange indeed that c is changed in main( ), since a pointer wasn’t passed. Pass-by-reference semantics have side effects and should be used sparingly. A good example is istream::get(char&c). Since stream functions return a reference to the stream itself so you can immediately test it for end-of-file, the character extracted from the input stream is stored via the reference argument c.11-9Write a class that has a const member function and a non-const member function. Write three functions that take an object of that class as an argument; the first takes it by value, the second by reference, and the third by const reference. Inside the functions, try to call both member functions of your class and explain the results.(Left to the reader)11-10(Somewhat challenging) Write a simple function that takes an int as an argument, increments the value, and returns it. In main( ), call your function. Now discover how your compiler generates assembly code and trace through the assembly statements so that you understand how arguments are passed and returned, and how local variables are indexed off the stack.(Left to the reader)11-11Write a function that takes as its arguments a char, int, float, and double. Generate assembly code with your compiler and find the statements that push the arguments on the stack before a function call.(Left to the reader)11-12Write a function that returns a double. Generate assembly code and determine how the value is returned.(Left to the reader)11-13Produce assembly code for PassingBigStructures.cpp. Trace through and demystify the way your compiler generates code to pass and return large structures.(Left to the reader)11-14Write a simple recursive function that decrements its argument and returns zero if the argument becomes zero, otherwise it calls itself. Generate assembly code for this function and explain how the way that the assembly code is created by the compiler supports recursion.(Left to the reader)11-15Write code to prove that the compiler automatically synthesizes a copy-constructor if you don’t create one yourself. Prove that the synthesized copy-constructor performs a bitcopy of primitive types and calls the copy-constructor ofuser-defined types.Solution://: S11:AutoCopy.cpp#include <iostream>using namespace std;class Inner {double x;public:Inner(double x) {this->x = x;}Inner(const Inner& i2) {x = i2.x;cout << "Inner::Inner(const Inner&)\n";}double getX() const {return x;}};class Outer {Inner m;int n;public:Outer(double x, int i) : m(x), n(i) {}void print() {cout << '(' << m.getX() << ',' << n << ")\n";}};int main() {Outer o1(10.0, 20);o1.print();Outer o2(o1);o2.print();}/* Output:(10,20)Inner::Inner(const Inner&)(10,20)*////:~Class Outer contains an instance of class Inner and an int, but it has no copy constructor, so the compiler will build one for us. Class Inner has a copy constructor that announces itself so you can see that it executes, and the subsequent call to Outer::print( ) also reveals that the int member was copied correctly.11-16Write a class with a copy-constructor that announces itself to cout. Now create a function that passes an object of your new class in by value and another one that creates a local object of your new class and returns it by value. Call these functions to prove to yourself that the copy-constructor is indeed quietly called when passing and returning objects by value.Solution://: S11:TraceCopies.cpp#include <iostream>using namespace std;class Trace {int n;public:Trace(int n) {cout << "Trace::Trace(" << n << ")\n";this->n = n;}Trace(const Trace& t) {cout << "Trace::Trace(const Trace&)\n";n = t.n;}int getN() const {return n;}};void f(Trace t) {cout << "f(" << t.getN() << ")\n"; }Trace g() {Trace t(2);return t;}Trace h(int n) {return n;}int main() {Trace t1 = 1;f(t1);Trace t2 = g();Trace t3 = h(3);}/* Output:* Compiler A:Trace::Trace(1)Trace::Trace(const Trace&)f(1)Trace::Trace(2)Trace::Trace(const Trace&)Trace::Trace(const Trace&)Trace::Trace(3)Trace::Trace(const Trace&)* Compiler B:Trace::Trace(1)Trace::Trace(const Trace&)f(1)Trace::Trace(2)Trace::Trace(const Trace&)Trace::Trace(3)*////:~Simply define a copy constructor that announces itself. Remember that if you define any constructor at all (including a copy constructor), the compiler will not synthesize a default constructor for you, so I needed to define some constructorother than the copy constructor so I can create Trace objects. I chose to take an int argument so I can better trace through the hidden operations.Compiler A performs no optimizations so you can see all the possible operations. The first line is the creation of t1, and the next two are the call that passes t1 to f( ). The call to g( ) invokes two calls to the copy constructor: one to create the return value, and another to initialize t2 with that value. Notice that h( ) returns a Trace object by value, but instead of using the copy constructor it uses the single-arg constructor that takes an int. That’s because we’re asking the compiler to create a Trace object from an int. The bottom line is, whenever an object is created, some constructor is called; which one depends on the context.Compiler B is a lot smarter than Compiler A when it comes to creating copies.11-17Create a class that contains a double*. The constructor initializes the double* by calling new double and assigning a value to the resulting storage from the constructor argument. The destructor prints the value that’s pointed to, assigns that value to -1, calls delete for the storage, and then sets the pointer to zero. Now create a function that takes an object of your class by value, and call this function in main( ). What happens? Fix the problem by writing a copy-constructor.Solution://: S11:ShallowCopy.cpp#include <iostream>using namespace std;class HasPointer {double* p;public:HasPointer(double x) {p = new double(x);}~HasPointer() {cout << "~HasPointer()\n";delete p;}void print() {cout << *p << endl;}};void f(HasPointer hp){hp.print();}int main() {HasPointer hp(5);f(hp);}/* Output:5~HasPointer()~HasPointer()<access violation error...!!!>*////:~(As a side note, notice that you can use constructor syntax to initialize built-in types in new expressions, as in the constructor for HasPointer.)When you call f(hp), a copy of hp is passed to f( ), the destructor of which executes when that copy is no longer needed. Problem is, the destructor deletes p, so when the destructor runs again to destroy hp as main( ) completes, it tries to delete p asecond time! The solution is to have the compiler perform a deep copy of HasPointer objects via an appropriate copy constructor, such as:HasPointer(const HasPointer& rhs) {p = new double(*rhs.p);}As a rule, a class with a pointer member probably needs a copy constructor (and as you’ll see in the next chapter, an appropriate assignment operator too).11-18Create a class with a constructor that looks like a copy-constructor, but that has an extra argument with a default value. Show that this is still used as thecopy-constructor.Solution://: S11:ExtraArgs.cpp#include <iostream>using namespace std;class HasPointer {double* p;public:HasPointer(double x) {p = new double(x);}HasPointer(const HasPointer& rhs, bool b = true) { p = new double(*rhs.p);if (b)cout << "copied a " << *p << endl;}~HasPointer() {cout << "~HasPointer()\n";delete p;}void print() {cout << *p << endl;}};void f(HasPointer hp){hp.print();}int main() {HasPointer hp1(5);f(hp1);HasPointer hp2(hp1, false);}/* Output:copied a 55~HasPointer()~HasPointer()~HasPointer()*////:~This is just the previous exercise modified to take an optional second argument in its copy constructor. Notice that I don’t get a trace for hp2, since I explicitly passed a false to the copy constructor.11-19Create a class with a copy-constructor that announces itself. Make a second classcontaining a member object of the first class, but do not create a copy-constructor. Show that the synthesized copy-constructor in the second class automatically calls the copy-constructor of the first class.Solution:This was already illustrated in Exercise 15.11-20Create a very simple class, and a function that returns an object of that class by value. Create a second function that takes a reference to an object of your class. Call the first function as the argument of the second function, and demonstrate that the second function must use a const reference as its argument.Solution://: S11:RefToTemp.cpp//=M @echo compile RefToTemp.cpp by hand#include <iostream>class Simple {int i;public:Simple() : i(1) {}int getI() const {return i;}void setI(int n) {i = n;}};Simple f() {return Simple();}void g(Simple& s) {using namespace std;cout << "before: " << s.getI() << endl;s.setI(2);cout << "after: " << s.getI() << endl; }int main() {g(f());}///:~This should fail to compile unless you define the signature of g as g(const Simple& ). The reason is that a non-const reference may alter the contents of its argument, so it needs writable storage connected to it. A temporary like the return from f( ) is destroyed as soon as it is no longer needed (i.e., at the end of its containing expression), hence trying to write to such temporary storage is a mistake. Some compilers still allow this, unfortunately.11-21Create a simple class without a copy-constructor, and a simple function that takes an object of that class by value. Now change your class by adding aprivate declaration (only) for the copy-constructor. Explain what happens when your function is compiled.(Left to the reader)11-22This exercise creates an alternative to using the copy-constructor. Create a classX and declare (but don’t define) a private copy-constructor. Make a public clone( ) function as a const member function that returns a copy of the object that is created using new. Now write a function that takes as an argument a const X& and clones a local copy that can be modified. The drawback to this approach is that you are responsible for explicitly destroying the cloned object (using delete) when you’re done with it.(Left to the reader)11-23Explain what’s wrong with both Mem.cpp and MemTest.cpp from Chapter 7. Fix the problem.(Left to the reader)11-24Create a class containing a double and a print( ) function that prints the double. In main( ), create pointers to members for both the data member and the function in your class. Create an object of your class and a pointer to that object, and manipulate both class elements via your pointers to members, using both the object and the pointer to the object.Solution://: S11:MemPtr.cpp#include <iostream>using namespace std;class HasDouble {public:double x;HasDouble(double x) {this->x = x;}void print() {using namespace std;cout << x << endl;}};int main() {HasDouble h(3);HasDouble* hp = &h;// Define pointers-to-members:double HasDouble::* px = &HasDouble::x;void (HasDouble::*pmf)() = &HasDouble::print;// Call via object:cout << h.*px << endl;(h.*pmf)();// Call via pointer-to-object:cout << hp->*px << endl;(hp->*pmf)();}/* Output:3333*////:~Things to remember:•Wherever you would normally put a * in a regular pointer declaration, use C::* instead, where C is your class name.•Wherever you would normally use & to get a pointer, use &C:: instead.•Use parentheses around the pointer-to-member function expression, both in the call as well as in the declaration.11-25Create a class containing an array of int. Can you index through this array using a pointer to member?Yes, you can. The declaration of the pointer is a little tricky, though. It has to do with the fact that pointers to arrays are different than pointers to objects. In the following example, pa is a pointer-to-member that refers to an array of 5 int s.Solution://: S11:PointerToMemArray.cpp#include <iostream>class HasArray {public:enum {LEN = 5};int a[LEN];HasArray() {for (int i = 0; i < LEN; ++i)a[i] = i;}};int main() {using namespace std;HasArray h;int (HasArray::* pa)[5] = &HasArray::a;for (int i = 0; i < HasArray::LEN; ++i)cout << (h.*pa)[i] << ' ';cout << endl;}/* Output:0 1 2 3 4*////:~If I had defined a as an int* and allocated its space dynamically in the HasArrayconstructor, then the program would look like the following://: S11:PointerToMemArray.cpp#include <iostream>#include <cstddef> // For size_tclass HasArray {size_t siz;public:int* a;HasArray(size_t siz) {a = new int[siz];for (size_t i = 0; i < siz; ++i)a[i] = i;this->siz = siz;}~HasArray() {delete a;}size_t size() const {return siz;}};int main() {using namespace std;HasArray h(5);int* HasArray::* pa = &HasArray::a;for (size_t i = 0; i < h.size(); ++i)cout << (h.*pa)[i] << ' ';cout << endl;}/* Output:0 1 2 3 4*////:~11-26Modify PmemFunDefinition.cpp by adding an overloaded member function f( ) (you can determine the argument list that causes the overload). Now make a second pointer to member, assign it to the overloaded version of f( ), and call the function through that pointer. How does the overload resolution happen in this case?(Left to the reader)11-27Start with FunctionTable.cpp from Chapter 3. Create a class that contains a vector of pointers to functions, with add( ) and remove( ) member functions to add and remove pointers to functions. Add a run( ) function that moves through the vector and calls all of the functions.(Left to the reader)11-28Modify the above Exercise 27 so that it works with pointers to member functions instead.(Left to the reader)[ Previous Chapter ] [ Table of Contents ] [ Next Chapter ]Last Update:06/27/2002。
第十章齿轮传动10.1渐开线性质有哪些?。
答:(1)发生线在基圆上滚过的长度等于基圆上被滚过的弧长,即NK=NA (2)因为发生线在基圆上作纯滚动,所以它与基圆的切点N就是渐开线上K点的瞬时速度中心,发生线NK就是渐开线在K点的法线,同时它也是基圆在N点的切线。
(3)切点N是渐开线上K点的曲率中心,NK是渐开线上K点的曲率半径。
离基圆越近,曲率半径越少。
(4)渐开线的形状取决于基圆的大小。
基圆越大,渐开线越平直。
当基圆半径无穷大时,渐开线为直线。
(5)基圆内无渐开线。
10.2何谓齿轮中的分度圆?何谓节圆?二者的直径是否一定相等或一定不相等?答:分度圆为人为定的一个圆。
该圆上的模数为标准值,并且该圆上的压力角也为标准值。
节圆为啮合传动时,以两轮心为圆心,圆心至节点p的距离为半径所作的圆。
标准齿轮采用标准安装时,节圆与分度圆是相重合的;而采用非标准安装,则节圆与分度圆是不重合的。
对于变位齿轮传动,虽然齿轮的分度圆是不变的,但与节圆是否重合,应根据具体的传动情况所决定。
10.3在加工变位齿轮时,是齿轮上的分度圆与齿条插刀上的节线相切作纯滚动,还是齿轮上的节圆与齿条插刀上的分度线相切作纯滚动?答:是齿轮上的分度圆与齿条插刀上的节线相切。
10.4为了使安装中心距大于标准中心距,可用以下三种方法:(1)应用渐开线齿轮中心距的可分性。
(2)用变位修正的直齿轮传动。
(3)用标准斜齿轮传动。
试比较这三种方法的优劣。
答:(1)此方法简易可行,但平稳性降低,为有侧隙啮合,所以冲击、振动、噪声会加剧。
(2)采用变位齿轮传动,因a'>a,所以应采用正传动。
可使传动机构更加紧凑,提高抗弯强度和齿面接触强度,提高耐磨性,但互换性变差,齿顶变尖,重合度下降也较多。
(3)采用标准斜齿轮传动,结构紧凑,且进入啮合和脱离啮合是一个逐渐的过程,传动平稳,冲击、噪声小,而斜齿轮传动的重合度比直齿轮大,所以传动平稳性好。
10.5 一渐开线齿轮的基圆半径rb=60mm,求(1)rK=70mm时渐开线的展角θK,压力角αK以及曲率半径ρK;(2)压力角α=20时的向径r、展角θ及曲率半径ρ。
《精通C程序设计教程》第十、十一章部分习题答案第十章10.2 read=0, green=1, yellow=5, white=6, black=710.6 42, 110.8#include "stdio.h"typedef struct student { long xh;char xm[21];int s1,s2,s3; } STU;#define N 5void inp_stu(STU a[N]){ int i;printf("Input %d students data\n",N);printf("xh xm s1 s2 s3\n");for(i=0;i<N;i++) scanf("%ld%s%d%d%d",&a[i].xh,a[i].xm,&a[i].s1,&a[i].s2,&a[i].s3); }void out_stu(STU a[N],int p[N]){ int i;for(i=0;i<N;i++) printf("%ld %s %d %d %d\n", \a[p[i]].xh,a[p[i]].xm,a[p[i]].s1,a[p[i]].s2,a[p[i]].s3);}#define SUM(a,i) (a[i].s1+a[i].s2+a[i].s3)void Sort(STU a[N],int p[N]) /* 索引冒泡排序*/{ int i,j,t;for(i=0;i<N;i++) p[i]=i;for(i=1;i<N;i++)for(j=0;j<N-i;j++)if(SUM(a,p[j])<SUM(a,p[j+1])) { t=p[j];p[j]=p[j+1];p[j+1]=t; }}void main(){ STU a[N];int p[N];inp_stu(a);Sort(a,p);out_stu(a,p);}10.10#include "stdio.h"#include "math.h"typedef struct { int y,m,d; } DA TE;long days(DA TE *p){ long m,n=(p->y-1)*365+(p->y-1)/4-(p->y-1)/100+(p->y-1)/400;for(m=1;m<p->m-1;m++)switch(m){ case 4:case 6:case 9:case 11:n+=30;break;case 2:n+=28+(p->y%4==0&&p->y%100!=0||p->y%400==0);break;default:n+=31;}return n;}void main(){ DA TE a1,a2;long n;while(1){ printf("Input date 1(y m d):");scanf("%d%d%d",&a1.y,&a1.m,&a1.d);if(a1.y<=0) break;printf("Input date 2(y m d):");scanf("%d%d%d",&a2.y,&a2.m,&a2.d);n=labs(days(&a1)-days(&a2));printf("The difference days=%ld\n",n);}}10.11#include "stdio.h"#include "conio.h"typedef struct { int h,m,s; } TIME;void inc_time(TIME *p){ int cy=1;p->s+=cy;cy=p->s/60;p->s%=60;p->m+=cy;cy=p->m/60;p->m%=60;p->h+=cy;}void dec_time(TIME *p){ int cy=1;p->s-=cy;cy=p->s<0;p->s=(p->s%60+60)%60;p->m-=cy;cy=p->m<0;p->m=(p->m%60+60)%60;p->h-=cy;}void main(){ char ch;TIME t;printf("Input a time(h m s):");scanf("%d%d%d",&t.h,&t.m,&t.s);while(1){ ch=getche();if(ch=='+') inc_time(&t);if(ch=='-') dec_time(&t);if(ch=='Q'||ch=='q') break;printf("\r%d:%d:%d\n",t.h,t.m,t.s);}10.14#include "stdio.h" /* 本例请用C++调制*/typedef struct node { int no,quantity;struct node *next; } NodeTp; void DscIns(NodeTp *h,NodeTp *s){ NodeTp *p=h->next,*pr=h;while(p&&p->quantity>s->quantity) { pr=p;p=p->next; }pr->next=s;s->next=p;}void Out(NodeTp *h){ NodeTp *p=h->next;while(p) { printf("%d,%d\n",p->no,p->quantity);p=p->next;}}void Ers(NodeTp *h){ NodeTp *p;while(h) { p=h;h=h->next;delete p;}}void main(){ NodeTp *h,*s,*ps;int no,quantity;h=new NodeTp;h->next=NULL;while(1){ printf("Input no and quantity:");scanf("%d%d",&no,&quantity);if(no==0) break;ps=h;s=h->next;while(s&&s->no!=no) { ps=s;s=s->next; }if(s==NULL) { s=new NodeTp;s->no=no;s->quantity=quantity; } else { s->quantity+=quantity;ps->next=s->next; }DscIns(h,s);}Out(h);Ers(h);}10.15#include "stdio.h" /* 本例请用C++调试*/#define N 10typedef struct node { int data;struct node *next; } NodeTp;NodeTp *Crt(int n){ int i;NodeTp *h,*p,*last;h=new NodeTp;h->data=1;last=h;for(i=2;i<=n;i++){ p=new NodeTp;p->data=i;last->next=p;last=p;}last->next=NULL;return h;void Out(NodeTp *h){ while(h) { printf("%6d",h->data);h=h->next; }}void Ers(NodeTp *h){ NodeTp *p;while(h) { p=h;h=h->next;delete p;}}NodeTp *Chg(NodeTp *h){ NodeTp *p1,*p2,*p,*last;p1=h;if(!p1) return h;p2=h->next;if(!p2) return h;h=NULL;while(1){ p=p2->next;if(h==NULL) { h=p2;p2->next=p1;p1->next=p; }else { last->next=p2;p2->next=p1;p1->next=p; }last=p1;p1=p;if(!p1) break;p2=p->next;if(!p2) break;}return h;}void main(){ NodeTp *h=Crt(N);h=Chg(h);Out(h);printf("\n");Ers(h);}10.16#include "stdio.h"typedef struct node { int data;struct node *next; }NodeTp;void AscIns(NodeTp *h,int x) /* 带附加头结点升序链表插入结点*/ { NodeTp *pr=h,*p=h->next,*s=new NodeTp;s->data=x;while(p&&p->data<x) { pr=p;p=p->next; }pr->next=s;s->next=p;}NodeTp *Crt(){ NodeTp *h=new NodeTp;int x;h->next=NULL;printf("Input integers until input positive integers or zero:\n");while(1){ scanf("%d",&x);if(x<=0) break;AscIns(h,x);}return h;}void Out(NodeTp *h){ h=h->next;while(h) { printf("%6d",h->data);h=h->next; } }void Ers(NodeTp *h){ NodeTp *p;while(h) { p=h;h=h->next;delete p;}}void DelRep(NodeTp *h){ NodeTp *p=h->next,*pn;while(1){ pn=p->next;if(pn==NULL) break;if(pn->data==p->data) { p->next=pn->next;delete pn; }else p=pn;}}void main(){ NodeTp *h=Crt();DelRep(h);Out(h);printf("\n");Ers(h);}10.17#include "stdio.h"typedef struct node { int data;struct node *next; }NodeTp; NodeTp *Crt(){ NodeTp *h=new NodeTp,*p;int x;h->next=NULL;printf("Input integers until input positive integers:\n"); while(1){ scanf("%d",&x);if(x<=0) break;p=new NodeTp;p->data=x;p->next=h->next;h->next=p;}return h;}void Out(NodeTp *h){ h=h->next;while(h) { printf("%6d",h->data);h=h->next; } }void Ers(NodeTp *h){ NodeTp *p;while(h) { p=h;h=h->next;delete p;}}void Del(NodeTp *h){ NodeTp *pr=h,*p=h->next;while(p)if(p->data>5&&p->data<20) { pr->next=p->next;delete p;p=pr->next; }else {pr=p;p=p->next;}}void main(){ NodeTp *h=Crt();Del(h);Out(h);printf("\n");Ers(h);}10.19NodeTp *GetPre(NodeTp *p){ NodeTp *pr=p;while(pr->next!=p) { pr=pr->next; }}10.20void link(NodeTp *p){ NodeTp *pr=p,*q=p;p=p->next;while(pr!=q) { p->previous=pr;pr=p;p=p->next; }}10.27 7 3 B最初为p2指针变量分配的空间丢失第十一章11.5#include "stdio.h"void main(){ FILE *fp;int i,j,c,n,w=4;printf("Input n=");scanf("%d",&n);if(n<=0) { printf("number of rows must be greater than 0.\n");return; }fp=fopen("a2.txt","w");for(i=0;i<n;i++){ printf("%*s",w*(n-i),"");fprintf(fp,"%*s",w*(n-i),"");c=1;printf("%*d",w,c);fprintf(fp,"%*d",w,c);for(j=1;j<=i;j++) { c=c*(i-j+1)/j;printf("%*d",2*w,c);fprintf(fp,"%*d",2*w,c); } printf("\n");fprintf(fp,"\n");}fclose(fp);}11.7#include "stdio.h"void main(){ FILE *fr;int ce,cd,c;char fname[81],ch;c=ce=cd=0;printf("Input a text file name:\n");scanf("%s",fname);fr=fopen(fname,"rb");if(!fr) { printf("File %s not found.\n",fname);return; }while(1){ ch=fgetc(fr);if(feof(fr)) break;c++;if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z') ce++;if(ch>'0'&&ch<='9') cd++;}fclose(fr);printf("number of letters=%d,number of digits=%d,others=%d\n",ce,cd,c-ce-cd); }11.10#include "stdio.h"#include "math.h"void main(){ FILE *fw;int m,i,c,k;fw=fopen("prime.txt","w");if(!fw) { printf("Can't create the text file prime.txt\n");return; }fprintf(fw,"%6d",2);c=1;for(m=3;m<10000;m+=2){ k=(int)sqrt(m+1);for(i=3;i<=k;i+=2) if(m%i==0) break;if(i>k) { fprintf(fw,"%6d",m);c++;if(c%10==0) fprintf(fw,"\n"); }}fclose(fw);}11.12#include "stdio.h"void main(){ FILE *fp;char ch,fname[81];printf("Input a text file name:\n");scanf("%s",fname);fp=fopen(fname,"rb+");if(!fp) { printf("File %s not found.\n",fname);return; }ch=fgetc(fp);while(!feof(fp)){ if(ch>='A'&&ch<='Z') ch+=32;fseek(fp,-1L,SEEK_CUR);fputc(ch,fp);fseek(fp,0L,SEEK_CUR);ch=fgetc(fp);}fclose(fp);}11.22 char *argv[] 3 !feof(f1) ch, f2 11.23 0 “r”或”rb”feof(fp) ch==32 11.24 添加一行字符到字符文件b.txt11.25 A C D。
第十一章标准模板库(STL)习题一. 基本概念与基础知识自测题11.1填空题11.1.1 STL大量使用继承和虚函数是(1)(填对或错)。
因为(2)。
答案:(1)错(2)它使用的是模板技术,追求的是运行的效率,避免了虚函数的开销11.1.2 有两种STL容器:(1)和(2)。
STL不用new和delete,而用(3)实现各种控制内存分配和释放的方法。
答案:(1)第一类容器(2)近容器(3)分配子(allocator)11.1.3 五种主要迭代子类型为(1)、(2)、(3)、(4)和(5)。
STL算法用(6)间接操作容器元素。
sort算法要求用(7)迭代子。
答案:(1)输入(InputIterator)(2)输出(OutputIterator)(3)正向(ForwardIterator)(4)双向(BidirectionalIterator)(5)随机访问(RandomAccessIterator)(6)迭代子(7)随机访问(RandomAccessIterator)11.1.4 三种STL容器适配器是(1)、(2)和(3)。
答案:(1)stack(栈)(2)queue(队列)(3)priority_queue(优先级队列)11.1.5 成员函数end()得到容器(1)的位置,而rend得到容器(2)的位置。
算法通常返回(3)。
答案:(1)最后一个元素的后继位置(2)引用容器第一个元素的前导位置。
实际上这是该容器前后反转之后的end()(3)迭代子11.1.6 适配器是(1),它依附于一个(2)容器上,它没有自己的(3)函数和(4)函数,而借用其实现类的对应函数。
答案:(1)不独立的(2)顺序(3)构造函数(4)析构函数11.1.7 返回布尔值的函数对象称为(1),默认的是(2)操作符。
答案:(1)谓词(predicate)(2)小于比较操作符“<”11.1.8C++标准库中给出的泛型算法包括(1)种算法。
第十、十一章作业答案1.某系统中使用3片8259A级联,一片为主8259A,两片为从8259A。
从8259A分别接入主8259A的IR2和IR7端。
若已知当前主8259A和从8259A三片的IR3上各接有一个外部中断源,它们三片的中断类型码分别为A0H、B0H和C0H,中断入口均在同一段中,其段基址为2050H, 偏移地址分别为11A0H、22B0H和33C0H,所有中断都采用电平触发方式、完全嵌套、自动EOI方式(原题出错),除了题中接了中断源的引脚外其余IR i均屏蔽。
主8259A的端口地址为1000H和1001H,从片1的端口地址为2000H和2001H,从片2的端口地址为3000H 和3001H。
(1)画出它们的硬件连接图;(2)编写全部初始化程序和中断服务程序入口地址的装入程序,要求注释程序。
(1)(2)主片初始化程序段:MOV DX,1000HMOV AL, 19H ; ICW1OUT DX, ALMOV DX,1001HMOV AL, 0A0H ;ICW2 :中断类型码为A0H~A7HOUT DX, ALMOV AL, 84H ; ICW3: IR7,IR2上连接从片OUT DX, ALMOV AL, 3 ; ICW4OUT DX, ALMOV AL, 73H ; OCW1OUT DX, AL从片1初始化程序段:MOV DX,2000HMOV AL, 19H ; ICW1OUT DX, ALMOV DX,2001HMOV AL, 0B0H ; ICW2: 中断类型码为B0H~B7HOUT DX, ALMOV AL, 2 ;ICW3:从片的识别地址,即主片的IR2OUT DX, ALMOV AL, 3 ; ICW4OUT DX, ALMOV AL, 0F7H ; OCW1OUT DX, AL从片2初始化程序段:MOV DX,3000HMOV AL, 19H ; ICW1OUT DX, ALMOV DX,3001HMOV AL, 0C0H ; ICW2: 中断类型码为C0H~C7HOUT DX, ALMOV AL, 7 ;ICW3:从片的识别地址,即主片的IR7OUT DX, ALMOV AL, 3 ; ICW4OUT DX, ALMOV AL, 0F7H ; OCW1OUT DX, AL中断服务程序入口地址的装入程序:MOV BX,2050H ;主片装入程序MOV DS,BXMOV DX,11A0HMOV AX,25ª3HINT 21HMOV DX,22B0H ;从片1装入程序MOV AX,25B3HINT 21HMOV DX,33C0H;从片2装入程序MOV AX,25C3HINT 21H2. 系统中使用1片8259A,端口地址为3000H和3001H,中断类型码为A0H,采用电平触发方式、完全嵌套、一般EOI结束方式,通过一开关(单稳、防抖)将中断请求信号接到IR7上。
C语言习题集专业班级___________________________ 学号______________________________ 姓名______________________________第 2 章运算符与表达式、选择题1. 若有定义:int a=2,b=3 ; float x=3.5,y=2.5; 则下面表达式的值为( C )。
(float)(a+b)/2+(int)x% (int)yA)3.5 B)35 C)3.500000 D)35.000002. 若有定义:int x=3 ,y=2; float a=2.5 ,b=3.5; 则下面表达式的值为( B ) 。
(x+y)%2+(int)a/(int)bA)1.0 B)1 C)2.0 D)23. 若x和n均是int型变量,且x的初值为12, n的初值为5,则执行下面表达式后x的值为(A ) 。
x%=(n%=2)A)0 B)1 C)2 D)34. 设有int x=11; 则表达式(x++*1/3) 的值是( A ) 。
A)3 B)4 C)11 D)125. 下列程序的输出结果是( C ) 。
#include <stdio.h>main( ){ double d=3.2; int x,y;x=1.2; y=(x+3.8)/5.0;printf("%d\n", d*y);}A)3 B)3.2 C)0 D)3.076. 下列程序执行后的输出结果是(小数点后只写一位)( A ) 。
#include <stdio.h>main( ){ double d; float f; long l; int i;i=f=l=d=20/3;printf("%d %ld %f %f\n", i,l,f,d);}A)6 6 6.0 6.0 B)6 6 6.7 6.7C)6 6 6.0 6.7 D)6 6 6.7 6.07. 若已定义x和y为double类型,则表达式x=1,y=x+3/2的值是(C )。
#include<iostream>using namespace std;class Complex{public:double r,i;Complex(double=0,double=0);void display();};Complex::Complex(double x,double y){r=x;i=y;} void Complex::display(){cout<<'('<<r<<','<<i<<")\n";}Complex operator+(Complex a,Complex b){ return Complex(a.r+b.r,a.i+b.i);}void main(){Complex a(1,2),b(3,4);operator+(a,b).display();(a+b).display();}#include<iostream>using namespace std;class Complex{double r,i;public:Complex(double=0,double=0);void display();Complex operator+(Complex b);Complex operator-(Complex b);Complex operator*(Complex b);Complex operator/(Complex b);};Complex::Complex(double x,double y){r=x; i=y;}void Complex::display(){cout<<'('<<r<<','<<i<<")\n";}Complex Complex::operator+(Complex b){ return Complex(r+b.r,i+b.i);}Complex Complex::operator-(Complex b){ return Complex(r-b.r,i-b.i);}Complex Complex::operator*(Complex b){ return Complex(r*b.r-i*b.i,r*b.i+i*b.r);}Complex Complex::operator/(Complex b){ double a=b.r*b.r+b.i*b.i;return (*this)*Complex(b.r/a,-b.i/a);}void main(){Complex a(1,2),b(3,4);cout<<"a="; a.display();cout<<"b="; b.display();cout<<"a+b="; (a+b).display();cout<<"a-b="; (a-b).display();cout<<"a*b="; (a*b).display();cout<<"a/b="; (a/b).display();}#include<iostream.h>class Complex{double r,i;public:Complex(double=0,double=0);void display();operator double();Complex operator=(double);Complex operator+(Complex);Complex operator+(double);friend Complex operator+(double,Complex); };Complex::Complex(double x,double y){r=x; i=y;}void Complex::display(){cout<<'('<<r<<','<<i<<")\n";}Complex::operator double(){return r;}Complex Complex::operator=(double re){r=re; i=0;return Complex(r);}Complex Complex::operator+(Complex c){ return Complex(r+c.r,i+c.i);}Complex Complex::operator+(double re){return Complex(r+re,i);}Complex operator+(double re,Complex c){ return c+re;}void main(){Complex a(1,2); double b=3.4,d;cout<<"a+a="; (a+a).display();cout<<"a+b="; (a+b).display();cout<<"b+a="; (b+a).display();cout<<"double(b+c)="<<double(b+a)<<endl;cout<<"d=b+c="<<(d=b+a)<<endl;}#include<iostream>using namespace std;class Student{long num; char name[9],sex[3];public:Student(long nu,char *na,char *se){num=nu;for(int i=0;i<9;i++)name[i]=na[i];for(i=0;i<3;i++)sex[i]=se[i];}friend class Teacher;};class Teacher{long num; char name[9],sex[3]; public:Teacher(Student s){num=s.num;for(int i=0;i<9;i++)name[i]=[i];for(i=0;i<3;i++)sex[i]=s.sex[i];}void display(){cout<<"num:\t"<<num<<endl;cout<<"name:\t"<<name<<endl;cout<<"sex:\t"<<sex<<endl;}};void main(){Student s(101,"张三","男");Teacher t(s);t.display();}#include<string>using namespace std;class Teacher{//教师类int num;string name;char sex;public:Teacher(int n,string na,char s);void disply();};Teacher::Teacher(int n,string na,char s){ num=n;name=na;sex=s;}void Teacher::disply(){cout<<"工号:\t"<<num<<endl;cout<<"姓名:\t"<<name<<endl;cout<<"性别:\t"<<sex<<endl;}class BirthDate{//生日类int year,month,day;public:BirthDate(int y,int m,int d);void disply();};BirthDate::BirthDate(int y,int m,int d){ year=y;month=m;day=d;}void BirthDate::disply(){cout<<"生日:\t"<<year<<"年";cout<<month<<"月"<<day<<"日\n";}class Professor:public Teacher{//教授类BirthDate birthday;public:Professor(int=0,string="",char=' ',int=0,int=0,int=0);void disply();};Professor::Professor(int n,string na,char s,int y,int m,int d) :Teacher(n,na,s),birthday(y,m,d){}void Professor::disply(){Teacher::disply();birthday.disply();}void main(){Professor Prof;Prof.disply();Prof=Professor(1001,"张三",'m',1960,1,1);cout<<endl;Prof.disply();}习题12.5 抽象类Shape#include<iostream>using namespace std;class Shape{//抽象类protected:float a;public:Shape(float x){a=x;}virtual float area()=0;};class Circle:public Shape{//圆形public:Circle(float x):Shape(x){}float area(){return 3.14159*a*a;}};class Square:public Shape{//正方形public:Square(float x):Shape(x){}float area(){return a*a;}};class Rectangle:public Shape{//矩形protected:float b;public:Rectangle(float x,float y):Shape(x){b=y;}float area(){return a*b;}};class Trapezoid:public Shape{//梯形protected:float b,h;public:Trapezoid(float x,float y,float z):Shape(x){b=y;h=z;}float area(){return (a+b)*h/2;}};class Triangle:public Shape{//三角形protected:float h;public:Triangle(float x,float y):Shape(x){h=y;}float area(){return a*h/2;}};void main(){Shape *p[5];p[0]=new Circle(1);p[1]=new Square(2);p[2]=new Rectangle(3,4);p[3]=new Trapezoid(5,6,7);p[4]=new Triangle(8,9);char c[][5]={"圆","正方","矩","梯","三角"};float s=0,a;for(int i=0;i<5;i++){s+=a=p[i]->area();cout<<c[i]<<"形面积="<<a<<endl;}cout<<"总面积="<<s<<endl;}。