第七章 结构与联合

7.1 结构的定义(P195)

  struct Person {    //个人资料、结构体

    char name[10];   //数据成员 姓名

    bool sex;        //性别

    int age;         //年龄

    float pay;       //工资

   };

7.2.1 用结构类型名定义变量

  格式举例(P198)

   struct Arith {

     char op;

     int a,b;

   };

  设整型变量

    int xx=40;

  可定义结构变量如下:

    Arith x,y;  //x,y为Arith型结构变量

    Arith z1={'+',10,xx},z2={'*',60},z3=z1;

  动态变量

    Arith *p=new Arith;

  动态数组

    Arith *p=new Arith[n];

7.2.2 定义结构类型的同时定义变量(P200)

   struct AAA {

     char s[20];

     int top;

   }a1={"MicroSoft",0},a2=a1,*ap;

7.2.3 定义无名结构类型的同时定义变量(P200)

  struct BBB {

   char name[10];

   struct {         //无名结构

    int yy,mm,dd;   //无名结构的成员

   }birth;         //无名结构变量

   }bx={"xxk",{55,3,27}};

7.3 结构成员的访问操作

  结构变量运算符(P201)

 结构变量用(=)、(.)、(->)运算符访问结构的成员。

  赋值运算符(=)、直接成员运算符(.)、间接成员运算符(->)。

  例如:x.a;           //x中的成员变量a

        vec[5].name;   //vec[5]元素的成员变量name

  例7.1 人员记录的结构

  struct Person {    //个人资料、结构体

    char name[10];   //数据成员 姓名

    bool isMale;     //性别

    int age;         //年龄

    fooat pay;       //工资

   };

  设计程序用结构数组存储人员记录

  14: Peson a[MaxPersons];

  20: Peson x;

  22: cin>>x.name;

  38: cout<<a[i].name;

7.4 结构与函数

  结构类型作为函数的参数类型和返回值。(P211)

  例7.5 按学号查找学生记录的结构数组。

    s[i].num:s数组元素i结构成员(学号)

    x.num:x结构成员(给定学号)

  4:stuct Student{...};   //学号、姓名、成绩

  6:int search(Student s[ ],int n,Student x)

            //s数组,元素个数,给定x结构(学号、姓名、成绩)

  10:if(strcmp(s[i].num,x.num)= =0)

  11:return i

  15:void main( )

  17:Student a[5]={{"ch231","王广敏",69},...};

  21:Student x={"ch231"};

  22:int k=search(a,5,x);

  23:if(k>=0)

  24:  cout<<a[k].num;

 

7.5 结构与链表(P215)

表头
指针f
表头结点
无前驱结点
-> 前驱结点 -> 结点 -> 后继结点 -> 最后结点
无后继结点
/
值域
data
指针域
next
值域
data
指针域
next
值域
data
指针域
next
值域
data
指针域
next
值域
data
48 指下一
结点
56 指下一
结点
72 指下一
结点
80 指下一
结点
83

 链表:通过指针域把结点依次链接起来。

7.6 结构与操作符重载

  1.操作符重载(P220)

    系统定义了基本数据类型的操作符,例如:整型的+,>>,<<。

    重载函数自定义的数据类型的操作符,例如:分数的+,>>,<<。

例7.9 用常规函数对分数相加。

  1.分数相加 n1/d1+n2/d2=(n1*d2+n2*d1)/d1*d2

  2.辗转相除法求最大公约数,例如:求450,105的公约数

    r=m%n=450%105=30

    r1=n%r=105%30=15  (最大公约数)

    r2=r%r1=30%15=0

  3.求最大公约数的程序段分析

