C++入门经典习题集【二】

第十章:程序文件和预处理指令*************************
    (1):程序中的每个实体都只能有一个定义
    (2):名称可以有内部链接属性,即该名称可以在一个转换单元中访问,名称也可以有外部链接属性,即名称可以在任何单元中访问,名称还可以没有链接属性,即名称只能在定义它的块中访问
    (3):头文件也可以包含源文件需要的定义和声明,头文件还可以包含模板和类型定义,枚举,常量,函数声明,内联函数定义,以及指定的命名空间,按照约定,头文件使用扩展名.h
    (4):把函数定义和全局变量放在源文件中,C++源文件的扩展名是.cpp
    (5):通过#include指令可以把头文件的内容插入到.cpp文件中
    (6):Cpp文件是转换单元的基础,编辑器会处理转换单元,以生成对象文件
    (7):命名空间定义一个作用域----在这个作用域内声明的所有名称都附加了命名空间的名称,不在显示命名空间作用域内声明的名称就在全局命名空间中
    (8):一个命名空间可以由几个独立的同名命名空间声明组成
    (9):在不同的命名空间中声明的相同名称是不同的
    (11):为了在命名空间的外部引用在命名空间中声明的标识符,需要指定命名空间的名称和标识符,两者之间用作用域解析运算符::分隔开
    (12):在某个命名空间声明的名称,在这个命名空间中使用时,可以不加限定符
    (13):预处理器执行预处理指令,在编译代码之前传送转换单元中的源代码,处理完所有的指令后,转换单元就只包含C++代码,没有预处理指令了
    (14):可以使用条件预处理指令,确保头文件的内容在一转换单元中没有重复
    (15):可以使用条件预处理指令,控制是否在程序中包含跟踪或其他诊断调试代码
    (16):assert()宏允许在执行过程中测试逻辑条件,如果逻辑条件为假,就输出一个消息,并终止程序
练习题
     1:有一个程序调用用了两个函数print_this(const string& s) 和 print_that(const string& s),这两个函数又调用了第三个函数print(const string& s),输出传送给它的字符串
        在4个源文件中实现这3个函数和main()函数,并提供3个头文件,分别包含print_this(),print_that() 和 print的原型确保头文件只包含一次,main.cpp包含的#include语句最少
     2:修改上题的程序,使print()函数使用一个全局整数变量来计算它被调用的次数,在main()调用print_this() 和print_that()输出这个变量的值
     3:在print.h头文件中,删除print()的已有原型,再创建两个命名空间print1和print2,每个命名空间都包含一个函数print(const string& s),这些函数都具有相同的函数签名,区分它们的唯一方式是命名空间的名称,在print.pp文件中实现这两个函数,输出命名空间的名称和字符串
       现在让print_this()调用在命名空间print1中声明的函数.让print_that()调用在命名空间print2中声明的函数,运行程序,验证是否调用了正确的函数
       提示:从上面可以看出,在print_this()和print_that()中调用print()函数有三种不同的方式,即三种不同语法形式
     4:修改main()例程,只有定义了预处理符号DO_THIS,才能调用print_this(),否则就调用print_that()
       修改代码,定义一个宏PRINT(),定义了DO_THIS后就让PRINT(abc)----注意没有引号--调用print_this("abc"),否则就调用print_that("abc")
 
第十一章:创建自己的数据类型*************************
    (1):结构类型是程序中的一个新数据类型
    (2):结构对象是带有成员的对象,这些成员在默认情况下可以公开访问,结构可以有数据成员和函数成员
    (3):可以使用对象名和句点分隔的成员来引用结构对象的成员,其中句点称为成员选择运算符
    (4):联合一种数据类型,它的对象可以使用同一个内存块在不同的时刻存储几种不同变量的值(也许类型也不同)
    (5):在声明联合对象时,只能为联合的第一个成员提供对应类型的初始值
    (6):结构的数据成员可以是任意类型,包括其他结构,但数据成员的类型不能与包含它的结构的类型相同
    (7):聚合是创建时可以用花括号中的初始值列表来初始化的实体
    (8):可以在自由存储区动态创建对象,但必须在指针中存储这些对象的地址
    (9):可以使用间接成员选择运算符访问对象的成员
