精华内容
下载资源
问答
  • C++课本电子版

    2014-04-26 14:31:41
    C++语言是在C语言的基础上逐步发展和完善的,C语句是吸收了其它高级语言的优点逐步成为实用性很强的语言。 二十世纪六十年代,Martin Richards开发了BCPL语言(BasicCombined Programming Language)。
  • C++课本__谭浩强

    2015-08-14 18:25:43
    该文档是C++对应课本的PPT,简单明了,对应课本会更好。
  • 大学C++课本,谭浩强版,电子教案。 第1篇 基 本 知 识 第1章 C++的初步知识 第2章 数据类型与表达式 第2篇 面向过程的程序设计 第3章 程序设计初步 第4章 函数与预处理 第5章 数组 第6章 指针 ...
  • c++课本答案

    2013-07-08 15:25:05
    c++语言中的面向对象答案,课后习题的答案
  • C++课本笔记

    2012-08-30 12:11:41
    C++课本笔记
  • C++课本习题带答案

    2013-03-31 12:55:29
    这是C++资料,您书上的所有习题和答案,样样俱全,内容丰富。希望可以给您带来方便,供您参考和学习。
  • C++课程学习过程中,课本案例的代码编写
  • c++学习时候谭浩强课本中第一章例题的源码,分享给大家学习使用
  • 这是我们学习的c++课本后面的答案。里面有详细的信息
  • c++) { if(S&bitMask) t++; S; } return t; } 一、选择题 1.有以下说明语句,则对应正确的赋值语句是( )。 structpoint {int x; int y; }p; (A)point.x = 1; point.y = 2; (B)point={ 1, 2 }; (C)p.x = 1;...

    第五章练习题

    一、选择题

    1.语句  cout<<(1&2)<<","<<(1&&2)<<endl;  的输出结果是(    )。

    (A)0, 0   (B)0, 1        (C)1, 0               (D)1, 1

    2.语句  cout<<(1|2)<<","<<(1||2)<<endl;  的输出结果是(    )。

    (A)0, 0   (B)1, 1        (C)2, 0               (D)3, 1

    3.语句  cout<<(3<<3)<<endl; 的输出结果是(    )。

    (A)24     (B)12          (C)9                   (D)6

    4.语句  cout<<(24>>3)<<endl; 的输出结果是(    )。

    (A)12     (B)9            (C)6                   (D)3

    5.语句  cout<<(2^5)<<endl; 的输出结果是(    )。

    (A)1             (B)3            (C)7                   (D)10

    【解答】       B    D    A    D    C

     

    二、程序练习

    使用按位异或(^)运算,可以不需要中间变量,快速交换两个变量的值。设计一个函数,实现快速交换两个长度相同整型数组元素的值。

    【解答】

    voidSwap(int * Aary, int * Bary , int n)

    {

          for(int i=0; i<n; i++)

          {

                 Aary[i]=Aary[i]^Bary[i];

                 Bary[i]=Aary[i]^Bary[i];

                 Aary[i]=Aary[i]^Bary[i];

          }

    }

    一、选择题

    设有

    unsigned A, B;             //表示两个集合

    unsigned x;                   //表示集合元素

    1.实现集合运算AB运算的对应表达式是(    )。

    (A)A|B    (B)A&B (C)A&(~(A&B))   (D)A|B==B

    2.实现集合运算A&B运算的对应表达式是(    )。

    (A)A|B    (B)A&B (C)A&(~(A&B))   (D)A|B==B

    3.实现集合运算A-B运算的对应表达式是(    )。

    (A)A|B    (B)A&B (C)A&(~(A&B))   (D)A|B==B

    4.实现集合运算AB运算的对应表达式是(    )。

    (A)A|B    (B)A&B (C)A&(~(A&B))   (D)A|B==B

    5.实现集合运算求补集~A运算的对应表达式是(    )。

    (A)~A     (B)A==0     (C)A&(~(A&B))   (D)1<<(x-1)&A==1<<(x-1)

    6.判断元素xA对应的表达式是(    )。

    (A)~A     (B)A==0     (C)A&(~(A&B))   (D)1<<(x-1)&A==1<<(x-1)

    【解答】              A      B       C       D      D

     

    二、程序练习

    设计一个函数:

    int count( unsigned S );

    计算由无符号整数S表示的集合中包含的元素个数。

    【解答】

    int count(unsigned S )

           unsigned bitMask = 1<<31, t=0;

           for(unsigned c=1; c<=32; c++)

           {

                  if(S&bitMask) 

                         t++;

                  S<<=1;

           }

           return t;

    }

    一、选择题

    1.有以下说明语句,则对应正确的赋值语句是(    )。

    structpoint

    {int x; int y; }p;

    (A)point.x = 1; point.y = 2;         (B)point={ 1, 2 };

    (C)p.x = 1; p.y = 2;                          (D)p = { 1, 2 };

    2.已知有职工情况结构变量emp定义如下,则对emp中的birth正确赋值方法是(    )。

    struct Date

    {  int year;

       intmonth;

       int day;

    };

    strnct Employee

    {  char name[20];

       long  code;

       Datebirth

    };

    Employee emp;

    (A)year=1980; month=5;  day=1;

    (B)birth.year=1980;  birth.month=5;  birth.day=1;

    (C)emp.year=1980;  emp.month=5; emp.day=1;

    (D)emp.birth.year=1980;  emp.birth.month=5;  emp.birth.day=1;

    3.有以下说明语句,则叙述正确的是(    )。

    struct Point

    {  int x;

       int y;

    };

    (A)正确的结构类型说明                        (B)正确的结构变量说明

    (C)错误的原因是结构中成员类型相同      (D)无意义的说明

    4.有以下说明语句,则下列错误的引用是(    )。

    struct  Worker

    {  int no;

    char name[20];

    };

    Worker w, *p =&w;

    (A)w.no         (B)p->no           (C)(*p).no          (D)*p.no

    5.s1和s2是两个结构类型变量,若要使赋值s1=s2合法,则要求(    )。

    (A)s1只接收s2中相同类型的数据成员                

    (B)s1和s2中的数据成员个数相同

    (C)s1和s2是同一结构类型的变量                             

    (D)s1和s2是存储字节长度一样的变量

    【解答】              C       D      A      D      C

     

    二、程序练习

    1.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    struct Data

    {  int n;

       doublescore;

    };

    int main()

    {  Data a[3] = { 1001,87,1002,72,1003,90 }, *p =a;

       cout<< (p++)->n << endl;

       cout<< (p++)->n << endl;

       cout<< p->n++ << endl;

       cout<< (*p).n++ << endl;

    }

    【解答】

     
     

     

    2.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    struct Employee

    {  char name[ 20 ];

       charsex;

    };

    void fun( Employee *p )

    {  if( (*p).sex == 'm' )

         cout << (*p).name << endl;

    }

    int main()

    {  Employee emp[5] = { "Liming", 'm',"Wangxiaoping", 'f', "Luwei", 'm' };

       int i;

       for(i=0; i<3; i++ )

          fun( emp+i );

    }

    【解答】

     
     

     

    3.编写程序,定义一个表示 ( x, y ) 坐标点的结构类型:

    struct Point{ int x; inty; };

    main函数输入两个坐标点的值。函数:

    int Line(Point a, Pointb);

    判断两点的连线是否为水平线、垂直线或斜线。

    【解答】

    #include<iostream>

    #include <iomanip>

    using namespace std;

    struct Point

    {

          int x;

          int y;

    };

    int Line(Point a, Point b)

    {

          if(a.x==b.x) return 1;

          if(a.y==b.y) return 2;

          return 0;

    }

    int main()

    {

          Point a,b;

          cout<<"输入第一点坐标值:\n";

          cout<<"x =";  cin>>a.x;

          cout<<"y =";  cin>>a.y;

          cout<<"输入第二点坐标值:\n";

          cout<<"x =";  cin>>b.x;

          cout<<"y =";  cin>>b.y;

          int t=Line(a,b);

          if(t==1)

                 cout<<"这是一条水平线\n";

          else

                 if(t==2)

                     cout<<"这是一条垂直线\n";

                 else

                         cout<<"这是一条斜线\n";

    }

    一、选择题

    1.有以下说明语句,则正确的赋值语句是(    )。

    struct Point

    {  double x;

       double y;

    };

    Point pp[3];

    (A)pp[0]={0,0}                           (B)pp.x= pp.y=1;      

    (C)pp[2]->x= pp[2]->y=2;          (D)pp[3].x=3;     pp[3].y=3

    2.有以下说明语句,则引用形式错误的是(    )。

    struct Student

    {  int num;

       doublescore;

    };

    Studentstu[3]={{1001,80}, {1002,75}, {1003,91}}, *p=stu;

    (A)p->num           (B)(p++).num            (C)(p++)->num        (D)(*p).num

    【解答】     D      B

     

    二、程序练习

    1.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    struct Node

    {  char * s;

       Node *q;

    };

    int main()

    {  Node a[ ] = { { "Mary", a+1 }, {"Jack", a+2 }, { "Jim", a } };

       Node*p = a;

       cout<< p->s << endl;

       cout<< p->q->s<< endl;

       cout<< p->q->q->s << endl;

       cout<< p->q->q->q->s << endl;

    }

    【解答】

     
     

     

    2.编写程序,定义点结构类型:

    struct Point{ int x; inty; };

    从键盘输入若干个点的数据,存放在结构数组中。函数:

    int Line(Point ary[], intn);

    判断这些点是否在一条水平线或垂直线上。

    【解答】

    #include<iostream>

    #include <iomanip>

    using namespace std;

    struct Point

    {

          int x;

          int y;

    };

    int Line(Point ary[], int n)

          int i, t1=0, t2=0;

          for( i=0; i<n-1; i++)

          {

                 t1+=ary[i].x==ary[i+1].x;

                 t2+=ary[i].y==ary[i+1].y;

          }

          if(t1==n-1) return 1;

          if(t2==n-1) return 2;

          return 0;

    }

    int main()

    {

          const int N=3;

          Point ary[N];

          for(int i=0; i<N; i++)

          {

                 cout<<"输入第"<<i+1<<"点坐标值:\n";

                 cout<<"x =";  cin>>ary[i].x;

                 cout<<"y =";  cin>>ary[i].y;

          }

          int t=Line(ary, N);

          if(t==1)

                 cout<<"构成一条水平线\n";

          else

                 if(t==2)

                     cout<<"构成一条垂直线\n";

                 else

                         cout<<"不能构成水平线或垂直线\n";

    }

    一、选择题

    有说明语句:

    Struct Node{ int data;Node * next; };

    Node *head, *p,*q, *s;

    并且,head是单向链表的头指针,p指向链表中的节点,q指向*p的前驱节点。

    1.在*p之后插入节点*s的操作是(    )。

    (A)p->next=s;  s->next=p->next;             (B)s->next=p-next; p->next=s;

    (C)p =s->next; s =p->next;              (D)s =p->next; p =s->next;

    2.在*p之前插入节点*s的操作是(    )。

    (A)q =s->next; s =p->next;              (B)q->next=s;  s->next=p;

    (C)s=p->next;  q=s->next;                (D)s->next=p;  q->next=s;

    3.在*hear之前插入节点*s的操作是(    )。

    (A)s->next=head; head=s;                (B)s->next=head->next;  head->next=s;

    (C)head=s; s->next=head;                (D)head->next=s; s->next=head->next;

    4.删除*p节点的操作是(    )。

    (A)q = p; delete p;                             (B)p = q; delete q;

    (C)q->next=p->next; delete p;                   (D)p->next = q->next; delete q;

    5.删除*(head->next)的操作是(    )。

    (A)p=head->next; head->next=head->next->next; delete p;

    (B)head->next=head->next->next; p=head->next; delete p;

    (C)p=head; head=head->next; delete p;

    (D)head=head->next; p=head; delete p;

    【解答】              B       D      A      C       A

     

    二、程序练习

    有以下声明语句和主函数。其中Create函数从键盘输入整数序列,以输入0为结束,按输入逆序建立一个以head为表头的单向链表。程序在main函数调用Create建立链表,调用ShowList函数验证链表。例如,输入序列为1 2 3 4 5 0,建立的链表是5 4 3 2 1。补充程序中的Create函数和ShowList函数。

    #include<iostream>

    using namespace std;

    struct Node{int data;Node * next;};

    void Create(Node*&head);

    void ShowList(Node*head);

    void main()

    {  Node *head=new Node;

       head=NULL;

       cout<<"输入链表元素,以输入 0 结束:\n";

       Create(head);

       cout<<"输出逆向链表\n";

       ShowList(head);    

    }

    【解答】

    void Create(Node *&head)

    {

          Node *p;

          p = new Node ;

          cin>>p->data;

          while(p->data!=0)

          {

                 if(head==NULL)

                        { head=p;head->next=NULL; }

                 else

                        {

                               p->next= head;

                               head =p;

                        }

          p=new Node;

          cin>>p->data;

          }

    }

     

    void ShowList(Node *head)

    {

          cout << "now theitems of node are: \n";

          while( head )

          {

                 cout <<head->data << '\t';

                 head = head->next;

          }

          cout << endl;

    }

     

    综合练习

    一、思考题

    1.判断一个整数n的奇偶性,可以利用位运算吗?请你试一试。

    【解答】

    可以。一个整数当最低位为1时,它是奇数,否则为偶数。以下函数返回对参数k的奇偶判断。

    bool odd( int k )

    {

      return 1&k;

    }

     

    2.长度为N的数组可以表示N个元素的集合,若有 S[i]==1,表示对应元素在集合中,如何实现集合的基本运算?请你试一试。并从内存和处理要求上与5.2.2节中集合的实现方法进行比较。

    【解答】

    长度为N的数组S可以表示有N个元素的集合。当S[i]==1,表示元素i+1在集合中;当S[i]==0,表示元素i+1不在集合中。集合运算通过对数组元素操作完成。

    用数组实现集合,每一个数组元素只能表示一个集合元素,运算的空间和时间消耗高于用无符号整数和位运算实现集合运算。

    用数组实现集合运算程序如下。

    #include<iostream>

    using namespacestd;

    void setPut(unsigned *S );                                    //输入集合S的元素

    void setDisplay(const unsigned *S );                //输出集合S中的全部元素

    bool putX(unsigned *S, unsigned x );               //元素x并入集合

    void Com(  unsigned *C, const unsigned *A, constunsigned *B);     //求并集C=A∪B

    void setInt(  unsigned *C, const unsigned A, const unsignedB);       //求交集C=A∩B

    void setDif(const unsigned A, const unsigned B );                           //求差集C=A-B

    bool Inc( constunsigned *A, const unsigned *B );                           //判蕴含

    bool In( constunsigned *S,  const unsigned x );                            //判属于x∈S

    bool Null( constunsigned *S );                                             //判空集

    const int N=32;

    //输入集合元素

    voidsetPut(unsigned *S)

    { unsigned x;

      cin >> x;

      while( x>0&&x<=N)

      {  putX(S, x );       //把输入元素并入集合S

         cin>> x;

      }

    }

    //输出集合S中的全部元素

    void setDisplay(const unsigned *S )

    { cout <<"{ ";

      if (Null(S))

      cout<<"  }\n";

      else

      {  for(int i=0; i<N; i++ )       //输出元素

             {

               if( S[i] )                          

                    cout << i+1 <<", ";

             }

         cout<< "\b\b }\n";                  //擦除最后的逗号

      }

      return;

    }

    //元素x并入集合S

    bool putX(unsigned *S, unsigned x )

    {if(x>0&&x<=N)

      { S[x-1] = 1;

        return true;

      }

      return false;

    }

    //求并集C=A∪B

    void Com(  unsigned *C, const unsigned *A, constunsigned *B )

    { for( int i=0; i<N;i++ )

        C[i]=int( A[i] || B[i] ) ;

    }

    //求交集C=A∩B

    void setInt(unsigned *C, const unsigned *A, const unsigned *B )

    { for( int i=0;i<N; i++ )

        C[i]=int( A[i]&&B[i] ) ;

    }

    //求差集C=A-B

    void setDif(  unsigned *C, const unsigned *A, constunsigned *B )

    { for( int i=0;i<N; i++ )

        C[i]=int( A[i]&&!(A[1]&&B[i]) ) ;

    }

    //判蕴含,A蕴含于B时返回true

    bool Inc( constunsigned *A, const unsigned *B )

    { for(int i=0;i<N; i++)

       { if(A[i]&&!B[i])

         return false;

       }

      return true;

    }

    //判属于,x∈S时返回true

    bool In( constunsigned *S, const unsigned x )

    {  return S[x-1];

    }

    //判空集,S为空集时返回true

    bool Null( constunsigned *S )

    { for( int i=0;i<N; i++)

      { if( S[i])

        return false;

      }

      return true;

    }

     

    int main()

    { unsignedA[N]={0}, B[N]={0},  C[N]={0};

      unsigned x;

      cout << "Input the elements of setA, 1-"<<N<<", until input 0 :\n";

      setPut( A );

      cout << "Input the elements of setB, 1-"<<N<<", until input 0 :\n";

      setPut( B );

      cout<<"A = ";

      setDisplay( A );

      cout<<"B = ";

      setDisplay( B );

      cout << "Input x: ";

      cin>>x;

      cout << "Put " << x<< " in A = ";

      putX( A, x) ;

      setDisplay(A);

      cout << "C = A+B = ";

      Com( C, A, B );

      setDisplay( C );

      cout << "C = A*B = ";

      setInt( C, A, B );

      setDisplay( C );

      cout << "C = A-B = ";

      setDif( C, A, B );

      setDisplay( C );

      if( Inc( A, B ) )

        cout<< "A <= B is true\n";

      else

        cout<< "not A <= B\n";

      cout << "Input x: ";

      cin >> x;

      if( In( A, x ) )

        cout<< x << " in A\n";

      else

        cout<< x << " not in A\n";

    }

     

    3.分析以下说明结构的语句:

    struct Node

    {  int data;

       Nodeerror;                      //错误

       Node *ok;                       //正确

    };

    error和ok分别属于什么数据类型?有什么存储要求?error出错的原因是什么?

    【解答】

    error是Node结构类型数据成员,错误。原因是结构定义的数据成员若为本身的结构类型,是一种无穷递归。ok是指向Node类型的指针,定义正确,占4字节。

     

    4.例5-15中用辅助数组对结构数组进行关键字排序,有定义:

    person *index[100];

    index数组存放结构数组元素的地址。如果把index定义改为:

    int index[100];

    用于存放结构数组元素的下标,可以实现对结构数组的索引排序吗?如何修改程序?请你试一试。

      【解答】

    可以。关键是通过整型索引数组元素作为下标访问结构数组。表示为:

    all[pi[i]].name    all[pi[i]].id           all[pi[i]].salary

    有关程序如下:

    #include<iostream>

    usingnamespace std;

    structperson                //说明结构类型

    {

    charname[10];

      unsigned int id; 

      double salary;

    };

    voidInput( person[], const int );

    voidSort( person[], int[],const int );

    voidOutput( const person[], int[],const int );

    intmain()

    {

    personallone[100] ;           //说明结构数组

      int index[100];                  //说明索引数组

      int total ;

      for(int i=0; i<100; i++)      //索引数组元素值初始化为结构数组元素下标

           index[i]=i ;

      cout<<"输入职工人数:";

      cin>>total;

      cout<<"输入职工信息:\n";

      Input(allone,total);

      cout<<"以工资做关键字排序\n";

      Sort(allone,index, total);

      cout<<"输出排序后信息:\n";

      Output(allone,index,total);

    }

    voidInput( person all[], const int n )

    {

    inti ;  

      for( i=0; i<n; i++ )            // 输入数据

       {

    cout<<i<<":姓名:";

         cin>>all[i].name;

         cout<<"编号:";

         cin >> all[i].id;

         cout<<"工资:";

         cin >> all[i].salary ;

       }

    }

    voidSort(person all[], int pi[], const int n)

    {

     int i,j; 

      int t;                               //交换用中间变量

      for(i=1; i<n; i++)                     //以成员salary做关键字排序

      {

    for(j=0;j<=n-1-i; j++)

        if(all[pi[j]].salary>all[pi[j+1]].salary)     //通过索引数组访问结构数组元素

           {

    t=pi[j];                                         //交换索引数组元素值

    pi[j]=pi[j+1];

    pi[j+1]=t;

           }

      }

    }

    voidOutput(const person all[], int pi[], const int n)

    {

     for( int i=0; i<n; i++ )             // 输出排序后数据

       cout<<all[pi[i]].name<<'\t'<<all[pi[i]].id<<'\t'<<all[pi[i]].salary<<endl;

    }

     

    5.有以下结构说明和遍历单向链表的函数。函数内有错误吗?是什么性质的错误?请上机验证你的分析。

    struct Node

    {  int data; 

       Node *next;

    };

    void ShowList( Node *head)

    {  while( head )

       {  cout<< head->date << '\n';

          head++;

       }

    }

    【解答】

    head++错误,原因是动态链表的结点存放不是连续顺序的内存空间,它们是逐个结点通过new建立的,所以不能用++做地址偏移运算。应该用:

    head=head->next;

     

    二、程序设计

    1.编写程序,将一个整型变量右移4位,并以二进制数形式输出该整数在移位前和移位后的数值。观察系统填补空缺的数位情况。

    【解答】

    #include<iostream>

    using namespacestd;

    voidbitDisplay(unsigned value);

    int main()

    {

      unsigned x;

      cout << "Enter an unsigned integer:";

      cin >> x;

      bitDisplay(x);

      x>>=4;

      cout<<"Right 4-bit\n";

      bitDisplay(x);

    }

    voidbitDisplay(unsigned value)

    {

      unsigned c;

      unsigned bitmask = 1<<31;

      cout << value << " =\t";

      for( c=1; c<=32; c++ )

      {

             cout << ( value&bitmask ? '1': '0' );

             value <<= 1;

             if( c%8 == 0 )

              cout << ' ';

      }

      cout << endl;

    }

     

    2.整数左移一位相当于将该数乘以2。编写一个函数:

    unsigned power2( unsignednumber, unsigned pow );

    使用移位运算计算number*2pow,并以整数形式输出计算结果。注意考虑数据的溢出。

    【解答】

    unsigned power2( unsigned number, unsigned pow )

    {

      unsigned c=1;

      unsigned bitmask = 1<<31;   

      while(c<31)           //溢出判断

      {

             if( number&bitmask )break;           //查找最高位的1

             c++;

             bitmask>>=1;

      }

      if(pow<c)

             return number<<pow;

      else

      {

             cout<<"overflow!\n";

             return 0;

      }

    }

     

    3.设计重载函数,使用按位异或(^)运算,实现快速交换两个整型变量和浮点型变量的值。

    【解答】

    void swap (int &a, int &b)

    {

      a=a^b;

      b=a^b;

      a=a^b;

    }

    void swap(double &x,double &y)

      int*xp,*yp;

      xp = (int*)(&x);

      yp = (int*)(&y);

      *xp=(*xp)^*(yp);     *yp=(*xp)^(*yp);     *xp=(*xp)^(*yp);

      xp++;   yp++;

      *xp=(*xp)^*(yp);     *yp=(*xp)^(*yp);     *xp=(*xp)^(*yp);

    }

     

    4.设计函数,不使用辅助数组,实现两个int类型或double类型数组的数据快速交换。

    【解答】

    void Swap(char * Aary, char * Bary , int n)

    {

      for(int i=0; i<n; i++)

      {

             Aary[i]=Aary[i]^Bary[i];

             Bary[i]=Aary[i]^Bary[i];

             Aary[i]=Aary[i]^Bary[i];

      }

    }

    以上函数使用char*,字节指针做数组参数,对于不同类型的数组,调用函数时,只需要对实参地址做指针类型转换,并且设定参数n对应的实参是交换数据的总字节数。例如,交换double类型数组的数据可以有以下方式:

    const int N=100;

    double x[N];

    double y[N];

    //……

    Swap((char*)x,(char*)y,sizeof(double)*N);

     

    5.集合的元素通常是字符。设计程序,用无符号整数表示ASCII码字符集合,用位运算实现各种基本集合运算。

    【解答】

    ASCII码是0~127的整数,可以用长度为4的无符号整型数组表示集合,如教材例5-6所示。区别是,在输入集合元素时,需要把字符转换成整型数据,在输出操作中,把整型集合元素转换成字符型数据。

    程序略。

     

    6.使用结构类型表示复数。设计程序,输入两个复数,可以选择进行复数的+、-、×或÷运算,并输出结果。

    【解答】

    #include<iostream>

    #include<iomanip>

    usingnamespace std;

    struct complex

    {

     double re, im; 

    };

    int main()

    {

        complex a,b,c;  char oper;

        cout << "输入复数a的实部和虚部: ";

        cin >> a.re >>a.im;

        cout << "输入复数b的实部和虚部:";

        cin >> b.re >>b.im;

        cout << "输入运算符: ";

        cin >> oper;

        switch ( oper )

       {

               case '+':  c.re=a.re+b.re; c.im=a.im+b.im;

                             break;

               case '-':   c.re=a.re-b.re; c.im=a.im-b.im;

                             break;

               case '*':   c.re=a.re*b.re-a.im*b.im;

                             c.im=a.im*b.re+a.re*b.im;

                             break;

               case '/':   c.re=(a.re*b.re+a.im*b.im)/(b.re*b.re+b.im*b.im);

                             c.im=(a.im*b.re-a.re*b.im)/(b.re*b.re+b.im*b.im);

                             break;

           default:             cout<< "input error!" << endl;

                             return 0;

    }

    cout << "c=" << c.re;

    cout << setiosflags( ios::showpos );

    cout << c.im << "i" << endl;

    return 0;

    }

     

    7.把一个班的学生姓名和成绩存放到一个结构数组中,寻找并输出最高分者。

    【解答】

    #include <iostream>

    using namespace std;

    struct data

    {

      char name[12];

      double score;

    };

    double searchMax(data *a, int n );

     

    int main()

    {

          data stu[ ] = {"李小平",90,"何文章",66,"刘大安",87,"汪立新",93,"罗建国",78,

                 "陆丰收",81,"杨勇",85,"吴一兵",55,"伍晓笑",68,"张虹虹",93};

          double max;

          int n=sizeof(stu) /sizeof(data);

          max=searchMax(stu, n);

          for( int i=0; i<n; i++ )

                 if( stu[i].score ==max )

                        cout<<stu[i].name <<'\t'<< stu[i].score<<endl;

    }

     

    double searchMax(data *a, int n )

    {

          int i;

          double max=a[0].score;

          for( i=1; i<n; i++ )

            if( a[i].score > max ) max = a[i].score;

          return max;

    }

     

    8.使用结构表示X-Y平面直角坐标系上的点,编写程序,顺序读入一个四边形的4个顶点坐标,判别由这个顶点的连线构成的图形是否为正方形、矩形或其他四边形。要求:定义求两个点距离的函数使用结构参数。

    【解答】

    #include<iostream>

    #include<cmath>

    usingnamespace std;

    struct point

    {

     double x;

     double y;

    };

    double d( point p1, point p2 )

    {

     return sqrt( pow( p1.x-p2.x,2 )+pow( p1.y-p2.y,2 ) );

    }

    int main()

    {

     int i;  point p[5];

      for( i=1; i<=4; i++ )

       { cout << "输入第"<< i << "个顶点的横坐标和纵坐标:";

         cin >> p[i].x >> p[i].y; 

    }

      if( fabs( d( p[1],p[2] ) - d( p[3],p[4] ))<=1e-8

           && fabs( d( p[1],p[4] ) - d( p[2],p[3] ))<=1e-8

           && fabs( d( p[1],p[3] ) - d( p[2],p[4] ))<=1e-8)

        if( fabs( d( p[1],p[2] ) - d( p[2],p[3] ))<1e-8 )

            cout << "四个顶点构成的图形为正方形!"<< endl;

        else cout << "四个顶点构成的图形为矩形!"<< endl;

     else cout << "四个顶点构成的图形为其它四边形!"<< endl;

    }

     

    9.建立一个结点包括职工的编号、年龄和性别的单向链表,分别定义函数完成以下功能:

    (1)遍历该链表输出全部职工信息;

    (2)分别统计男、女职工的人数;

    (3)在链表尾部插入新职工结点;

    (4)删除指定编号的职工结点;

    (5)删除年龄在60岁以上的男性职工或55岁以上的女性职工结点,并保存在另一个链表中。

    要求:用主函数建立简单菜单选择,并测试程序。

    【解答】

    #include<iostream>

    usingnamespace std;

    struct employee

    {

    int num;

     int age;

     char sex;

     employee *next;

    };

    employee *head, *head1;

    //建立单向链表

    employee *create()

    {

     employee *head, *p, *pend;

     char ch;

     head = NULL;

     cout << "\t输入数据?(y/n)";cin >> ch;

     if( ch == 'y' )

      {

     p= new employee;

        cout << "\t编号:";  cin >> p->num;

        cout << "\t年龄:";  cin >> p->age;

        cout << "\t性别:";  cin >> p->sex;

    }

     else

        goto L0;

     while( ch == 'y' )

      {

     if( head == NULL ) head = p;

        else pend->next = p;

        pend = p;

          cout << "\t输入数据?(y/n)"; cin>>ch;

        if( ch == 'y' )

          {

     p= new employee;

             cout << "\t编号:"; cin >> p->num;

             cout << "\t年龄:"; cin >> p->age;

             cout << "\t性别:"; cin >> p->sex;  

    }

      }

     pend->next = NULL;

     L0: return head;         

    }

    //显示单向链表中全部职工信息

    void show( employee *head )

    {

     employee *p = head;

    if( !head ) { cout << "\t空链表!" << endl; goto L1; }

        cout << "\t链表中的数据是:\n";

     while( p )

      {

     cout << '\t' << p->num <<"," << p->age << "," << p->sex<< endl;

          p = p->next; 

    }

    L1:

    }

    //统计男女职工人数

    void count( employee *head )

    {

     employee *p = head;

     int m, f;

      m= 0; f = 0;

     while( p )

      {

     if( p->sex == 'm' )

    m++;

         else

     f++;

         p = p->next; 

    }

     cout << "\t男职工人数:"<< m << endl;

     cout << "\t女职工人数:"<< f << endl;

    }

    //在链表尾部插入新结点

     employee *insert()

    {

    employee *pend = head, *p;

     //在空链表尾部插入新结点

     if( !head )

      {

    p = new employee;

       cout << "\t编号:";  cin >> p->num;

       cout << "\t年龄:";  cin >> p->age;

       cout << "\t性别:";  cin >> p->sex;

       head = p;

       p->next = NULL;

       return head;

    }

     //在链表尾部插入新结点

     while( pend->next != NULL )

      {

    pend = pend->next; 

    }

      p= new employee;

     cout << "\t编号:";  cin >> p->num;

     cout << "\t年龄:";  cin >> p->age;

     cout << "\t性别:";  cin >> p->sex;

     pend->next = p;

     pend = p;

     pend->next = NULL;

     return head;

    }

    //删除指定编号的结点

    employee *del( int bh )

    {

    employee *p, *q;

     if ( !head )

      {

    cout << "\t空链表!" << endl;

       goto L2; 

    }

     //删除链首结点

     if( head->num == bh )

      {

     p= head;

        head = head->next;

          delete p;

          cout << "\t结点已被删除!" << endl;

          goto L2;

    }

     //删除非链首结点

      q= head;

     while( q->next != NULL )

      {

    if ( q->next->num == bh )

       {

     p= q->next;      //待删除结点

            q->next = p->next;

            delete p;

          cout << "\t结点已被删除!"<< endl;

            goto L2;  

    }

         q = q->next;

      }

     cout << "\t找不到需删除结点!"<< endl;

    L2: return ( head );

    }

    //删除指定年龄段的结点,并把被删除结点保存在另一链表中

    employee *delcreate()

    {

     employee *p, *pd, *p1, *q;

     int flag;

     //建立新链表

     if ( head == NULL )

      {

     cout << "\t空链表!" << endl;

        goto L3;

    }

     head1 = NULL;

     pd = new employee;

      p= head;

     flag = 0;

     while ( p != NULL )

      {

    if( p->age >= 55 &&p->age <=60 )

         {

     pd->num = p->num;

           pd->age = p->age;

           pd->sex = p->sex;

           if( head1 == NULL )

    head1 = pd;

         else

    p1->next = pd;

         p1 = pd;

           pd = new employee;

           flag = 1; 

    }

          p = p->next; 

    }

    if ( flag == 0 )

      {cout << "\t没有需删除的结点!"<< endl; goto L3; }

    p1->next = NULL;

    //显示新链表

    cout <<"\t新链表中的数据是: \n";

    p = head1;

    while( p )

     {

     cout << '\t' << p->num <<"," << p->age << "," << p->sex<< endl;

      p = p->next;

    }

    //删除指定年龄的结点

    p = head;

    q = p;

    while ( p != NULL )

    {

     if( p->age >= 55 && p->age<= 60)

       if( head->age == p->age )

      {

    pd = head;               //待删除结点

           head = head->next;

               deletepd;

               p= head;

               continue;

       }

         else

               if(p->next == NULL )

               {

     pd= p;                       //待删除结点        

                 q->next = NULL;

           delete pd;

                 goto L3; 

    }

               else

               {

    pd = p;                        //待删除结点

    q->next = p->next;

    delete pd;

    p = q->next;

    continue;

    }

    q = p;

    p = p->next; 

    }

     L3: return ( head );

    }

     

    int main()

    {

    int choice, bh ;

    L:

    cout << "\n\t\t请键入操作选择\n" << endl;

    cout << "\t 1 --- 建立单向链表" << endl;

        cout << "\t 2 --- 显示单向链表中全部职工信息" << endl;

        cout << "\t 3 --- 统计男女职工人数" << endl;

        cout << "\t 4 --- 在职工尾部插入新结点" << endl;

        cout << "\t 5 --- 删除指定编号的结点" << endl;

        cout << "\t 6 --- 删除指定年龄的结点,并把被删除结点保存在另一链表中" << endl;

        cout << "\t 0 --- 退出" << endl ;

    cout << "\t\t";

        cin >> choice ;

     switch ( choice )

      {

    case 1 : head = create() ; goto L ;

        case 2 : show( head );  goto L ;

        case 3 : count( head ); goto L;

        case 4 : head = insert(); goto L;

        case 5 : cout << "\t输入需删除结点编号:";

                     cin >> bh;

                         head = del( bh ); goto L;

          case 6 : head = delcreate(); goto L;

          case 0 : cout << " \t退出程序的运行!\n" << endl ; break ;

        default : cout << "\t输入错误,请重新输入!\n" << endl ; goto L; 

    }

    }

    10.输入一行字符,按输入字符的反序建立一个字符结点的单向链表,并输出该链表中的字符。

    【解答】

    #include<iostream>

    usingnamespace std;

    struct node

    {

     char ch;

     node *next; 

    };

    void show( node *head );

    int main()

    {

     node *head, *p;

     char c;

     head = NULL;

     while( (c = getchar()) != '\n' )                //输入一行字符

      {

     p= new node;                              //建立新结点

          p->ch = c;

          p->next = head;                        //插入表头

          head=p; 

    }

      show(head);

    }

    void show( node *head )                        //输出链表

    {

     node *p = head;

     cout << "链表中的字符是:\n";

     while( p )

      { cout << p->ch;

         p = p->next; 

    }

     cout << endl;

    }

     

    11.设有说明语句:

    struct List { intdata;  List * next; };

    List *head;

    head是有序单向链表的头指针。请编写函数:

    void Count( List * head);

    计算并输出链表数据相同值的结点及个数。例如,若数据序列为:

    2 3 3 3 4 5 5 6 6 6 6 7 89 9

    则输出结果为:

    data   number

    3                3

    5                2

    6                4

    9                2

    可以用例5-18的程序生成有序链表,测试Count函数。

    【解答】略

     

    12.用带头结点的有序单向链表可以存放集合,如图5.16所示。头结点不存放集合元素,仅为操作方便而设置。使用这种数据结构,设计集合的输入、输出和各种基本运算的函数。

    图5.16  带头结点的有序单向链表

    【解答】略

     

    推荐阅读
    全部习题章节:
    C++课本的练习题及答案(第四章)
    C++课本的练习题及答案(第五章)
    C++课本的练习题及答案(第六章)
    C++课本的练习题及答案(第七章)
    C++课本的练习题及答案(第八章)
    展开全文
  • 学习c++过程中根据书上习题自己编写的答案源码,上传分享给大家参考
  • 谭浩强c++学习第一章习题解答的源码,按照题号形式分文件命名,供大家学习参考
  • C++课本的练习题及答案(第四章)

    千次阅读 2020-04-07 17:27:16
    第4章练习题同步练习4.1一、选择题1.有数组定义  double d[10];  以下叙述不正确的是(    )。(A)数组d有10个元素       ......

    第4章练习题

    同步练习4.1

    一、选择题

    1.有数组定义  double d[10];  以下叙述不正确的是(    )。

    (A)数组d有10个元素                            (B)数组d的最后一个元素是d[10]

    (C)数组d的第一个元素*d                      (D)数组d的字节数是sizeof(double)*10

    2.以下对一维数组a的定义正确的是(    )。

    (A)int n = 5, a[n];                                       (B)int a(5);

    (C)const int N = 5; int a[N];                       (D)int n;  cin>>n; int a[n];   

    3.下列数组定义语句中,不合法的是(    )。

    (A)int a[3] = { 0, 1,2, 3 };                         (B)int a[] = { 0, 1,2 };

    (C)int a[3] = { 0, 1,2 };                    (D)int a[3] = { 0 };

    4.已知 int a[10] = { 0,1, 2, 3, 4, 5, 6, 7, 8, 9 }, *p = a;  以下不能表示数组 a 中元素的表达式是(    )。

    (A)*a                    (B)*p                       (C)a                         (D)a[ p-a ]

    5.已知 int a[] = {0,2,4,6,8,10 }, *p = a+1; 其值等于0的表达式是(    )。

    (A)* (p++)            (B)*(++p)               (C)*(p--)               (D)*(--p)

    【解答】     B       C       A      C       D

     

    二、程序练习

    1.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    int main()

    { int i, count=0, sum=0;

    double average;

    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    for( i=0; i<10; i++ )

    {    if( a[i] % 2 == 0 )

            continue;

    sum += a[ i ];

    count++;

    }

    average = sum/count;

    cout << "count = " <<count << '\t' << "average = " << average <<endl;

    }

    【解答】

     

     

     

     

            

    2.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    int main()

    {  int a[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    int *p = a, sum =0;

    for(; p<a+9; p++ )

       if(*p % 2 == 0 )

      sum+= *p;

    cout << "sum = " << sum << endl;

    }

    【解答】

     
     

    3.设计一个程序,要求有以下功能:

    (1)声明一个长度为10的整型数组;

    (2)输入数组元素;

    (3)寻找数组中的最大值元素和这个元素的下标;

    (4)输出最大值元素的值和它的下标值。

    【解答】

    #include<iostream>

    #include<cstdlib>

    using namespace std;

    int main()

    {

        int a[10],max,i,j;

        cout<<"请输入10个数:";

        for( i=0;i<10;i++)

        {

            cin>>a[i];   

        }

        max=0;                 //记录最大元素的下标

        for(j=0;j<10;j++)

        {

            if(a[j]>=a[max])              //用当前最大元素与遍历元素比较

            max=j;                         //修改最大下标值

        }

        cout<<"最大值为:"<<a[max]<<endl;

             cout<<"它的下标为:"<<max<<endl;

    }

     

    同步练习4.2

    一、选择题

    1. 说明一个长度为10的数组,元素类型为整型指针的正确语句是(    )。

    (A)int *pary[10];                                       (B)int (*pary)[10]  

    (C)int *pary(10);                                        (D)int **pary[10]

    2. 有以下语句,则能够输出a+b+c的值的语句是(    )。

    int a=1, b=2, c=3; int*pary[3]={&a, &b, &c};

    (A)cout<<(pary[0]+pary[1]+pary[2]);       (B)cout<<(*pary[0]+*pary[1]+*pary[2]);

    (C)cout<<(pary[1]+pary[2]+pary[3]);       (D)cout<<(*pary[1]+*pary[2]+*pary[3]);

    【解答】    A      B

     

    二、程序练习

    使用以下语句:

    const int n=20;

    int a[n]; int *pa[n];  int i;

    for(i=0; i<n; i++)

       a[i]=i+1;

    编写完整的程序,通过pa数组修改数组a元素的值,使其元素值自增10,然后通过pa数组遍历a数组,输出全部元素值,要求每行输出10个元素。

    【解答】

    #include<iostream>

    usingnamespace std;

    intmain()

    {

             const int n=20;

             int a[n];

             int *pa[n];

             int i;

             for(i=0; i<n; i++)

             {

                       a[i]=i+1;

                       pa[i]=a+i;                               //对指针数组元素赋值

                       *pa[i]+=10;                            //数组元素值自增10

                       cout<<*pa[i]<<"  ";             //输出数组元素

                       if((i+1)%10==0)                    //格式控制

                                cout<<endl;

             }

    }

     

    同步练习4.3

    一、选择题

    1.以下不能对二维数组a进行正确初始化的语句是(    )。

    (A)int a[2][3] = { 0};

    (B)int a[][3] = { {0,1 }, { 0 } };

    (C)int a[2][3] = { {0, 1 }, { 2, 3 }, { 4, 5 } };

    (D)int a[][3] = { 0,1, 2, 3, 4, 5 };

    2.已知  int a[][3] = { { 0, 1 }, { 2, 3, 4 }, { 5, 6}, { 7 } };  则 a[2][1]的值是(    )。

    (A)0                      (B)2                        (C)6                         (D)7

    3.已知  int a[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };  以下不能表示数组元素a[2][1]的地址是(   )。

    (A)&a[2][1] (B)*(a[2]+1)        (C)a[2]+1           (D)*(a+2)+1

    4. 有以下说明语句,则正确的赋值语句是(    )。

    int a[5][5];  int*p, **q;

    (A)p=a;                 (B)p=*a;                 (C)q=a;                   (D)q=*a;

    5. 有以下说明语句,则正确的赋值语句是(    )。

    int a[5][5];  int*p, **q;

    (A)p=a[0];             (B)p=&a[0];            (C)q=a[0];               (D)q=&a[0][0];

    【解答】      C     C       B       B       A

     

    二、程序练习

    1.阅读程序,写出运行结果。

    #include <iostream>

    #include <iomanip>

    using namespace std;

    const int N = 5;

    int main()

    {  inta[N][N]={ 0 }, i, j, k;

       for( k=1,i=0; i<N; i++ )

          for( j=i; j>= 0; j--, k++ )

             a[j][i - j ] = k;

       for( i=0;i<N; i++ )

       {  for( j=0; j<N; j++ )

             cout<< setw( 3 ) << a[i][j];

          cout << endl;

       }

    }

    【解答】

     
     

            

    2.以下程序用于输入一个矩阵的元素,并输出指定行的元素。请补充inputAry函数和outputAry函数。

    #include<iostream>

    using namespace std;

    const int N=5;

    int main()

    {  intary[N][N], k;

       inputAry(ary,N);

       cout<<"输入行号,k = ";

       cin>>k;

       outputAry(ary,N, k-1);

    }

    【解答】

    #include<iostream>

    usingnamespace std;

    constint N=5;

    voidinputAry(int ary[N][N], int n );

    voidoutputAry(const intary[N][N], int n, intline);

    intmain()

    {

             intary[N][N], k;

             inputAry(ary, N);

             cout<<"输入行号,k = ";

             cin>>k;

             outputAry(ary, N, k-1);

    }

    voidinputAry(int ary[N][N], int n)

    {

             cout<<"输入"<<n<<"*"<<n<<"个矩阵元素\n";

             for(int i=0; i<n; i++)

                       for(int j=0; j<n; j++)

                       cin>>ary[i][j];

    }

    voidoutputAry(const intary[N][N], int n, intk)

    {

             for(int i=0; i<n; i++)

                       cout<<ary[k][i]<<"  ";

             cout<<endl;

    }

    同步练习4.4

    一、选择题

    1.若用数组名作为调用函数的实参,则传递给形参的是(    )。

    (A)数组存储首地址                                 (B)数组的第一个元素值

    (C)数组中全部元素的值                          (D)数组元素的个数

    2.有说明语句:int a[10];

    及函数:int fun(int x[10], int n)  {  returnsizeof(x);  }

    则语句  cout<<fun(a,10)<<endl;  的显示结果是(    )。

    (A)40                              (B)10                      (C)4                                 (D)0

    3.有以下说明语句,则调用函数的正确语句是(    )。

    int a[10];

    void fun( int * ,int n);

    (A)fun(a, 10);                 (B)fun(a[0], 10);     (C)fun(*a, 10);                 (D)fun(&a, 10);

    4.有以下说明语句,则调用函数的正确语句是(    )。

    int b[4][5];

    void fun( int * ,int n);

    (A)fun(b, 20);                 (B)fun(b[0], 20);     (C)fun(b[0][0], 20); (D)fun(&b, 20);

    5. 有以下说明语句,则调用函数的正确语句是(    )。

    int x[4][5];

    void fun( int y[4][5] , int m, int n);

    (A)fun(x, 4,5);                (B)fun(*x, 4,5);       (C)fun(x[0], 4,5);             (D)fun(&x, 4,5);

    【解答】      A      C       A      B       A

     

    二、程序练习

    1.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    int f(int [],int);

    int main()

    {  int a[] ={ -1, 3,5, -7,9, -11};

       cout<< f( a, 6 ) << endl;

    }

    int f( int a[], int size )

    {  int i,t=1;

       for( i=0;i<size; i ++ )

          if(a[i]>0 )   t*= a[i];

       return t;

    }

    【解答】

     

    2.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    int f( int [][3], int, int );

    int main()

    {  inta[][3] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };

       cout<< f( a, 3, 3 ) << endl;

    }

    int f( int a[][3], int row, int col )

    {  int i, j,t=1;

       for( i=0;i<row; i++ )

          for(j=0; j<col; j++ )

          {  a[i][j]++;

             if(i == j )  t *= a[i][j];

          }

       return t;

    }

    【解答】

     

    3.本程序的main函数定义了一个用二维数组m表示的6×6方阵。程序中:

    (1)调用setMatrix函数,对方阵元素赋不大于100的随机整数;

    (2)调用diagonal函数,依次把m阵的主对角线、次对角线放在数组a中。

    请补充定义setMatrix函数和diagonal函数,使其成为完整程序。

    #include<iostream>

    #include <cstdlib>

    #include<ctime>

    using namespace std;

    const int N=6;

    int main()

    {  intm[N][N],a[2*N],i,j;

       setMatrix( m, N*N );                //调用函数,对方阵元素赋不大于100的随机整数

       cout<<N<<"*"<<N<<"方阵:\n";

       for(i=0; i<N; i++ )         //输出方阵元素

       { for(j=0;j<N; j++) 

             cout<<m[i][j]<< '\t';

          cout<<endl;

       }

       diagonal( m, a, N );                  //调用函数,依次把m阵的主对角线、次对角线放在数组a中

       cout<<"对角线元素:\n";

       for(i=0; i<2*N; i++ )              //输出对角线元素

          cout<<a[i]<<"  ";

       cout<<endl;

    }

    【解答】

    void setMatrix( int matrix[][N],intn )              //matrix是二维数组参数

    { int i,*p;                                //p是一级指针变量

     p=*matrix;                         //二维数组作降维处理

     srand(unsigned(time(0)));

     for( i=0; i<n; i++,p++ )

         *p= rand()%100;                   //对数组元素赋随机数

     }

    void diagonal( int matrix[][N],int *ary, int n)

    { int i;

     for (i=0;i<n;i++)

     {   ary[i]= matrix[i][i];                //主对角线

             ary[i+n]=matrix[i][n-i-1];               //次对角线

     } 

    }

     

    同步练习4.5

    一、选择题

    1. 以下建立动态存储的语句正确的是(    )。

    (A)int p=new int;                              (B)int p=new (10); 

    (C)int *p(10);                                    (D)int *p=newint(10);

    2. 以下建立动态存储的语句正确的是(    )。

    (A)int p=new int[];                            (B)int p=new [10]; 

    (C)int *p=newint[10];                      (D)int *p[10]=newint;

    3. 有说明语句,则释放动态数组的正确语句是(    )。

    int *p=new int[10];

    (A)delete []p;                                    (B)delete p[]

    (C)delete int[]p                                  (D)delete p int[10]

    4. 有说明语句,则访问动态数组元素的正确语句是(    )。

    int *p=new int[10];

    (A)int a=p;                                         (B)int a=&p;

    (C)int* a=p[1]                                  (D)int a=p[1];

    【解答】      D      C       A      C

     

    二、程序练习

    1.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    int main()

    {  int *p;

       cout<< "test1: \n" ;

       p= newint( 5);

       cout<<*p<< endl;

       p= newint[5];

       cout<< "test2: \n";

       for(inti=0; i<5; i++)

       {  *(p+i)=i+1;

          cout <<*(p+i) << "\t";

       }

       cout<<endl;

    }

    【解答】

     

    2.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    void test1( int *a1 )

    {  a1 = newint( 5 );

       cout<< "*a1 = " << *a1 << endl;

    }

    void test2(int * & a2)

    {  a2 = newint( 5 );

       cout<< "*a2 = " << *a2 << endl;

    }

    int main()

    {  int *p =new int( 1 );

       test1( p);

       cout<< "test1: *p1 = " << *p << endl;

       test2( p);

       cout<< "test2: *p2 = " << *p << endl;

    }

    【解答】

     
     

     

    3.以下程序修改了同步练习4.3程序练习第2题中程序的主函数,请补充inputAry函数和outputAry函数,使程序完成相同的功能。

    #include<iostream>

    using namespace std;

    int main()

    {  int *pa,n, k;

       cout<<"输入矩阵的阶,n = ";

       cin>>n;

       pa=newint[n*n];

       inputAry(pa,n);

       cout<<"输入行号,k = ";

       cin>>k;

       outputAry(pa,n, k-1);

    }

    【解答】

    #include<iostream>

    usingnamespace std;

    voidinputAry(int *ary, int n );

    voidoutputAry(const int *ary, int n, int k);

    intmain()

    {

             int *pa, n, k;

             cout<<"输入矩阵的阶,n = ";

             cin>>n;

             pa=new int[n*n];

             inputAry(pa, n);

             cout<<"输入行号,k= ";

             cin>>k;

             outputAry(pa, n, k-1);

    }

    voidinputAry(int *ary, int n)

    {

             cout<<"输入"<<n<<"*"<<n<<"个矩阵元素\n";

             for(int i=0; i<n*n; i++)

                       cin>>ary[i];

    }

    voidoutputAry(const int *ary, int n, int k)

    {

             for(int i=0; i<n; i++)

                       cout<<ary[n*k+i]<<"  ";

             cout<<endl;

    }

    同步练习4.6

    一、选择题

    1.已知  char *a[]={ "fortran", " basic", "pascal","java", "c++" };  则 cout<<a[3];的显示结果是(    )。

    (A)t                       (B)一个地址值       (C)java                    (D)javac++

    2.设有  char *s="ABCDE"; cout<<*(s+1)<<endl;  输出结果是(    )。

    (A)A                     (B)B                        (C)ABCD               (D)BCD

    3.设有  char *s="ABCDE"; cout<<(s+1)<<endl;  输出结果是(    )。

    (A)A                     (B)B                        (C)ABCD               (D)BCDE

    4.设有  char *s="ABCDE"; cout<<strlen(s)<<endl;  输出结果是(    )。

    (A)6                      (B)5                        (C)4                        (D)1

    5.设  char *s1, *s2;  分别指向两个字符串,可以判断字符串s1和s2是否相等的表达式为(    )。

    (A)s1=s2                                           (B)s1==s2

    (C)strcpy(s1,s2)==0                         (D)strcmp(s1,s2)==0

    【解答】      C       B       D      B       D

     

    二、程序练习

    1.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    int main()

    {  char s[]= "abccda";

       inti;  char c;

       for( i= 1; ( c=s[i] ) != '\0'; i++ )

       {  switch( c )

          {  case 'a' : cout << '%'; continue;

             case'b' : cout << '$'; break;

             case'c' : cout << '*'; break;

             case'd' : continue;

          }

          cout<< '#' << endl;

       }

    }

             【解答】

     

    2.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    int main()

    {  char*str[] = { "c++", "basic", "pascal" };

       char**p;  int i;

       p =str;

       for(i=0; i<3; i++ )

          cout<< * ( p+i ) << endl;

    }

    【解答】

     
     

     

    3.阅读程序,写出运行结果。

    #include <iostream>

    using namespace std;

    int main()

    {  char s1[]= "Fortran", s2[] = "Foxpro";

       char*p, *q;

       p =s1;  q = s2;

       while(*p && *q )

       {  if (*p == *q )

             cout << *p;

          p++;

          q++;

       }

       cout<< endl;

    }

    【解答】

     

    4.阅读程序,写出运行结果。

    #include <cstring>

    #include <iostream>

    using namespace std;

    int main()

    {  charstr[][10] = { "VB", "Pascal", "C++" }, s[10];

       strcpy_s( s, ( strcmp( str[0], str[1] ) < 0? str[0] : str[1] ) );

       if(strcmp( str[2], s ) < 0 )

          strcpy_s( s, str[2] );

       cout<< s << endl;

    }

    【解答】

     

     
     

    5.本程序可以完成对字符串text的插入和删除操作。其中:

    insertStr(text,s,n);                  //在text串的第n个字符后插入s串

    deleteStr(text,start,n);             //删除text串中从第start 个字符开始,连续n个字符的串

    请补充定义insertStr函数和deleteStr函数(不使用标准库函数)。函数不需要考虑字符串的允许长度。

    #include<iostream>

    using namespacestd;

    voidinsertStr(char *t, char *s,int n);

    voiddeleteStr(char *t, int start, int n);

    void main()

    {  char text[256]="\0";

       char s[128]="\0";

       int k,n,start;

       while(1)

       {  cout<<"当前字符串:"<<text<<endl;

          cout<<"请选择:1—插入字符串    2—删除字符串    0—退出\n";

          cin>>k;

          switch(k)

          { case 1:

                {  cout<<"请输入字符串:";

                   cin>>s;

                   cout<<"插入位置?";

                   cin>>n;

                   insertStr(text,s,n);

                   break;

                }

             case 2:

                {  cout<<"请输入删除字符串开始位置:";

                   cin>>start;

                   cout<<"被删串长?";

                   cin>>n;

                   deleteStr(text,start,n);

                   break;

                }

             case 0: return;

          }

       }

    }

    【解答】

    voidinsertStr(char *t, char *s,int n)

    {

      int i,k;

      int lens=strlen(s);

      int lent=strlen(t);

      if(lent==0)

              n=0;

      for(i=lent;i>=n;i--)

        t[i+lens]=t[i];

      for(k=0;k<lens;k++)

        t[++i]=s[k];

    }

     

    voiddeleteStr(char *t,int start, int n)

       int i=start-1;

       while(t[i+n])

             { t[i]=t[i+n];

              i++;

             }

             t[i]='\0';

    }

    综合练习

    一、思考题

    1.数组说明语句要向编译器提供什么信息?请写出一维数组、二维数组说明语句的形式。

    【解答】

    数组说明语句要向编译器提供数组名(标识符),数组元素的类型、数组维数、数组长度(元素的个数)等信息。

    一维数组说明语句为: 类型 数组名[表达式]

    二维数组说明语句为: 类型 数组名[表达式1] [表达式2]

     

    2.数组名、数组元素的区别是什么?归纳一维数组元素地址、元素值不同的表示形式。若有说明:

    int aa [3], *pa=aa;

    请使用aa或pa,写出三个以上与aa[2]等价的表达式。

    【解答】

    数组名是一个标识符,执行代码中代表数组的地址,即指向数组起始位置的指针;而数组元素是下标变量,性质相当于普通变量。

    对一维数组aa第i个元素的地址可以表示为:     &aa[i]         aa+i;

    对一维数组aa第i个元素的值可以表示为:         a[i]             *(a+i);

    与aa[2]等价的表达式:

    *(aa+2)        *(&a[2])     *(pa+2)      pa[2]

     

    3.要把一维数组int a[m*n] 的元素传送到二维数组int b[m][n]中,即在程序中要执行:

    b[i][j]=a[k];

    请写出ki, j的下标变换公式,并用程序进行验证。

    【解答】

    转换公式:  i=k/n  j=k%n

    验证程序:

    #include<iostream>

    using namespacestd;

    int main()

    {

    const intM=3,N=4;

      int k,a[M*N]={1,2,3,4,5,6,7,8,9,10,11,12},b[M][N];

      int i,j;

      cout<<"array a:"<<endl;

      for( k=0; k<M*N; k++ )

         b[k/N][k%N] = a[k];

      for( k=0; k<M*N; k++ )

     cout<<a[k]<<'\t';

      cout<<endl;

    cout<<"**Afterconvert**"<<endl;

      cout<<"array b:"<<endl;

      for(i=0;i<M;i++)

      {

    for(j=0;j<N;j++)cout<<b[i][j]<<'\t';

           cout<<endl;

      }

    }

     

    4.有以下函数:

    void query()

    {  int *p;

       p=newint[3];

       //…

       delete []p;

       p=new double[5];

       //…

      delete []p;

    }

    出现了编译错误。请分析错误的原因,并把上述程序补充完整,上机验证你的判断。

    【解答】

    在语句p=new double[5]; 中企图把动态浮点型数组的地址写入整型指针p,造成错误。错误为:

    errorC2440: “=”: 无法从“double *”转换为“int *”。

    改正方法:增加一个double*q指针。

    void query()

    {

    int *p;

      p=new int[3];

      delete [] p;

      //……

      double *q;

      q=new double[5];

    //……

      delete []q;

    }

     

    5.有以下程序,设计功能是调用函数create建立并初始化动态数组,令a[i]=i。但该程序运行后不能得到期望结果,请分析程序的错误原因并进行修改。

    #include <iostream>

    using namespace std;

    void create(int *, int);

    int main()

    {  int *a =NULL, len;

       cin>>len;

       create(a,len);

       for(int i = 0; i<len; i++ )

       cout<< a[i] << "   ";

       cout<< endl;

       delete[]a;

       a =NULL;

    }

    void create(int *ap, int n)

    {  ap=newint[n];

       for(inti=0; i<n; i++) ap[i]=i;

    }

       【解答】

    函数create中,指针参数int*ap是传地址值的参数。调用函数时接受实际参数a的值(地址值)作为初始值。ap仅是局部变量,ap=newint[n]获得新的地址值,函数执行完毕返回,ap被释放,完全与实际参数a无关。程序没有编译错误,但main不能获得动态数组。修改方法是把ap改为指针引用参数。

    void create(int*&,int);                      //函数原型声明,使用引用参数

    void create(int*&ap,int n)           //函数定义

    {

    ap=newint[n];

    for(inti=0;i<n;i++)

    ap[i]=i;

    }

     

    二、程序设计

    1.已知求成绩的平均值和均方差公式:, ,其中,n为学生人数,si为第i个学生成绩。求某班学生的平均成绩和均方差。

    【解答】

    #include<iostream>

    #include<cmath> 

    using namespacestd;

    void aveMsd(double [], int, double &, double & );    //求平均值和均方差值函数

    int main()

    {

    double s[] = {76, 85, 54, 77, 93, 83, 90, 67, 81, 65 };

    double ave, msd;

    int i,n;

    n = sizeof( s)/sizeof( double );     //求数组元素的个数

    cout<<"学生成绩:";

    for( i=0; i<n;i++ )

      cout<<s[i]<<"  ";

    cout<<endl;

    aveMsd( s, n,ave, msd );

    cout <<"平均值:" <<ave << endl << "均方差值:"<< msd << endl;

    }

    void aveMsd(double s[], int n, double &ave, double &msd )

    {

    int i;

    double sum1=0,sum2=0;

    for( i=0; i<n;i++ )             //求平均值

       sum1 += s[i];

    ave = sum1/n;

    for( i=0; i<n;i++ )             //求均方差

       sum2 += pow( s[i]-ave, 2 );

    msd = sqrt(sum2/n );

    }

     

    2.用随机函数产生10个互不相同的两位整数存放到一维数组中,并输出其中的素数。

    【解答】

    #include<iostream>

    #include<cmath>        

    #include <cstdlib>

    #include<ctime>

    using namespace std;

    int main()

    {

    int a[10],i,j;

      srand( int( time(0)) );           //为随机数生成器设置种子值

      for( i=0; i<10; i++ )

      {

     l: a[i] = rand();                 //产生随机数存放到数组中

           if ( a[i]<10 || a[i]>=100 )                   //获取指定范围数据

    goto l;

               for( j=0; j<i;j++ )                              //排除相同数据

              if( a[i]==a[j] )

    goto l;

      }

      for( i=0; i<10; i++ )

         cout << a[i] << "   ";

      cout << endl;

      for( i=0; i<10; i++ )

      {

    double m=sqrt( double(a[i]) );

         for( j=2; j<=m; j++)

            if( a[i] % j == 0 )break;

         if( j>m )

           cout << a[i] << "   ";

      }

      cout << "是素数!" << endl;

    }

     

    3.将一组数据从大到小排列后输出,要求显示每个元素及它们在原数组中的下标。

    【解答】

    #include<iostream>

    usingnamespace std;

    intmain()

    {

    int a[] = { 38, 6, 29, 1, 25, 20, 6, 32,78, 10 };

     int index[10];           //记录下标的数组

     int i,j,temp;

      for( i=0; i<10; i++ )

        index[i] = i;

     for( i=0; i<=8; i++ )

        for( j=i+1; j<=9; j++ )

          if( a[i] < a[j] )

          {

    temp = a[i]; a[i] = a[j]; a[j] = temp;

             temp = index[i]; index[i] = index[j]; index[j] = temp;

          }

     for( i=0; i<10; i++ )

        cout << a[i] << '\t' << index[i] << endl;

    }

     

    4.从键盘输入一个正整数,判别它是否为回文数。所谓回文数,是指正读和反读都一样的数。例如,123321是回文数。

    【解答】

    #include<iostream>

    usingnamespace std;

    intmain()

    {

    int b[10], i, j, k, flag ;

     long num, n ;

     cout << "num=" ; cin >> num;

      k= 0;

      n= num;

     do                                         //拆分整数,把各数字放入数组b

      {

    b[k++] = n % 10;

        n = n/10;

      }while( n != 0);

     flag=1;                                      //判断标志

     i=0; j=k-1;                                //设置指示下标的指针

     while(i<j)

       if( b[i++] != b[j--] )                           //对称位置元素不相等

        {

     flag = 0;           

          break ;

        }

     if( flag )  cout << num<< "是回文数!" << endl;

     else  cout << num <<"不是回文数!" << endl;

    }

     

    5.把两个升序排列的整型数组合并为一个升序数组。设计好算法,以得到较高的运行效率。

    【解答】

    #include<iostream>

    using namespacestd;

    void merge(constint a[],int na, const int b[],int nb, int c[],int nc);

    int main()

    {

    int a[4] = { 1,2, 5, 7 };

      int b[8] = { 3, 4, 8, 8, 9, 10, 11, 12 };

      int c[12];

      int i;

      merge( a,4,b,8,c,12 );

      for( i=0; i<12; i++ )

        cout << c[i] << "   ";

      cout << endl;

    }

    void merge(constint a[],int na, const int b[],int nb, int c[],int nc)

    {

    int i,j,k;

      i = j = k = 0;

      while( i<na && j<nb )

      {

        if( a[i] > b[j] )                       //当a[i]>b[j],把b[i]写入数组c

          { c[k] = b[j];  k++; j++; }

        else                          //当a[i]<=b[j],把a[i]写入数组c

          { c[k] = a[i];  k++; i++; }

    }

      while( i<na )

      {

    c[k] = a[i];  i++; k++;                   //把数组a的剩余元素写入数组c

    }    

      while( j<nb )

      {

    c[k] = b[j];  k++; j++;                   //把数组b的剩余元素写入数组c

    }    

    }

     

    6.输入一个表示星期几的数,然后输出相应的英文单词。要求:使用指针数组实现。

    【解答】

    #include<iostream>

    usingnamespace std;

    intmain()

    {

    char *weekday[7]

    = { "sunday","monday", "tuesday","wednesday","thursday", "friday", "saturday" };

     int d;

     cout << "please input week day: ";

     cin >> d;

     if( d>=0 && d<=6 )

    cout << d << "---"<< *( weekday + d ) <<endl;

     else

     cout << "input error!"<< endl;

    }

     

    7.编写以下函数:

    (1)在一个二维数组中形成以下形式的n阶矩阵:

    (2)去掉靠边的元素,生成新的n-2阶矩阵;

    (3)求矩阵主对角线下元素之和;

    (4)以方阵形式输出数组。

    在main函数中调用以上函数进行测试。

    【解答】

    #include<iostream>

    usingnamespace std;

    void create( int *&app, int n );

    void del( int *&app, int *&bpp,int n );

    int maindiagonal( int *&app, int n );

    void output( int *&app, int );

    int main()

    {

    int *ap = NULL, *bp = NULL, n;

     cout << "输入矩阵的阶:";

     cin >> n;

     create( ap,n );

     cout << "\n形成矩阵:\n";

     output( ap, n );

     cout << "去掉靠边元素生成的矩阵:\n";

     del( ap,bp,n );

      output(bp,n-2 );

     cout << "主对角线元素之和:"<< maindiagonal( ap, n ) <<endl;

    }

    //形成n阶矩阵函数

    void create( int * &app, int n )

    {

    app = new int[ n*n ];

     int i,j,k = 0;

     for( i=0; i<n; i++ )

       for( j=0; j<n; j++ )

        {

     if( i<=j )

    app[k] = 1;

           else

     app[k] = i-j+1;

           k++;

        }

    }

    //去掉靠边元素生成n-2阶矩阵函数

    void del( int *&app, int *&bpp,int n )

    {

     int i,j,k = 0;

     bpp = new int[ ( n-2 )*( n-2 ) ];

     for ( i=0; i<n; i++ )

      {

    for( j=0; j<n; j++ )

              if ( i && j && i<n-1&& j <n-1 )

              {

     bpp[k]= *( app + i*n + j );   

                 k++;

            }

      }

    }

    //求主对角线元素之和函数

    int maindiagonal( int *&app, int n )

    {

    int i,j,k = 0,sum = 0;

     for ( i=0; i<n; i++ )

      {

     for( j=0; j<n; j++ )

              if( i==j )

                sum += *( app + i*n + j);

      }

     return sum;

    }

    //以方阵的形式输出数组函数

    void output( int *&app, int n )

    {

     int i,j;

     for ( i=0; i<n ; i++ )

      {

    for( j=0; j<n; j++ )

               cout << *( app + i*n + j)<<  '\t';

       cout<<endl;

      } 

     cout<<endl;

    }

     

    8.设某城市三个百货公司某个季度销售电视机的情况和价格如下所示。编写程序,将表数据用数组存放,求各百货公司的电视机营业额。

    牌号

    价格

    康佳

    3500

    TCL

    3300

    长虹

    3800

     

     

              牌号

     公司

    康佳

    TCL

    长虹

    第一百货公司

    300

    250

    150

    第二百货公司

    200

    240

    200

    第三百货公司

    280

    210

    180

    【解答】

    #include<iostream>

    usingnamespace std;

    intmain()

    {

    long s[][3] = { { 300, 250, 150 }, { 200,240, 200},{ 280, 210, 180 } };

     long p[] = { 3500, 3300, 3800 };

     int i,j;

     double sum;

     for( i=0; i<3; i++ )

      {

    sum=0;

       for( j=0; j<3; j++)

         sum += s[i][j] * p[j];

       cout << "第"<< i+1 << "百货公司的电视机营业额:  " << sum << endl;

      }

    }

     

    9.设计函数求一整型数组的最小元素及其下标。在主函数中定义和初始化该整型数组,调用该函数,并显示最小元素值和下标值。

    【解答】

    #include<iostream>

    usingnamespace std;

    int fmin(int [], int);

    int main()

    {

    int a[ ] = { 73, 85, 62, 95, 77, 56, 81,66, 90, 80 };

     int index;

     index = fmin( a, sizeof(a)/sizeof(int) );

     cout << "The minnum number is : " << a[index]<< endl;

     cout << "The index is : " << index << endl;

    }

    int fmin( int a[], int size )

    {

    int i,min = a[0], index = 0;

     for( i=0; i<size; i++ )

       if( a[i]<min )

    {

     min = a[i];

    index = i;

    };

     return index;

    }

     

    10.假设有从小到大排列的一组数据存放在一个数组中,在主函数中从键盘输入一个在该数组的最小值和最大值之间的数,并调用一个函数把输入的数插入到原有的数组中,保持从小到大的顺序,并把最大数挤出。然后在主函数中输出改变后的数组。

    【解答】

    #include<iostream>

    usingnamespace std;

    void insert( int a[],int,int );

    int main()

    {

     int a[] = { 10, 12, 23, 25, 48, 48, 53, 58,60, 78 };

     int x,n,i;

     cout << "please input insert data: ";

     cin >> x;

      n= sizeof(a)/sizeof(int);                //求数组长度

     insert( a, n, x );                         //插入元素

     for( i=0; i<n; i++ )

       cout << a[i] << "  ";

    cout << endl;

    }

    void insert( int a[],int n,int x )

    {

     int i,p,j;

      if( x<a[n-1] )

      {

     for( i=1; i<n; i++ )      //查找插入位置

         if( x<a[i] )

    {

     p=i; break;

    }

         for( j=n-1; j>=p; j-- )                //后移元素,挤出最大值

            a[j] = a[j-1];

         a[p] = x;                                              //插入元素

      }

    }

     

    11.一个整型数组的每个元素占4字节。编写一个压缩函数pack,把一个无符号小整数(0~255)数组进行压缩存储,只存放低8位;再编写一个解压函数unpack,把压缩数组展开,以整数形式存放。主函数用随机函数生成数据初始化数组,测试pack和unpack函数。

    【解答】

    #include<iostream>

    #include <cstdlib>

    #include<ctime>

    using namespace std;

    void pack( int *a, unsignedchar *p,int n );

    void unpack( unsigned char *p, int *a, int n );

    int main()

    {

       int*ary, n, i;

       unsigned char *packary;

       cout<<"请输入数组长度:";

       cin>>n;

       ary= new int [n];                                     //建立动态数组

       packary= new unsigned char[n];             //压缩数组

       srand(int(time(0)));

       for(i=0;i<n;i++)                                        //产生随机数并存放到动态数组中

          ary[i]=rand()%256;

       pack(ary, packary, n );

       cout<<"\n输出压缩数组:";

       for(i=0; i<n; i++ )

       {

          if (i %10 == 0)  cout<<endl;            //控制一行输出10个数据

          cout << int( packary[i] )<<"  ";

       }

       unpack(packary, ary, n);

       cout<<"\n输出解压数组:";

       for(i=0; i<n; i++ )

       {

          if (i %10 == 0)  cout<<endl; 

          cout<<ary[i]<<"  ";

       }

    }

    void pack( int *a, unsigned char *p, int n )

    {

       for(inti=0; i<n; i++)

       {

          p[i] =unsignedchar(a[i]);

       }

    }

    void unpack( unsigned char *p, int *a, int n )

    {

       for(inti=0; i<n; i++)

       {

          a[i] = int(p[i]);

       }

    }

     

    12.编写程序,按照指定长度生成动态数组,用随机数对数组元素进行赋值,然后逆置该数组元素。例如,数组A的初值为{6, 3, 7, 8, 2},逆置后的值为{2, 8, 7, 3, 6}。要求:输出逆置前、后的数组元素序列。

    【解答】

    #include<iostream>

    #include <cstdlib>

    #include<ctime>

    usingnamespace std;

    void printarray(int *p,int n);

    void adverse(int *p,int n);

    int main()

    {

    int *p,n,i;

     cout<<"请输入数组长度:";

     cin>>n;

     p=new int [n];            //建立动态数组

     srand(int(time(0)));

     for(i=0;i<n;i++)          //产生随机数并存放到动态数组中

       *(p+i)=rand()%1000;

     cout<<"动态数组:";

     printarray(p,n);            // 输出动态数组

     adverse(p,n);              // 对数组逆置

     cout<<"逆置数组:"; 

     printarray(p,n);            // 输出逆置数组

    }

     //输出数组函数

    void printarray(int *p,int n)

    {

    int i;

     for( i=0; i<n; i++ )

      {

     if(i % 5==0) cout<<endl;   // 控制一行输出5个数据

            cout<<"ary["<<i<<"]="<<*(p+i)<<"\t";

    }

     cout<<endl;   

     }

    // 对数组逆置函数

    void adverse(int *p,int n)

    {

     int i,t;

    for (i=0;i<n/2;i++)

      {

     t=*(p+i);

       *(p+i)=*(p+n-i-1);

       *(p+n-i-1)=t;

    }

    }

     

    13.把某班学生的姓名和学号分别存放到两个数组中,从键盘输入某位学生的学号,查找该学生是否在该班,若找到该学生,则显示出相应的姓名。

    【解答】

    #include<iostream>

    usingnamespace std;

    intmain()

    {

    char name[5][20] = { "li ming","zhang qing", "liu xiao ping", "wang ying","lu pei" };

     long num[5] = { 20030001, 20030002, 20030005, 20030007, 20030010 };

     int i;

     long snumber;

     cout << "please input studentnumber:";

     cin >> snumber;

     for( i=0; i<5; i++ )

      {

     if( num[i] == snumber )

        {

     cout << "Found! The name is :"<< name[i] << endl;

             break;

    }

      }

     if( i==5 )  cout <<"Can\'t found!" << endl;

    }

     

    14.将一组C++关键字存放到一个二维数组中,并找出这些关键字中的最小者。

    【解答】

    #include<iostream>

    #include<cstring>

    usingnamespace std;

    intmain()

    {

     char string[10];

     char str[][10]={ "while", "break", "if","extern", "void", "auto", "long","static", "do", "const" };

     int i;

     strcpy_s( string, str[0] );

     for( i=0; i<10; i++ )

       if( strcmp(str[i],string)<0 ) strcpy_s( string, str[i] );

     cout << "The minimum string is:" << string<< endl;

    }

     

    15.使用指针函数编写程序,把两个字符串连接起来。

    【解答】

    #include<iostream>

    usingnamespace std;

    char *strcat( char *str1,char *str2 )

    {

     char*p = str1;

     while( *p != '\0' ) p++;

     *p = *str2;

     do

    p++;

       str2++;

       *p = *str2;

    } while( *str2 != '\0' );

     return( str1 );

    }

    int main()

    {

     char str1[80], str2[80];

     cout << "input str1:";

    cin >> str1;

     cout << "input str2:"; 

    cin >> str2;

     cout << "str1+str2=" << strcat( str1, str2 )<< endl;

    }

     

    16.使用string类,编写一个简单的文本编辑程序,能够实现基本的插入、删除、查找、替换等功能。

    【解答】

    略。

     

    推荐阅读
    全部习题章节:
    C++课本的练习题及答案(第四章)
    C++课本的练习题及答案(第五章)
    C++课本的练习题及答案(第六章)
    C++课本的练习题及答案(第七章)
    C++课本的练习题及答案(第八章)
    展开全文
  • 李忠哗版面向c++课本第二章到第十章各章习题代码集,对于基础好的同学而言,可节省很多时间去完成自己感兴趣对的C++项目。
  • 谭浩强版的c++课本上的所以例子,全部由本人亲自调试一遍,和大家分享一下
  • c++课本第一章

    2017-02-23 21:17:20
    第一章没讲太多内容,就对c++面向对象程序设计进行了介绍 一· cin 1. 析取运算符>> 当程序执行到cin时就会停下来等待键盘的输入,输入的数据被插入到输入流中,当遇到>>时就从输入流中提取一个数据,存入内存变量...

    第一章没讲太多内容,就对c++面向对象程序设计进行了介绍
    一· cin
    1. 析取运算符>> 当程序执行到cin时就会停下来等待键盘的输入,输入的数据被插入到输入流中,当遇到>>时就从输入流中提取一个数据,存入内存变量中。
    2. cin 是在 iostream中预定义的一个标准输入设备(一般代表键盘)>>是析取运算符,用于从输入流中析取数据。
    3. cin遇到空白,回车和tab就结束了。
    4. 在>>后面只能出现变量名,cin具有自动识别数据类型的能力,析取运算符在输入流中为他们提取对应的数据。
    5. 数值型数据的输入,在读取数值数据的型时,析取运算符>>首先忽略前面所有的空白符号,如果遇到正,负或者数字时就开始读入,并在遇到空白符或者是其他非数字字符就停止。(在c中也是这样,真是血淋淋的教训啊)。
    这里写图片描述

    二· cout
    1.在输出的时候如果是字符串类型或者是字符型都要加双引号,在数值类型时不用加,如果用/n来表示换行,则要加双引号,如果用endl则不用加双引号。
    2.cout与cin都可以把多条指令写在多行。

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        char ch1='c';
        char ch2[]="Hellow C++!";
        cout<<ch1<<endl;
    
        cout<<ch2<<endl;
        cout<<"C"<<" "
             <<"Hellow C++!"
             <<"\n";
        return 0;
    }
    

    这里写图片描述
    三. 输出格式控制
    1.c++中提供了许多控制数据输入输出格式的函数和操纵符(也称为操纵函数或者操纵算子),如setprecision,setw,right等,他们是在iomanip中定义的。
    2.设置浮点数的精度
    在需要控制输出数据的精度时,可以用setprecision(n),其中,n代表有效位数,包括整数的位数和小数的位数,如果用setprecision设置精度则他要到下次用setprecision()才会改变精度。
    注意如果是浮点数则包括整数部分和小数部分,但是不包括小数点。并且要注意和setw的区别,一次设置到重新设置才无效。
    这里写图片描述
    3.设置输出域宽和对齐方式
    用操纵函数setw来设置输出数据的占用列数(域宽,即占用的字符个数) setw(n),其中n是输出数据占用的字符个数,在默认情况下输出右对齐,则左边留空,如果输出数据的实际位数比n大,则输出数据将自动扩展到所需的占用列数。
    setw只对紧随其后的输出数据有效。
    这里写图片描述
    4. 设置对其方式
    操纵符setiosflags()和rsetiosflags()用于设置或者是取消输入输出数据的各种格式,包括数制基数,设置浮点数的精度,转换字母大小写,设置对齐方式等,用法如下: setiosflags(long f);
    resetiosflags(long f);在iostream中还定义了两个对齐方式的常数,表示左对齐的常数值是ios::left,表示右对齐的常数值是ios::right,他们可作为setiosflags()和resetiosflags()操作符的参数,用于设置输出数据的对齐方式。当用setiosflags()设置对齐之后会一直有效,直到resetiosflags()取消。
    四. 数制基数
    1.c++在iostream中预定义了hex,oct,dec等操纵符,分别表示十六进制,八进制和十进制数,在默认方式下,c++按照十进制数形式输入输出,当要按其他进制输入输出时,就需要在cin和cout语句中指定数据的基数。
    十进制整数:直接输入数据本身,如78;
    十六进制整数:要在输入的数据前面加上0x或0X,如0x1A(对应的十进制数是26);
    八进制整数:在输入的数据前加0,如043(代表十进制数35)。
    并且在设置基数之后会一直有效,直到遇到下一基数设置。

    c++的第一章就这么多,感觉写了好长时间啊,要去刷题了,还要去给评分,真是麻烦啊。

    setiosflags和数制基数在下一篇文章中在详细介绍一下吧。明天早上请假,不用去跑操了,开心。

    展开全文
  • Accelerated C++源代码
  • 很好的一般c++教科书,英文版本,在国外评价很好,里面的讲解循序渐进,非常容易理解。不可用于商业用途,仅供大家自学。
  • 谭浩强C++课本习题答案,这是一部被奉为经典的C++编程教程
  • 谭浩强 C++ 课本教材 课本例题 课本课后习题答案 附有程序代码
  • C++课本的练习题及答案(第八章)

    千次阅读 2020-04-07 17:31:19
    (A)C++允许派生类的成员与基类成员重名 (B)在派生类中访问重名成员时,屏蔽基类的同名成员 (C)在派生类中不能访问基类的同名成员 (D)如果要在派生类中访问基类的同名成员,可以显式地使用作用域符指定 8....

    第8章练习题

    同步练习8.1

    1.一个大的应用程序,通常由多个类构成,类与类之间互相协同工作, 它们之间有三种主要关系。下列不属于类之间关系的是(    )。

    (A)gets-a               (B)has-a                  (C)uses-a           (D)is-a

    2.在C++中,类之间的继承关系具有(    )。

    (A)自反性              (B)对称性                  (C)传递性           (D)反对称性

    3.下列关于类之间关系的描述,正确的是(    )。

    (A)has-a表示一个类部分地使用另一个类 (B)uses-a表示类的包含关系

    (C)is-a关系具有对称性。                      (D)is-a机制称为“继承”

    4.下列关于类的描述,正确的是(    )。

    (A)父类具有子类的特征                        (B)一个类只能从一个类继承

    (C)is-a关系具有传递性                         (D)uses-a表示类的继承机制

    5.下列关于类之间关系的描述,错误的是(    )。

    (A)用有向无环图(DAG)表示的类之间关系,称为“类格”

    (B)DAG中每个结点是一个类定义,它的前驱结点称为基类

    (C)DAG中每个结点是一个类定义,它的后继结点称为派生类

    (D)DAG中每个结点是一个类定义,它有且仅有一个前驱结点

    6.下列关于类的继承描述中,正确的是(    )。

    (A)派生类公有继承基类时,可以访问基类的所有数据成员,调用所有成员函数。

    (B)派生类也是基类,所以它们是等价的。

    (C)派生类对象不会建立基类的私有数据成员,所以不能访问基类的私有数据成员。

    (D)一个基类可以有多个派生类,一个派生类可以有多个基类。

    【解答】     A     C     D     C     D     D

     

    同步练习8.2

    一、选择题

    1.当一个派生类公有继承一个基类时,基类中的所有公有成员成为派生类的(    )。

    (A)public成员        (B)private成员    (C)protected成员       (D)友元

    2.当一个派生类私有继承一个基类时,基类中的所有公有成员和保护成员成为派生类的(    )。

    (A)public成员        (B)private成员    (C)protected成员       (D)友元

    3.当一个派生类保护继承一个基类时,基类中的所有公有成员和保护成员成为派生类的(    )。

    (A)public成员        (B)private成员    (C)protected成员       (D)友元

    4.不论派生类以何种方式继承基类,都不能直接使用基类的(    )。

    (A)public成员        (B)private成员    (C)protected成员       (D)所有成员

    5.在C++中,不加说明,则默认的继承方式是(    )。

    (A)public               (B)private           (C)protected              (D)public或protected

    6.某公有派生类的成员函数不能直接访问基类中继承来的某个成员,则该成员一定是基类中的(    )。

    (A)私有成员           (B)公有成员        (C)保护成员               (D)保护成员或私有成员

    7.下列关于类层次中重名成员的描述,错误的是(    )。

    (A)C++允许派生类的成员与基类成员重名      

    (B)在派生类中访问重名成员时,屏蔽基类的同名成员

    (C)在派生类中不能访问基类的同名成员

    (D)如果要在派生类中访问基类的同名成员,可以显式地使用作用域符指定

    8.下列关于类层次中静态成员的描述,正确的是(    )。

    (A)在基类中定义的静态成员,只能由基类的对象访问

    (B)在基类中定义的静态成员,在整个类体系中共享

    (C)在基类中定义的静态成员,不管派生类以何种方式继承,在类层次中具有相同的访问性质

    (D)一旦在基类中定义了静态成员,就不能在派生类中再定义

    【解答】   A     B     C     B     B     A     C     B

     

    二、程序练习

    1.阅读程序,写出运行结果。

    #include<iostream>

    using namespace std;

    class Base

    {  public :

          void get(int i,int j,int k,int l )

          {  a = i; b = j; x = k;  y = l; }

          voidprint()

          {  cout << "a = "<< a<< '\t' << "b = " << b << '\t'

               << "x = " << x << '\t' << "y =" << y << endl;

          }

          int a, b;

       protected :

          int x, y;

    };

    class A : public Base

    {  public :

          void get(int i, int j, int k, int l )

          {  Base obj3;

            obj3.get( 50, 60, 70, 80 );

            obj3.print();

             a = i; b= j; x = k; y = l;

             u = a +b + obj3.a; v = y - x + obj3.b;

          }

          voidprint()

          {  cout << "a = " << a<< '\t' << "b = " << b << '\t'

                 << "x = " << x<< '\t' << "y = " << y << endl;

             cout<< "u = " << u << '\t' << "v = "<< v << endl;

          }

       private:

          int u, v;

    };

    int main()

    {  Base obj1;

       A obj2;

       obj1.get( 10, 20,30, 40 );

       obj2.get( 30,40, 50, 60 );

       obj1.print();

       obj2.print();

    }

    【解答】

     

    2.阅读程序,写出运行结果。

    #include<iostream>

    using namespace std;

    class A

    {  public :

          A( inti, int j )  {  a=i; b=j; }

          voidAdd( int x, int y )  {  a += x; b += y;  }

          voidshow()  {  cout <<"("<<a<<")\t("<<b<<")\n"; }

       private:

          int a,b;

    };

    class B : public A

    {  public :

          B(inti, int j, int m, int n) : A( i, j ),x( m ), y( n ) {}

          voidshow()  {  cout << "(" << x<< ")\t(" << y << ")\n";  }

          voidfun()  {  Add( 3, 5 );  }

          voidff()  {  A::show();  }

       private:

          int x,y;

    };

    int main()

    {  A a( 1, 2 );

       a.show();

       B b( 3,4, 5, 6 );

       b.fun();

       b.A::show();

       b.show();

       b.ff();

    }

    【解答】

     

    3.编写程序,定义一个Rectangle类,它包含:

    数据成员  length,width

    成员函数  Rectangle( double l, double w );                    //构造函数

    double area();                                                   //返回矩形面积

    double getlength();                                             //返回数据成员length的值

    double getwidth();                                             //返回数据成员width的值

    再定义Rectangle的派生类Rectangular,它包含:

    数据成员  height

    成员函数  Rectangular( double l, double w, double h );    //构造函数

    double volume();                                      //返回长方体体积

    double getheight();                                             //返回数据成员height的值

    在main函数中测试类体系,建立两个类的对象,显示它们的数据和面积、体积。

    【解答】

    #include <iostream>

    using namespace std;

    class rectangle

    {

     public:

      rectangle(double l, double w )

      {length = l; width = w; }

      doublearea()

      {  return( length*width ); }

      doublegetlength()

      {return length; }

      doublegetwidth()

      {return width; }

     private:

       double length;

      doublewidth;

    };

    class rectangular: public rectangle

    {

      public:

      rectangular(double l,double w,double h ) : rectangle( l,w )

        {height = h; }

       double getheight()

      {return height; }

      doublevolume()

      {return area() *height; }

     private:

      doubleheight;

    };

    int main()

    {

      rectangleobj1( 2,8 );

      rectangularobj2( 3,4,5 );

      cout<<"length="<<obj1.getlength()<<'\t'<<"width="<<obj1.getwidth()<<endl;

      cout<<"rectanglearea="<<obj1.area()<<endl;

      cout<<"length="<<obj2.getlength()<<'\t'<<"width="<<obj2.getwidth();

      cout<<'\t'<<"height="<<obj2.getheight()<<endl;

      cout<<"rectangularvolume="<<obj2.volume()<<endl;

    }

     

    同步练习8.3

    一、选择题

    1.在C++中,可以被派生类继承的函数是(    )。

    (A)成员函数           (B)构造函数        (C)析构函数        (D)友元函数

    2.下列关于派生类对象的初始化,叙述正确的是(    )。

    (A)是由派生类的构造函数实现的

    (B)是由基类的构造函数实现的

    (C)是由基类和派生类的构造函数实现的

    (D)是系统自动完成的,不需要程序设计者干预

    3.在创建派生类对象时,构造函数的执行顺序是(    )。

    (A)对象成员构造函数—基类构造函数—派生类本身的构造函数

    (B)派生类本身的构造函数—基类构造函数—对象成员构造函数

    (C)基类构造函数—派生类本身的构造函数—对象成员构造函数

    (D)基类构造函数—对象成员构造函数—派生类本身的构造函数

    4.在具有继承关系的类层次体系中,析构函数执行的顺序是(    )。

    (A)对象成员析构函数—基类析构函数—派生类本身的析构函数

    (B)派生类本身的析构函数—对象成员析构函数—基类析构函数

    (C)基类析构函数—派生类本身的析构函数—对象成员析构函数

    (D)基类析构函数—对象成员析构函数—派生类本身的析构函数

    5.在创建派生类对象时,类层次中构造函数的执行顺序是由(    )。

    (A)派生类的参数初始式列表的顺序决定的       (B)系统规定的

    (C)是由类的书写顺序决定的                         (D)是任意的

    【解答】   A     C     D     B     B

     

    二、程序练习

    1.阅读程序,写出运行结果。

    #include<iostream>

    using namespace std;

    class Base1

    {  public :

          Base1( inti )

          {  cout << "调用基类Base1的构造函数:" << i<< endl;  }

    };

    class Base2

    {  public:

          Base2( intj )

          {  cout << "调用基类Base2的构造函数:" << j<< endl;  }

    };

    class A : public Base1, public Base2

    {  public :

          A( inta,int b,int c,int d ):Base2(b),Base1(c),b2(a),b1(d)

          {  cout << "调用派生类A的构造函数:" <<a+b+c+d << endl;  }  

       private :

          Base1 b1;

          Base2 b2;

    };

    int main()

    {  A obj( 1, 2,3, 4 );

    }

    【解答】

     

    2.编写程序。已知有一个描述个人信息的Person类,数据成员记录个人姓名name和身份证号idNumber;成员函数print输出个人信息,构造函数完成对数据成员的初始化。请根据Person类和main函数运行结果,补充定义Person类的派生类Teacher类,除了记录教师的姓名和身份证号,还须记录职称title和工资wage;成员函数print输出教师个人信息,构造函数完成对数据成员的初始化。

    #include <iostream>

    #include<string>

    using namespace std;

    class Person

    {  private:

          string name;                        //姓名

          string idNumber;                 //身份证号

       public:

          Person( const char *n, constchar *i) 

            {  name= n;

               idNumber = i;

            }

          void Print() const

          { cout<<"Name: "<<name<<"\n\tidNumber:"<<idNumber<<endl;

       }

    };

    //此处定义Teacher类

    int main()

    {  Personp("张少华","420106196611070538");

       Teacher t("李若山","420106195801247168", "教授", 5000);

       p.Print();

       t.Print();

    }

    程序运行结果:

    Name:张少华

                      idNumber:420106196611070538

    Name:李若山

                      idNumber:420106195801247168

                      Title:教授         Wage:5000

    【解答】

    #include <iostream>

    #include<string>

    using namespace std;

     

    class Person

    {

    private:

        string name;        //姓名

        string idNumber;  //身份证号

      public:

        Person( const char *n, const char *i) 

         {

                    name= n;

                    idNumber= i;

         }

        void Print() const

         { cout<<"Name:"<<name<<"\n\tidNumber: "<<idNumber<<endl;

         }

    };

    //定义Teacher类

    class Teacher : public Person

    {

      private:

             stringtitle;             //职称

             doublewage;         //工资

      public:

             Teacher(const char *n, const char *i, const char *t, double w)

                    :Person(n, i)

             {

                    title= t; wage = w;

             }

             voidPrint() const

             {

                    Person::Print();

                    cout<<"\tTitle:"<<title<<"\tWage: "<<wage<<endl;

             }

    };

    int main()

    {

      Personp("张少华", "420106196611070538");

      Teachert("李若山", "420106195801247168","教授", 5000);

      p.Print();

      t.Print();

    }

     

    同步练习8.5

    一、选择题

    1.当不同的类具有相同的间接基类时,(    )。

    (A)各派生类无法按继承路线产生自己的基类版本

    (B)为了建立唯一的间接基类版本,应该声明间接基类为虚基类

    (C)为了建立唯一的间接基类版本,应该声明派生类虚继承基类

    (D)一旦声明虚继承,基类的性质就改变了,不能再定义新的派生类

    2.下列关于多继承的描述,错误的是(     )。

    (A)一个派生类对象可以拥有多个直接或间接基类的成员

    (B)在多继承时不同的基类可以有同名成员

    (C)对于不同基类的同名成员,派生类对象访问它们时不会出现二义性

    (D)对于不同基类的不同名成员,派生类对象访问它们时不会出现二义性

    3.下面关于基类和派生类的描述,正确的是(     )。

    (A)一个类可以被多次说明为一个派生类的直接基类,可以不止一次地成为间接基类

    (B)一个类不能被多次说明为一个派生类的直接基类,可以不止一次地成为间接基类

    (C)一个类不能被多次说明为一个派生类的直接基类,且只能成为一次间接基类

    (D)一个类可以被多次说明为一个派生类的直接基类,但只能成为一次间接基类

    4.下列关于虚继承的说明形式的描述,正确的是(     )。

    (A)在派生类类名前添加关键字virtual             (B)在基类类名前添加关键字virtual

    (C)在基类类名后添加关键字virtual        

    (D)在派生类类名后,类继承的关键字之前添加关键字virtual

    5.设置虚基类的目的是(     )。

    (A)简化程序           (B)消除二义性            (C)提高运行效率  (D)减少目标代码

    【解答】  C     C     B     D     B

     

    二、程序练习

    1.阅读程序,写出运行结果。

    #include<iostream>

    using namespace std;

    class A

    {  public :

          A(constchar *s)  {  cout << s << endl;  }

          ~A() {}

    };

    class B : virtual public A

    {  public :

          B(constchar *s1, const char *s2) : A( s1 )  {  cout << s2 << endl;  }

    };

    class C : virtual public A

    {  public :

          C(const char *s1, const char *s2):A(s1)  {  cout<< s2 << endl;  }

    };

    class D : public B, public C

    {  public :

          D( constchar *s1,const char *s2,const char *s3,const char *s4 ):

          B(s1, s2 ), C( s1, s3 ), A( s1 )

          {  cout << s4 << endl;  }

    };

    int main()

    {  D *ptr = newD( "class A", "class B", "class C", "classD" );

       delete ptr;

    }

     
     

    【解答】

     

    综合练习

    一、思考题

    1.函数和类这两种程序模块都可以实现软件重用,它们之间有什么区别?

    【解答】

    函数是基于参数集的功能抽象模块,以调用方式实现软件重用,函数之间没有逻辑关系。

    类是数据属性与操作的封装,以继承方式实现软件重用,类之间构成有向无回图的类格。

     

    2.按照类成员的访问特性、类层次的继承特点,制作一张表格,总结各种类成员在基类、派生类中的可见性和作用域。

    【解答】

               基类成员

    派生类继承

    public

    protected

    private

     

    public

    在派生类中访问特性不变。派生类和类外均可见,有作用域。

    在派生类中访问特性不变。类体系中可见。

    基类私有成员,仅在基类中可见。

    protected

    成为派生类保护段成员。在整个类体系中可见。

    private

    成为派生类私有成员。仅在派生类和基类中可见。

     

    派生类不论以何种方式继承基类,基类所有成员在整个类体系有作用域。

     

    3.若有以下说明语句:

    class A

    {  private : inta1;

    public : int a2; double x;

     /*…*/

    };

    class B : private A

    {  private : intb1;

       public : int b2;  double x;

    /*…*/

    };

    B b;

    对象b将会生成什么数据成员?与继承关系、访问特性、名字有关吗?

    【解答】

    对象b生成的数据成员有a1 a2 A::x b1 b2 B::x,共六个数据成员。数据成员的建立和继承关系、访问特性、名字无关。

     

    4.若有以下说明语句:

    class A

    {  /*…*/

       public : void sameFun();

    };

    class B : public A

    {  /*…*/

       public : void sameFun();

    };

    void comFun()

    {  A a;

       B b;

       /*…*/

    }

    (1)若在B::sameFun中调用A::sameFun,语句格式如何?它将在什么对象上操作?

    (2)在comFun中可以用什么方式调用A::sameFun和B::sameFun?语句格式如何?它们将可以在什么对象上操作?

    【解答】

    (1)若要在B::sameFun中调用A::sameFun,语句形式应为:

              A::samefun();         //域作用符说明调用基类函数

    调用的A::samefun将在B类对象上进行操作。

    (2)在comFun中调用B::sameFun和A::sameFun的方式有:

              a.A::sameFun();             //通过A类对象调用A::sameFun,在a类对象上操作

              b.sameFun();          //通过B类对象调用B::sameFun,在b类对象上操作

              b.A::sameFun();             //通过B类对象调用A::sameFun

    //在b类对象上(对由基类继承下来的数据成员)操作

     

    5.有人定义一个教师类派生一个学生类。他认为“姓名”和“性别”是教师、学生共有的属性,声明为public,“职称”和“工资”是教师特有的,声明为private。在学生类中定义特有的属性“班级”和“成绩”。所以有:

    class teacher

    {  public:

          char name[20];  char sex;

          //…

       private:

          char title[20]; doublesalary;

    };

    class student : public teacher

    {  //…

       private:

          char grade[20]; int score;

    };

    你认为这样定义合适吗?请给出你认为合理的类结构定义。

    【解答】

    不合适,这样导致数据冗余。合理的结构是提取它们共有的数据和操作定义一个基类,然后分别定义teacher和student作为派生类。

    class person

    { protected:

    charname[20];  char sex;

           //……      

    };

    class teacher :public teache

    { //……

      private:

           char title[20]; double salary;

    };

    class student :public teacher

    { //……

    private :

    char grade[20] ;int score;

    };

     

    6.在第6章的例6-21中,定义Student类包含了Date类成员。可以用继承方式把Student类定义为Date类的派生类吗?如何改写程序?请你试一试。

    【解答】

    可以用继承方式改写。程序略。

     

    7.“虚基类”是通过什么方式定义的?如果类A有派生类B、C,类A是类B虚基类,那么它也一定是类C的虚基类吗?为什么?

    【解答】

    虚基类是在声明派生类时,指定继承方式时声明的,声明虚基类的一般形式为:

    class 派生类名 : virtual 继承方式 基类名

    若类A是类B和类C的虚基类,但不一定是类D的虚基类,原因在于“虚基类”中的“虚”不是基类本身的性质。而是派生类在继承过程中的特性。关键字virtual只是说明该派生类把基类当作虚基类继承,不能说明基类其他派生类继承基类的方式

     

    8.在具有虚继承的类体系中,建立派生类对象时,以什么顺序调用构造函数?请用简单程序验证你的分析。

    【解答】

    在具有虚继承的类体系中,建立派生类对象时先调用间接基类构造函数,再按照派生类定义时各个直接基类继承的顺序调用直接基类的构造函数,最后再对派生类对象自身构造函数。

    另外,C++为了保证虚基类构造函数只被建立对象的类执行一次,规定在创建对象的派生类构造函数中只调用虚基类的构造函数和进行(执行)自身的初始化。参数表中的其他调用被忽略,即直接基类的构造函数只调用系统自带的版本,或调用自定义版本但不对虚基类数据成员初始化。

    程序略。

     

    二、程序设计

    1.假设某销售公司有一般员工、销售员工和销售经理。月工资的计算办法是:

    一般员工月薪=基本工资;

    销售员工月薪=基本工资+销售额*提成率;

    销售经理月薪=基本工资+职务工资+销售额*提成率。

    编写程序,定义一个表示一般员工的基类Employee,它包含三个表示员工基本信息的数据成员:编号number、姓名name和基本工资basicSalary。

    由Employee类派生销售员工Salesman类,Salesman类包含两个新数据成员:销售额sales和静态数据成员提成比例commrate。

    再由Salesman类派生表示销售经理的Salesmanager类。Salesmanager类包含新数据成员:岗位工资jobSalary。

    为这些类定义初始化数据的构造函数,以及输入数据input、计算工资pay和输出工资条print的成员函数。

    设公司员工的基本工资是2000元,销售经理的岗位工资是3000元,提成率=5/1000。在main函数中,输入若干个不同类型的员工信息测试你的类结构。

    【解答】

    #include<iostream>

    using namespacestd;

    class Employee

    {

        public:

          Employee( char Snumber[]="\0", char Sname[]="\0",double bSalary=2000 )

           {

                     strcpy_s(number,Snumber);

                     strcpy_s(name,Sname);

                     basicSalary=bSalary;

              }

              void input()

              {

                     cout << "编号:" ;   cin>> number;

                     cout <<"姓名:" ;    cin>> name;

              }

              void print()

              {

               cout<<"员工 :"<<name<<"\t\t编号:"<<number<<"\t\t本月工资:"<<basicSalary<<endl;

              }

        protected:

          char number[5];

          char name[10];

          double basicSalary;

    };

     

    class Salesman:public Employee

    {

       public:

              Salesman(int sal=0)

              { sales=sal; }

              void input()

              {

                     Employee::input();

                     cout<<"本月个人销售额:";

                     cin>>sales;

              }

              void pay()

              {

                     salary =basicSalary+sales*commrate;

              }

              void print()

              {

                     pay();

                     cout<<"销售员 :"<<name<<"\t\t编号:"<<number<<"\t\t本月工资:"<<salary<<endl;             }

       protected:

              static double commrate;

              int sales;

              double salary;

    };

    double Salesman:: commrate=0.005;

     

    classSalesmanager : public Salesman

    {

        public:

              Salesmanager(double jSalary=3000)

              {

       jobSalary = jSalary;

              }

              void input()

              {

                     Employee::input();

                     cout<<"本月部门销售额:";

                     cin>>sales;

              }

          voidpay()

              {

                     salary = jobSalary +sales*commrate; 

              }

              void print()

           {

                     pay();

                     cout<<"销售经理 :"<<name<<"\t\t编号:"<<number<<"\t\t本月工资:"<<salary<<endl;         }

    private:

          double jobSalary;

    };

    int main()

    {

       cout<<"基本员工\n";

       Employee emp1;

       emp1.input();

       emp1.print();

     

    cout<<“销售员\n”;

    Salesman emp2;

    emp2.input();

    emp2.print();

    cout<<“销售经理\n”;

    Salesmanager emp3;

    emp3.input();

    emp3.print();

    }

    2.试写出你所能想到的所有形状(包括二维的和三维的),生成一个形状层次类体系。生成的类体系以Shape作为基类,并由此派生出TwoDimShape类和ThreeDimShape类。它们的派生类是不同的形状类。定义类体系中的每个类,并用main函数进行测试。

    【解答】

    略。

    3.为第7章综合练习的程序设计第1题和第2题中的Integer类和Real类定义一个派生类IntReal:

    class IntReal : public Integer, public Real;

    使其可以进行+、-、*、/、= 的左、右操作数类型不同的相容运算,并符合原有运算类型转换的语义规则。

    【解答】

    略。

    4.使用Integer类,定义派生类Vector类:

    class Integer

    { //…

    protected :

      int n;
    

    };

    class Vector:public Integer

    { //…

    protected :

      int *v;
    

    };

    其中,数据成员v用于建立向量,n为向量长度。要求:类的成员函数可以实现向量的基本算术运算。

    【解答】

    略。

    5.用包含方式改写第4题中的Vector类,使其实现相同的功能。

    class Vector

    { //…

    protected :

      Integer *v;
    
      Integersize;
    

    };

    【解答】

    略。

    6.使用第5题定义的Vector类,定义它的派生类Matrix,实现矩阵的基本算术运算。

    【解答】

    略。

    7.用包含方式改写第6题的Matrix类,使其实现相同的功能。

    【解答】

    略。

    8.设计快捷店会员的简单管理程序。基本要求如下:

    (1)定义人民币RMB类,实现人民币的基本运算和显示。

    (2)定义会员member类,表示会员的基本信息,包括:编号(按建立会员的顺序自动生成),姓名,密码,电话。提供输入、输出信息等功能。

    (3)由RMB类和member类共同派生一个会员卡memberCar类,提供新建会员、充值、消费和查询余额等功能。

    (4)main函数定义一个memberCar类数组或链表,保存会员卡,模拟一个快捷店的会员卡管理功能,主要包括:

    ① 新建会员;

    ② 已有会员充值;

    ③ 已有会员消费(凭密码,不能透支);

    ④ 输出快捷店当前会员数,营业额(收、支情况)。

    【解答】

    略。

    推荐阅读
    全部习题章节:
    C++课本的练习题及答案(第四章)
    C++课本的练习题及答案(第五章)
    C++课本的练习题及答案(第六章)
    C++课本的练习题及答案(第七章)
    C++课本的练习题及答案(第八章)
    展开全文
  • C++课本的练习题及答案(第七章)

    千次阅读 2020-04-07 17:30:26
    } intmain() { s obj1( "Visual" ), obj2( "C++" ), obj3(" language"); obj3 = (obj1.connect(obj2)).connect(obj3); //调用字符串连接函数 cout【解答】 #include #include using namespace std; class s { ...
  • 由于之前下载了很多课本的程序,但由于电脑故障,所有的资料全部丢失,在此,我免费分享。希望没有资源分的朋友可以来我这里。也希望,没有资源分的我能够再次下载。
  • 本人对朱立华、俞琼主编,郭剑 、朱建副主编的面对对象程序设计及c++(第2版)的学习结束,接下来是练习代码篇章 内容中如有错误请评论或者加Q977043768告知 谢谢大家的指导哦,一起努力吧
  • 为什么第二个输出不是-50呢?
  • 谭浩强c++课本例题

    2010-07-22 16:49:40
    谭浩强c++课后习题答案,这也是我在我同学买的书中找到的,不过在学习过程中,好像发现了点错误
  • //2.1简单的例子 #include  using namespace std; class Time { public: int hour; int minute; int sec; }; int main() { Time t1; cin>>t1.hour; cin>>t1.minute; cin>>t1.sec;...
  • 本书详细介绍了C++面向对象程序设计方法,书中例子简单,逻辑清晰,逐层深入,是一本不错的C++学习手册。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,905
精华内容 4,362
关键字:

c++课本

c++ 订阅