分数 nume/deno x 赋值 辗转相除
分子 nume x.nume m=x.nume m=n
分母 deno x.deno n=x.deno n=r 公约数
余数   r m%n n%r r=0

  4:struct Fraction{  //分数类型

  5: int nume;        //分子

  6: int deno;        //分母

  9:void FracSimp(Fraction &x)

 12: int m,n,r;

 13: m=x.nume;n=x.deno;

 14: r=m%n;

 15: while(r!=0){

 17: m=n;n=r;

 18: r=m%n;

 20: 化简x 除n

 34: Fraction FracAdd(const Fraction &a,const Fraction &b){

 36: Fraction c;

 37: c.nume=a.nume*b.deno+b.nume*a.deno; //分子

 38: c.deno=a.deno*b.deno;  //分母

 39:FracSimp(c);

 69: void main( ){

 71: Fraction a,b,c;

 74: c=FracAdd(a,b);

例7.10 用重载操作符函数对分数相加(P224)

 13: Fraction operator +(const Fraction &a,const Fraction &b){

 15: Fraction c;

 16: c.nume=a.nume*b.deno+b.nume*a.deno; //分子

 17: c.deno=a.deno*b.deno;  //分母

 18:FracSimp(c);

 64: void main( ){

 66: Fraction a,b,c;

 68: c=a+b;

7.7 联合

7.7.1 联合的定义和访问

  1.结构定义(P231)

    struct stype{

      char ch;

      int gr;

      int * pt;

      double db;

    };

    结构变量:stype x;

    结构对象x的存储空间:1+4+4+8=17

    同一时刻可访问结构中的所有成员,结构成员可顺序初始化。

  2.联合定义(P231)

    union utype{

      char ch;

      int gr;

      int * pt;

      double db;

    };

    联合变量:utype y;

    联合对象y的存储空间:max(1+4+4+8)=8

    同一时刻只可访问联合中的一个成员,

    联合成员只可初始化第一个数据成员。

  3.匿名联合(P232)

    在联合类型定义中,不给类型名和变量,

    联合中的成员可直接使用。

例如:struct ABC {

        char ch;

        union {        //不给类型名

          int ia;      //匿名联合中的数据成员

          float fa; //可作为结构ABC的成员直接使用

        };               //不给变量

        ABC * pa;

      } x,*px=&x;

7.7.2 使用联合举例

例7.12 用数组保存职工记录(P232)

类别

(kind)

职级

(匿名联合类型union)

1干部 局级(juji)
……
科员(keyuan)
2教师 教授(jiaoshou)
副教授(fujiaoshou)
……
3工人 1级
……
8级

 

   struct Workers {  //职工记录类型

     char num[6];    //编号:01001--12020

     char name[12];  //姓名

     char sex;       //性别:m,f

     short kind;     //类别:1,2,3

     union {         //职级

       char cadre[8];     //干部职级:科员(keyuan)

       char teacher[12];  //教师职级:副教授(fujiaoshou)

       short worker;      //工人职级:1~8级

     };

   };

   //向结构数组a中输入n个职工记录(P234)

   void Input(Workers a[ ],int n) {

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

      cin>>a[i].num>>a[i].name>>a[i].sex;

      cin>>a[i].kind;

      switch(a[i].kind){  //根据类别输入的职级

       case 1:

       cin>>a[i].cadre;

       break;

第八章 类与对象

8.1 类的定义

8.1.1 类的定义格式(P245)

  1.数据类型

基本数据类型 整型、字符型、枚举型、实型、符号常量、常值变量
数组 一维数组、二维数组、字符数组、字符串
其它类型 指针、结构、联合、类

  2.结构有数据成员,类增加了函数成员。

数据类型 属性 行为(操作) 定义变量
结构struct 数据成员公有public 结构变量
类class 数据成员私有private 成员函数 对象

8.1.2 定义格式举例(P245)

  1. struct CA{   //结构

      int a;      //数据成员公有

      int b;

     }ax;         //定义变量ax

  2. class CB{   //类

      int a;      //数据成员私有

      int b;

     }bx;         //定义对象bx

  3. class CC{   //类

      int a;      //数据成员私有

      public:     //函数成员公有

        void Init(int aa){a=aa};

        int GetData( ){return a;}

      }cx;         //定义对象cx

    

  对象用(.)运算符访问类的成员。

     赋值:cx.Init(x)--Init(int aa)--a=aa;

     取值:cx.GetDAta--a--cx.a;

  4. class CD{   //类

      char * a;

      int b;      //数据成员私有

      public:     //函数成员公有

        void Init(char *aa,int bb){ //初始化 a,b

          a=new char[strlen(aa)+1];

          strcpy(a,aa);

          b=bb;

         }

        char * Geta( ){return a;}   //取数 a,b

        int Getb( ){return b;}

        void Output( ){cout<<a<<' '<<b<<endl;} //显示 a,b

       }dx;         //定义对象dx

  5.取最大数(P247)

三个数 a=3 b=5 c=7
取最大数 d=5 c=7
取最大数 e=7

    class CE{

      private:

         int a,b;

         int getmax( ){return(a>b ? a:b);}

      public:

         int c;

         void SetValue(int x1,int x2,int x3){ //置数

          a=x1;

          b=x2;

          c=x3;

         }

         int GetMax( ){

          int d=getmax( );

          return (d>c? d:c);

         }

     } ex,*ep=&ex;

8.1.3 类的定义与使用说明(P248)

 1.对象操作(访问类成员):外部访问—公有成员—私有成员。

 2.类成员能访问类中的其它成员。

 3.this指针:类成员函数中有所属类的指针参数。

   this:指向类对象的指针,* this:类对象本身。

  1.成员函数放在类外定义(P249)

    class CE{

      private:

         int a,b;

         int getmax( );  //成员函数声明

      public:

         int c;

         void SetValue(int x1,int x2,int x3);

         int GetMax( );

     } ex,*ep=&ex;

     int CE::getmax( ){return(a>b? a:b);}

      用(::)运算符访问类的成员。

   类CE的(:: 类区分符)成员函数getmax( )放在类外定义

  2.类定义:含成员函数原形,存放在头函数.h中;(P250)

     类实现:成员函数在类外定义,存放在程序文件.cpp中

             用户只管成员函数调用格式和功能,不用管其实现。

例8.1 用类来实现分数的定义和有关运算(P251)

  3: class Fraction{  //分数类

  4: int nume;        //分子

  5: int deno;        //分母

  6: public:

 7:void FracSimp( ){ //把*this化简为最简分数

  8: int m,n,r;

 9: m=x.nume;n=x.deno;

 10: r=m%n;

 11: while(r!=0){

 12: m=n;n=r;

 13: r=m%n;

 36: Fraction operator +(Fraction &x){ 

    //返回两个分数*this(nume/deno)和x(x.nume/x.deno)之和

 39: Fraction c;

 40: c.nume=a.nume*b.deno+b.nume*a.deno; //分子

 41: c.deno=a.deno*b.deno;  //分母

 42:c.FracSimp( );

 71: void main( ){

 73: Fraction a,b,c;  //类对象a,b,c

74: a.InitFraction(7,12); //用类对象a的成员函数赋初值

77: c=a+b;

8.2 构造函数

  1.构造函数(P254)

    与类同名,为类对象中的数据成员赋初值,公用成员。

  例8.2 数组大小可在定义Array的对象时指定,

        数组空间由调用程序提供。

    4:class Array{ //定义数组类

        int * a;   //定义指向整型数组的指针

        int n;     //定义数组长度

    7:public:

       Array( ) {a=NULL;n=0;}   //无参构造函数,构造空数组

    10:Array(int aa[ ],int len) {n=len;a=aa;}

       //有参构造函数,构造指向aa数组

8.2.2 拷贝构造函数

  1.拷贝构造函数(P259)

    构造函数的参数为同类对象引用。通过调用拷贝构造函数,

    可定义与已有对象相同的对象。

  例如:class A { }a;

        A b(a); //或 A b=a;

  调用A的拷贝构造函数,以对象a作为初值初始化对象b。

  2. 系统默认的拷贝构造函数(P259)

  例如:X(X &x){  //引用形参x  类X,对象x

          * this=x; //把x对象空间的内容拷贝到当前对象空间

        }

8.2.3 赋值操作符的重载(P261)

  

8.3 析构函数(P262)

  1. 析构函数与类同名,函数名前加(~)号。

  2. 构造函数是对象生成时调用。析构函数是对象撤消时调用,

     用来删除对象中由指针成员指向的动态分配的存储空间。

     例如:~Array( ) {delet [ ]a; }

  3. 类X的默认析构函数 ~X( ) { }

8.4 友元函数和友元类(P265)

  1. 把类A外的函数B或类B说明为友元函数和友元类,

     函数B或类B可以直接访问类A的私有成员。

8.5 类的继承(P272)

  1.基类:被继承类、父类,例如:建筑物。

  2.派生类:继承类、子类,继承父类的数据成员和函数成员,

    例如:房屋、桥梁。

8.5.1 派生类定义的格式(P272)

  1. 定义派生类的格式:

        class 派生类名:基类表{成员表};

    继承基类操作符:(:)

  例如:class   PXL : JLB  {private: ; public: ;}

  2. 派生类包括(P273)

     继承基类的私有成员、保护成员、公有成员;

     新定义的私有成员、保护成员、公有成员。

8.8 模板类(P293)

  1.模板函数:带类型参数的函数。

    模板类:带类型参数的类。

    模板结构:带类型参数的结构。

例:用实参类型int代替模板类TT

  #include<iostream.h>

    template<class TT>  //模板类TT,实际类型由实参决定

    class FF{

          TT a1,a2,a3;  //TT当已定义的类型

    public:

          FF(TT b1,TT b2,TT b3){

             a1=b1;a2=b2;a3=b3;

    }

    TT sum( ){return a1+a2+a3;}

    };

    void main( ){

         FF<int>x(2,3,4),y(5,7,9); 用实参类int代替模板类TT

         cout<<x.Sum( )<<' '<<y.Sum( )<<endl;  //输出:9 21

 

第九章 C++流

9.1 C++流的概念

9.1.1 C++流的体系结构(P307)

  1. 数据的输入和输出(I/O)包括:

     标准输入和输出(标准I/O):键盘和显示器;

     文件输入和输出(文件I/O):磁盘;

     字符串输入和输出(串I/O):内存字符串存储空间。

  2. I/O类的继承关系

     输入(i)、输出(o)、文件(f)、

     字符串(string)、流(stream)、基类(base)。

基类
ios
输入流
istream
文件流基类
fstreambase
字符串流基类
strstreambase
输出流
ostream
输入文件流
ifstream
输出文件流
ofstream
输入字符串流
istrstream
输出字符串流
ostrstream
输入输出流
iostream
文件流
fstream
字符串流
strstream
输入输出流
iostream

  3. I/O 类库:iostream.h, fstream.h, strstrea.h

9.1.2 预定义流对象(P309)

  cin标准输入,cout标准输出

9.1.3 提取操作符>>和插入操作符<<

   键盘 cin>>内存>>cout 显示器

   从键盘提取数据流到内存,把内存数据流插入到显示器。

9.2.2 输入输出的数制状态控制

  1.设置数制状态操纵符(P313)

    dec十进制, oct八进制, 十六进制hex。

9.2.3 输入输出的宽度控制(P314)

  setw(in n)

9.2.8 填充字符(P316)

  setfill(char c)

9.2.11 插入换行符(P316)

  endl  ('\n')

9.2.12 插入字符串结束符(P317)

  ends  ('\0')

9.2.15  跳过前导空白字符(P317)

  ws

9.3 文件操作(P319)

名称 形式 特点
文本文件
数值2577
字符文件(ASCII码)
4个字节 32 35 37 37H
二进制  0011 0010B
有格式适合显示打印,
可读字符
二进制文件
数值2577
字节文件(二进制数)
短整型,2个字节
0000 1010 0001 0001B
0A 11H
无格式适合数据处理,
速度快
内存文件 字节文件(二进制数) 文本文件数值2577
要经ASCII码转换成
内存的二进制数

9.3.3 文件流状态判定(P323)

  is_open 流对象与打开文件联系?

  dood( ); 操作成功;

  fail( ); 操作失败;

  bad( ); 非法操作;

  eof( ); 文件尾;

  9.4 字符串流(P337)

  1. 字符串流类定义在strstrea.h中,

     包括:输入字符串流(istrstream),

     输出字符串流类(ostrstream),输入输出字符串流类(strstream)

  2. 文件有文件结束符标志,

     字符串流对应的字符数组由用户规定结束符。

 

考试复习

1.数据类型

基本数据类型 整型、字符型、枚举型、实型、符号常量、常值变量
数组 一维数组、二维数组、字符数组、字符串
其它类型 指针、结构、联合、类

2.操作符

操作符 举例
一元操作符:取正(+)、取负(-) +3,-4 27
单目操作符:增1(+ +)减1(- -) i++ 29
二元操作符:加(+)、减(-) k+=3 29
三目操作符:(?:) y=x>10?33:3 40
逗号操作符:(,) x=(i++,j); 44
取地址操作符:(&) p=&k; 148
间接访问操作符:(*) y=* px 148
访问结构成员操作符:(.) x.a 201
访问对象成员操作符:(.) cx.Init(x) 247
访问类成员操作符:(::) int CE::getmax( ) 249
继承基类操作符:(:) class Y:X{ } 272
提取操作符:(>>) cin>>x 311
插入操作符:(<<) cout<<x 311

二、填空题

 2. 'A'的ASCII码65

    ch=14*5+2;

    ch=72-65;

    距离‘A’7个字符是‘H’。

 7. * p=25;

    *(p+1)=46;

    (* P)++; * p的值25+1=26

    而*(p++)的值是46

 8. 二维数组a[M][N](P88,P95,P159)

    按先行(M)后列(N)存储数据

    设 int a[3][5]

  0列 1列 2列 3列 4列
0行 a[0][0] a[0][1] a[0][2] a[0][3] a[0][4]
1行 a[1][0] a[1][1] a[1][2] a[1][3] a[1][4]
2行 a[2][0] a[2][1] a[2][2] a[2][3] a[2][4]

    a[i]的地址为 a+(i*N)*sizeof(a[0][0]),i行N列a数组元素长度

              或 a+i*sizeof(a[i]),i行a[i]一维数组长度

    a[2]的地址为 &a[0][0]+2*5*4

三、阅读程序

 1. 求偶数和

  if(s>50)break;

    if(i%2= =0)s+=i;  求偶数和

    i:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

    s:2+4+6+8+10+12+14

 2. 统计字符'a'‘b'

    char a[ ]="abcd abc abfg acd";  //字符中不能空格

    int i1=0,i2=0,i=0;

    while(a[i]){           //a[i]非空

              if(a[i]= ='a')i1++; //统计'a'

              if(a[i]= ='b')i2++; //统计'b'

     i++;

    }

3. 输出三个数字换一行

   int a[9]={2,4,6,8,10,12,14,16,18};

   if(i+1)%3= =0)cout<<endl;

4. 数字交换

   void LE(int * a,int * b){

   int x=* a;

   * a=* b;* b=x;

   }

   viod main( ){

   int x=10,y=25;

   LE(&X,&Y);  //变量地址通过引用参数传递(P176)

   }

5. 构造函数(P255)

   class A{

       int a,b;       //4.私有成员a

   public:

        A( ){a=b=0;}  //无参构造函数

        A(int aa,int bb){  //有参构造函数,2.形参

        a=aa;b=bb;         //3.赋值给私有成员a

        cout<<a<<' '<<b<<endl;  //5.输出

        }

    };

   void main( ){

        A x ,y(2,3),z(4,5);   //1.实参

   }

四、阅读函数

1.计算序列数的和

  double p=1,s=1;

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

  p* =x;   //等比序列

  s+=p/(i+1);   //等差序列

  }

i 1 2 ....... n
p/(i+1) 1*x/(1+1) x*x/(2+1)    
s 1+(1/2)x 1+(1/2)x+(1/3)x*x    

2. 求键入数的平均值

    cin>>x;

   while(x!=-1){  //x=-1结束循环

  n++;y+=x; //求x的和存入y,n记录x的个数

  cin>>x;

  }

   if(n= =0)return y;

   else

   return y/n; //求键入数的平均值

  }

3. 升序排列数组的元素

   void WA(int a[ ],int n){

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

         int k=i;

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

         if(a[j]<a[k])k=j;   //升序排列数组的元素

        int x=a[i];a[i]=a[k];a[k]=x;

      }

     }

3 大数
a[i]
  小数
a[i+1]
a[n-1]
x 4 1   1  
5 大数
a[k]
2 小数
a[j]
 

4. 读字符串并显示