练习题
     1:编写一个简单的货币转换程序,为此,需要在货币对象中关联两个实体:货币类型和把货币转换为美元的转换因子,设计一个结构来表示货币对象,编写一个程序,让用户从一个列表中选择转换的货币类型,在任意两种货币中转换,用户应输入值,并获得转换后的结果,如果输入一个负值,就退出程序
     2:(较难)提供一种方式,让用在运行程序时添加新的货币类型
     3:实现本章中"更复杂的结构"一节中描述的SharedData结构,扩展改结构(及相关的枚举类型),以及存储4种类型的指针,测试一下,看看是能否存储变量的指针
     4:编写一个函数,它接受ShareData对象数组,并以[array_element]type = value形式输出每个元素的值,例如:
       [0] double = 37.2
              [1] float *= 2.5
       在合适的main()函数中测试这个函数
第十二章:类*********************************
    (1):类提供了定义自己的数据类型的一种方式,类可以反映某个问题所需要的对象类型
    (2):类可以包含数据成员和成员函数,类的成员函数总是可以自由访问该类中的数据成员
    (3):类的对象用构造函数来创建和初始化,在声明对象时会自动调用构造函数,构造函数可以重载,以提供初始化对象的不同方式
    (4):类的成员可以指定为public,此时它们可以由程序中的任何函数自由访问,另外类的成员还可以指定为private,此时它们只能被类的成员函数和友元函数访问
    (5):类的数据成员可以定义为static,无论类中创建了多少个对象,类中的静态数据成员都只有一个
    (6):可以在类对象的成员函数中访问类的静态数据成员,它们不是类对象的一部份,类对象的大小不包括静态数据成员的字节数
    (7):即使没有创建类的对象,类的静态函数成员也存在,并可以调用
    (8):类的每个非静态函数成员上都包含this指针,它指向调用该函数的当前对象
    (9):类的静态函数成员不包含this指针
    (0):类中声明为const的成员函数不能修改类对象的数据成员,除非数据成员声明为mutable
    (11):把类对象的引用用作函数调用的参数,可以避免产生把复杂对象传送给函数的系统开销
    (12):副本构造函数可以用类中已有的对象初始化同一个类中的新对象,如果没有定义类的构造函数,编辑器就会生成默认的副本构造函数
练习题
     1:创建一个简单的类Integer,它只有一个私有数据成员int,为这个类提供构造函数,并使用它们输出创建对象的消息,提供类的成员函数,获取和设置数据成员,并输出该值,编写一个测试程序,创建和操作至少3个Integer对象,验证不能直接给数据成员赋值
       在测试程序中获取,设置和输出每个对象的数据成员值,以验证这些函数
     2:修改上一题类Integer的构造函数,把数据成员初始化为初始化列表中的0,并实现类的副本构造函数
       编写一个成员函数,比较当前对象和作为参数传送的Integer对象,如果当前对象小于参数,该函数就返回-1,如果他们相等函数就返回0,如果当前对象大于参数,函数就返回+1,测试该函数的两个版本:第一个版本的参数按值传送,第二个版本的参数按引用传送,在调用该函数时,构造函数会输出什么结果?解释出现这种结果的原因
       类中的函数不能是重载函数,为什么?
     3:为类Integer实现成员函数add(), subtract(), multiply(),对当前对象和Integer的参数值进行加,减和乘法运算,在类中用main()演示这些函数的操作,main()创建了几个Integer对象,它们分别包含值4,5,6,7,8,在使用些对象计算4*5的三次方,加6*5的二次方,再加7*5,再加8的值,实现这些函数,使计算和结果的输出在一个语句中完成
     4:修改题2的解决方法,把compare()函数实现为Integer的一个友元
 
第十三章:类的操作******************************
    (1):只能通过构造函数的初始化列表来初始化类的引用成员,引用不能用赋值语句来初始化
    (2):只要给函数按值传递对象,就会调用副本构造函数,其结果是传送给类的副本构造函数的参数必须是一个引用
    (3):如果在类的成员函数中动态分配内存,就中要执行析构函数来释放内存,实现副本构造函数和副本赋值运算符
    (4):把类的所有成员都声明为private,就可以限制对类的访问,此时,只有友元类可以创建该类类型的对象
    (5):嵌套类是把自己的定义放在另一个类定义的内部,嵌套类的名称在包含类的作用域内,为了在包含类的外部引用嵌套的类类型,类型名称必要用包含类的名称来限定
    (6):如果嵌套类的定义防在包含类的私有部分,嵌套类类型的对象就不能在包含类的外部创建
    
练习题
     1:编写一个类Sequence,在自由存储区中按照升序存储整数数值的递增序列,序列的长度和起始值在构造函数中提供,确保该序列至少有两个值,默认有10个值,从0开始(0,1,2,3,4,5,6,7,8,9),需要足够的内存空间来存储该序列,再用要求的值来填充内存.
       提供show()函数列出该序列,释放分配给该序列的内存,(注意:确保释放所有的内存),创建并输出5个随机长度(长度有限)的序列和一个默认的序列,来演示这类的操作
     2:编写一个函数来比较这两个序列,如果Sequence对象有不同的长度,它们就是不同的,如果Sequence对象有相同的长度,但是对应的值不同,它们也是不同的,只有Sequence对象有相同的长度,且对应的值也相同,它们才是相同的,把这个函数编写为Sequence类的一个成员
     3:重新编写比较函数,把它作为Sequence类的一个友元,如何改变参数和调用该函数的方式?最好使用什么技术
     4a:标准库包含一个string类,但创建自己的string类可以弄明白设计和编写sC++类的许多问题,使用基本的char数据类型编写一个string类,看看它如何隐藏使用C样式字符串的复杂性
       为MyString类创建一个头文件,把它放在自己的命名空间中,给这个类提供两个私有数据成员,整型长度和char*,char*指向对象所管理的字符串,为什么要把长度作为该类的一个数据成员存储
          4b:创建一个类的实现文件(.CPP),并提供构造函数,从下面的数据类型中构建MyString对象:
        一个字符串字面量,(例如:const char*类型),以便编写MyString s1("hello")
        一个重复多次的字符,默认的重复次数应是1,使用这个构造函数的例子如MyString s2('c',5)
                一个整数值,这样MyString s3(10)就存储了字符串"10"
        这些构造函数是显式的还是隐式的?构造函数在需要时应提供错误处理
          4c:构造函数为存储字符串而分配内存,提供一个析构函数,在删除对象时正确的释放内存
          4d:编写一个类的副本构造函数,以便从其他字符串中创建和初始化MyString对象
          4e:给类添加一些成员函数:
        返回字符串的长度
        输出字符串
        索引从0开始,找出某个字符或子字符串在字符串中的位置,如果没有找到则返回-1
        现在可以编写一个测试程序,以各种方式创建并处理mystring对象,保证所有的成员都工作正常 
 
第十四章:运算符重载
    (1):在类中可以重载任何运算符,以提供针对该类的功能,但作用域解析符(::),条件运算符(?:),成员访问运算符(.),解除类成员指针的引用运算符(.*)和sizeof运算符不能重载
    (2):运算符函数可以定义为类的成员或全局运算符函数
    (3):如果一元运算符定义为类的成员函数,操作数就只类对象
    (4):如果一元运算符定义为全局运算符函数,操作数就是函数的参数
    (5):如果二元运算符定义为类的成员函数,左操作数就是类对象,右操作数就是函数的参数
    (6):如果二元运算符定义为全局运算函数,第一个参数指定左操作数,第二个参数指定为右操作数
    (7):要重载递增运算符,需要用两个函数分别提供运算符前缀和后缀形式,实现后缀运算符的函数有一个int类型的额外参数,它仅用于与前缀函数区分,递减运算符也是这样
    (8):实现+=运算符重载的函数可以用在+函数的实现上,所有op=运算符都是这样
    (9):智能指针是一个操作类似于指针的对象,智能指针的一种形式是迭代给定类型的对象的复杂集合,采用的方式与一般指针类似,标准模板库广泛使用了这种形式
 
练习题
     1:这些练习都建立在第13章练习题的基础上,首先为MyString类提供一个重载的赋值运算符,确保它不是自我赋值,用下面的语句测试这个运算符是否工作正常,其中s1, s2,s3都是MyString的对象
        s1 = s2;
                s1 = s1;
                s1 = s2 = s3;
     2:重载加运算符,提供字符串连接功能,测试s1 = s2+s3;语句正确运行,提供+=运算符,这个运算符返回什么值?
     3:重载[],提供对字符串中单个字符的访问,于是,s1[4]返回s1中的5第个字符,如果确保它可以于等号的两端
     4:提供==,!=,<,>运算符的重载,用于比较MyString对象,这些布尔运算符应返回什么类型?检查表达式if(s1 == s2)?
     5:(教难)重载()运算符,从MyString对象返回一个子字符串,于是s1(2, 3)返回从s1[2]开始的三个字符
 
第十五章:继承********************************
     (1):类可以派生自一个或多个基类,此时派生类在其所有的基类中继承成员
     (2):单一继承就是从一个基类中派生新类,多重继承就是从两个或多个基类中派生新类
     (3):访问派生类的继承成员由两个因素控制:基类中成员的访问指定符和在派生类声明中基类的指定访问符
     (4):创建派生类对象一般需要按顺序(从一般的基类开始到最特殊的直接基类)调用所有直接和间接基类的构造函数,之后执行派生类的构造函数
     (5):派生类构造函数可以在初始化类表中显式调用直接基类的构造函数
     (6):在派生类中声明的成员名,如果与继承的成员名相同,就会遮盖继承的成员,为了访问被遮盖的成员,可以使用作用域解析运算符和类名来限定成员名
     (7):如果派生类有两个或多个直接基类,就会包含同一个类的两个或多个继承子对象,此时把重复的类声明为虚基类,就可以避免出现重复
 
练习题
      1:定义一个基类,它包含两和私有成员,一个是string,存储动物的名称(例如"Fido"或"Yogi"),另一个是整数成员,weight,包含该动物的重量,该类还包含一个公共函数who(),它可以显示一个消息,给出对象的名称和重量,把用做公共基类,派生两个类lion和Aardvatk,再编写一个main()函数,创建lion和Aardvatk对象("Leo",400磅,"Algernon",50磅),为派生类对象调用who()成员,说明who()成员在两个派生类中继承的来的
      2:在类中,把who()函数的访问指定符改为peotected,但类中的其他内容不边,现在修改派生类,使原来的main()函数仍能工作
      3:在上一题中,把基类成员who()的访问指定符改为public,但把who()函数实现为每个派生类的成员,且在输出消息中显示派生类名,现在修改main()函数,为每个派生类对象调用who()的基类版本和派生类版本
      4:定义一个类Person,它包含数据成员age, name和gender,从Person中派生一个类Employee,在新类中添加一个数据成员,存储个人的number,再从Employee中派生一个类Executive,每个派生类都应定义一个函数,来显示相关的信息,(名称和类型,如"Fred Smith is an Employee").编写一个main()函数,生成两个数组,一个数组包含5个Executive对象,另一个数组包含5个一般的Employee对象,然后显示它们的信息,另外,调用Employee类继承的成员函数,显示的信息
 
第十六章:虚函数和多态性***************************
    (1):多态性是指通过指针或引用调用函数,而且调用是动态解析的,即在程序执行时确定调用哪个函数
    (2):基类中的函数可以声明为vitual,在派生于该基类的所有类中,这会迫使该函数总是虚函数,在通过指针或引用调用函数时,函数调用就是动态解析的,函数调用的对象类型,将确定所使用的函数版本
    (3):使用对象或直接成员选择运算符来调用虚函数,该函数调用就是动态解析的,即在编译期间进行解析
    (4):如果基类包含虚函数,就应把基类的虚函数声明为vitual,这会为确保动态创建的派生类对象选择正确的函数
    (5):纯虚函数没有定义,基类的虚函数在函数声明的最后加上=0,就变成了纯虚函数
    (6):包含一个或多个纯虚函数的类被称为抽象类,这种类不能创建对象,在该类的任何派生类中,必须定义所继承的所有纯虚函数,否则该派生类也是抽象类,也不能创建类的对象
    (7):虚函数的默认参数值是静态赋予的,如果虚函数的的基类版本有默认的参数值,在派生类中指定的默认参数值就会被忽略,因为虚函数调用是动态解析的
    (8):可以声明类成员的指针,它们可以是数据成员的指针,也可以是函数成员的指针,这类指针需要与对象,对象的引用或指针一起使用,来引用成员指针定义的对象的类成员
练习题
    1:在15章的练习中,定义了一个基类Animal,它包含两个私有数据成员,一个是string成员,存储动物的名称("Fido"),一个是整数成员weight,存储了动物的重量(单位是磅),该基类还包含一个公共的虚拟函数who()和一个纯虚函数sound(),公共的虚拟函数who()返回一个string对象,该对象包含了Animal对象的名称和重量,纯虚函数sound()在派生类中应返回一个string对象,表示该动物发出的声音,把Animal类作为一个公共基类,派生至少三个类Sheep, Dog和Cow,在每个类中实现sound()函数
      定义一个类Zoo,它至多可以在一个数组中存储50种不同类型的动物(使用指针数组),编写一个main()函数,创建给定数量的派生类对象的随机序列,在Zoo对象中存储这些对象的指针,使用Zoo对象的一个成员函数,输出Zoo中每个动物的信息,以及每个动物发出的声音
    2:定义一个BaseLength,它把长度存储为一个整数值,从BaseLength中派生一个成员函数length(),该函数返回一个指定长度的double值,从BaseLength中派生一些类Inches, Meters ,Yards, Perches,并重写基类的length()函数,把长度返回为相应单位的double值,(1英寸=25.4毫米,1米=1000毫米,1码=36英寸,1杆(US)=5.5码),定义一个main()函数,读取一系列不同单位的长度,创建相应的派生类对象,把它们的地址存储在 BaseLength* 类型的数组中,以毫米和原单位输出每个长度
    3:定义转换运算函数,把第二题中的每个派生类型转换为其他派生类型,例如,在Inches类中,定义成员operator Meters(), operator Perches()和operator Yards(),在main()中添加代码,以4种不同的单位输出每个长度值(转换运算符不需要指定返回值,因为返回类型在名称中隐含了)
    4:使用转换的构造函数代替转换运算符,完成第3题
第十七章:程序错误和异常处理*************************
第十八章:类模板
第十九章:输入输出操作
第二十章:标准模板库(STL)
  第十六章     虚函数和多态性************************
本章小结
1、多态性是通过指针或引用调用函数,而且调用是动态解析的,即在程序执行时确定调用哪个函数。
2、基类中的函数可以声明为virtual,在派生于该基类中的所有类中,这会迫使该函数总是虚函数。在通过指针或引用调用虚函数时,函数调用就是动态解析的。函数调用的类型将确定所使用的函数版本。
3、使用对象和直接成员选择运算符来调用虚函数,该函数调用就是静态解析的,即在编译期间解析。
4、如果基类包含虚函数,就应把该函数声明为virtual。这会确保为动态创建的派生类对象选择正确的析构函数。
5、纯虚函数没有定义。基类中的虚函数在函数声明的最后加上=0,就变成了纯虚函数。
6、包含一个或多个纯虚函数的类称为抽象类,这种类不能创建对象。在该类的任何类中,必须定义所继承的所有纯虚函数。否则该派生类业是抽象类,也不能创建该类的对象。
7、虚函数的默认参数值是静态赋予的,如果虚函数的基类版本有默认参数值,在派生类中指定的默认参数值就会被忽略,因为虚函数是动态解析的。
8、可以声明类成员的指针。他们可以是数据成员的指针,也可以是函数成员的指针。这类指针要与对象、对象的引用或指针一起使用,来引用成员指针定义的对象的类成员。
 
练习
 
1、定义一个基类Animal,它包含两个私有数据成员,一个是string,存储动物的名称(例如"Fido"),另一个是整数成员weight,包含该动物的重量(单位是磅)。该类还包含一个公共虚拟成员函数who()和一个纯虚函数sound(),公共的虚拟成员函数who()返回一个string对象,表示该动物发出的声音。把Animal类作为一个公共基类,派生至少三个类Sheep、Dog和Cow,在每个类中实现Sound()函数。
       定义一个类ZOO,他至多在一个数组中存储50种不同类型的动物(使用指针数组)。编写一个MAIN()函数,创建给定数量的派生类对象的随机序列,在ZOO对象种存储这些对象的指针。使用ZOO对象的一个成员函数,输出ZOO中每个动物的信息,以及每个动物发出的声音。
2、定义一个类Baselength,把他的长度存储为一个整数值,单位是毫米,该类有一个成员函数length(),该函数返回一个指定长度的double值。从Baselength中派生一些类Inches、Meters、Yards和Perches,并重写基类的length()函数,把长度返回为相应单位的double值(1英寸=25。4毫米,1米=1000毫米,1码=36英寸,1杆(US)=5.5码)。定义一个main()函数,读取一系列不同单位的长度,创建相应的派生对象,把他们的地址存储在Baselength*类型的数组中。以毫米和原单位输出每个长度。
3、定义转换运算符函数,把第2题中的每个派生类型转换为其他派生类型。例如,在Inches类中,定义成员operator Meters()、operator Perches()和operator Yards()。在main()中添加代码,以4种不同的单位输出每个长度值(转换运算符不需要指定返回值,因为返回类型在名称中隐含了)。
4、使用转换的构造函数代替转换运算符,完成第3题。
 
 
第十七章 程序错误和异常处理*************************
本章小结:
1、异常是用于在程序中警示错误的对象。
2、可能抛出异常的代码通常包含在try块中。
3、处理在try块中抛出的各种类型异常的代码放在该try块后面的一个或多个catch块中。
4、Try块及其catch块可以嵌套在另一个try块中。
5、参数为基类类型的处理程序可以捕获派生类类型的异常。
6、如果异常没有被catch块捕获,就调用terminate()函数,该函数会接着调用abort()。
7、标准库定义了一组标准异常。
8、异常说明限制了函数可以抛出的异常类型。
9、如果函数抛出的异常类型不在该函数的异常说明的允许范围之内,就会调用unexcepted()函数。
10、可以改变unexcepted()函数的默认操作,方法是实现自己的excepted()处理程序,把该函数指针传递给set_ unexcepted()函数,以建立该处理程序。
11、构造函数的函数try块可以包含初始化列表和构造函数体。
12、Uncaught_ exceptioned()函数允许检测因抛出异常而调用的析构函数。
 
 
练习
 
1、从标准exception类中派生自己的异常类CurveBall,表示一个随机错误,再编写一个函数,在时间过了大约25%时抛出这个异常(一种方式是生成一个1到20之间的随机数,如果该数小于或等于5,就抛出异常)。定义函数main(),调用这个函数1000次,记录并显示异常抛出的次数。
2、定义另一个异常类TooManyExceptions,在第1题中,当捕获的异常超过10次时,就从CurveBall异常的catch块中抛出这个类型的异常。
3、在第一题的代码中实现自己的中断处理程序,在抛出TooManyExceptions异常时显示一个消息。
4、在稀疏数组中,大多数元素的值都是0或空。给类型为string指针的一维稀疏数组元素定义一个类,仅存储数组中的非0元素。元素的个数应指定为构造函数参数,因此至多可以存储100个对象的稀疏数组声明如下:
 
        SparseArray words(100);
 
为类实现下标运算符,以使用数组表示法提取或存储元素。如果在下标运算符函数中超出了合法的索引范围,就抛出了异常(提示:在内部使用链表,让每个节点存储一个元素及其下标)。
 
 
 
 
第十八章 类模版*************************
本章小结:
1、类模板定义了一系列类类型。
2、类模板的实例是根据给定的模版参数集,从该模版中生成的类定义。
3、声明类模板类型的对象,就会对类模板进行隐式实例化。
4、类模版的显式实例化,会根据类模版的给定参数集定义一个类。
5、对于类模版中类型参数的参数,其类型可以是基本类型、类类型、指针或引用类型。
6、非类型参数可以是整型类型、枚举类型、指针或引用。
7、类模板的部分说明可以根据原类模板中参数的一组限定子集,定义一个新模板。
8、类模板的完全说明可以根据原类模板的所有参数参数,定义一个新模板。
9、类模板的友元可以是函数、类、函数模板或类模板。
10、普通的类可以把类模板或函数模板声明为友元。
 
练习
 
1、第17章的练习题要求创建一个稀疏数组类。这里则要求定义一个一维稀疏数组的模板,存储任意类型的对象,而且只有存储在数组中的元素才能占用内存。元素的个数可以由模板的一个实例存储,该个数是不应有限制的。该模板可以用于定义一个稀疏数组,该数组包含double类型的元素指针,语句如下:
 
SparseArray<double>values;
 
为模板定义下标运算符,以便象普通的数字那样提取和设置元素值。如果在某个索引位置不存在元素,下标运算符就应该返回由对象类的默认构造函数创建的对象。在main()函数中使用这个模版,在一个稀疏数组的随机位置上存储20个int类型的随机元素值,随机数的范围是32到212,索引值的范围是0到499,输出非0元素值及其索引位置。
 
2、为链表定义一个模板,允许从链表的最后开始向前遍历链表,再从列表的开始向后遍历列表(每个节点都需要前一个节点的指针和下一个节点的指针)。在一个程序中使用该模板,把每个散文或诗歌中的单词存储为字符串对象,再以逆序方式显示他们,一行显示5个单词。
 
3、使用链表和稀疏数组模板创建一个程序,在至多有26个链表的稀疏数组中,存储散文或诗歌中的单词,每个列表都包含首字母的相同单词。输出这些单词,在输出时,对这些单词分组,使每一组单词具有相同的首字母,并在一个新行上显示该组中的单词(在指定模板参数时,应在连续的>字符之间加上空格,否则>>会被解释为按位右移运算符)。
 
4、在SparseArray模板中添加insert()函数,该函数在数组的最后一个元素后面添加一个元素。使用这个函数和一个SparseArray实例完成上一题,其中,该实例的元素是存储了string对象的SparseArray对象。
 
 
第十九章    输入输出操作*************************
本章小结:
1、标准库支持字符流、二进制(字节)流和字符串流的输入输出操作。
2、输入和输出的标准是cin和cout,还有错误流cerr和clog。
3、提取和插入运算符提供了格式化的流输入输出操作。
4、文件流可以与磁盘上的文件关联起来,进行输入、输出或输入输出。
5、文件大开模式决定了是从流中读取数据,还是给流写入数据。
6、如果创建了一个文件输出流,并把它与未有文件本身使用的文件名关联起来,就会创建该文件。
7、文件有开头、结尾和当前位置。
8、可以把文件流的当前位置改为以前记录的某个位置。这位置与流开头的偏移量为正,
9、结尾的偏移量为负,而与流当前位置的偏移量可以为正,也可以为负。
10、为了支持类对象的流操作,可以重载插入和提取运算符,使这些运算符函数成为类的友元。
11、字符串流类提供了string对象的输入输出操作。
 
 
练习
 
1、编写一个Time类,把小时、分钟和秒存储为整数。提供一个重载的插入运算符(<<),把时间以hh::mm::ss的格式输出到任意输出流上。
 
2、给time类提供一个简单的提取运算符(operator>>()),它可以以hh::mm::ss格式读取时间值。如何复制“:”符号?(提示:用什么类型的变量存储“:”?)
 
3、编写一个程序,把时间记录到文件中。编写一个匹配程序,读取文件中的时间值,把他们显示到屏幕上。
 
4、编写一个程序,从标准输入中读取文本行,再把他们写到标准输出上,删除所有的前导空白,把多个空格转换为一个空格。对键盘输入测试该程序,再对从文件中读取的字符测试该程序。编写第二个程序,把小写字母转换为大写形式,在测试他们。
 
 
 
 
 
第二十章   标准模板库*************************
本章小结:
1、STL通过三类模板提供了功能:容器、迭代器和算法。
2、容器提供了存储和组织任意类型的对象的各种方式,但要存储的对象类型必须满足元素的基本要求。
3、迭代器是操作方式像指针的对象。迭代器是智能指针的示例。
4、迭代器可以访问容器中的对象,或从流中提取对象。
5、迭代器成对使用时,可以在序列的半开间隔中定义一组对象。第一个对象包含在间隔中,而最后一个对象不包含在间隔中。
6、算法是一般化的标准函数,可以处理迭代器指定的对象集。
7、算法独立于容器,但可以通过迭代器应用于任何容器中的对象。
 
 
练习
 
1、编写一个程序,使用Vector存储任意个城市,这些城市借助键盘读取为string对象,再输出他们。
 
2、在上一题中添加代码,使用sort()算法按照升序对出城市排序,之后输出他们。
 
3、编写一个程序,借助键盘读取任意个名称和关联的电话号码(其格式是”Laurel , Stan” 5431234),把他们存储在map容器中,给定一个名称,就可以提取电话号码。在输入一系列名称和电话号码后,对map进行随机访问,提取一个随即电话号码。
 
4、利用上一题的代码,使用一个迭代器列出map的内容。
 
5、给上一题添加代码,用multimap替换map容器,为给定的名称列出所有的电话号码,作为查询的相应。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值