1 / 36

// BINFILE.CPP #include <fstream.h> void main() { ofstream of("test2.dat", ios :: binary);

// BINFILE.CPP #include <fstream.h> void main() { ofstream of("test2.dat", ios :: binary); int nArr[10]; for(int i = 0; i < 10; i ++) nArr[i] = i * i; of.write((char*)nArr, 10 * sizeof(int)); of.close(); }. void main() { ifstream inf("test2.dat", ios :: binary);

hovan
Télécharger la présentation

// BINFILE.CPP #include <fstream.h> void main() { ofstream of("test2.dat", ios :: binary);

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. // BINFILE.CPP #include <fstream.h> void main() { ofstream of("test2.dat", ios :: binary); int nArr[10]; for(int i = 0; i < 10; i ++) nArr[i] = i * i; of.write((char*)nArr, 10 * sizeof(int)); of.close(); }

  2. void main() { ifstream inf("test2.dat", ios :: binary); int n; while(1) { inf.read((char*)&n, sizeof(int)); if(inf.eof()) break; cout << n << " "; } cout << endl; inf.close(); } 该程序的输出为: 0 1 4 9 16 25 36 49 64 81

  3. int Lookup(char* fname, int what, int num) { ifstream inf(fname, ios :: binary); int n, low = 0, hi = num - 1, mid, len = sizeof(int); while(low <= hi) { mid = (low + hi) / 2; inf.seekg(mid * len); inf.read((char*)&n, len); if(n == what) break; if(n < what) { low = (mid + 1) * len; else hi = (mid - 1) * len; }

  4. inf.close(); if(low > hi) return -1; return(inf.tellg() - len); } 习题: 31,32,33

  5. 第14章 模板 模板(Template)是 C++ 语言代码重用和多态性的一个集中表现。模板是提供这样一个转换机制:由程序员定义一种操作或一个类,而该操作或类却可以适应几乎所有的数据类型。在一定意义上,模板类似宏定义或函数重载,但它书定更为简洁,使用更加灵活,适应性更强。 模板分函数模板和类模板。前者为程序员编写通用函数提供了 一种手段;而后者则为程序员设计通用类奠定了基础。

  6. 14.1 函数模板 14.1.1 定义模板函数 利用函数模板定义的函数叫做模板函数,定义模板函数应具有以下的一般形式: template<class T> type Function_Name(arg_list) { // Function_Body; } 其中:关键字 template 指出下面将要说明的是一个模板;而<class T> 则是该函数所要求的参数,这里的 class 与类无关,而是与参数名 T 一起指出:“这是一个用户定义的数据类型”,它与一对尖括号是模板语法的组成部分。

  7. 例:定义模板函数 // MAXMIN.H template<class T> T Max(T a, T b) { return (a > b) ? a : b; } template<class T> T Min(T a, T b) { return (a < b) ? a : b; }

  8. 定义模板函数时应注意: 1. 在模板的参数表中,至少得有一个参数的数据类型为模板的参数类型 T;模板函数的返回值的数据类型也可以为 T。 2. 模板可以带有多个不同数据类型的参数,比如: template<class T1, class T2, class T3> int f(T1 arg1, T2 arg2, T3 arg3) { //… } 3. 模板参数的数据类型也可以是已存在的数据类型,比如: template<class T, int n> T f(T arg) { int i = n; //… }

  9. 4. 函数可以带有模板中未给出的、已存在的数据类型的参数,比如: template<class T> T f(T arg, int n) { //… } 5. 模板函数的函数体中必须使用模板参数。

  10. 14.1.2 使用模板函数 调用模板函数与调用一般函数的方法无二致。 例:使用 Max()和 Min()模板函数 #include <iostream.h> #include "maxmin.h" void main() { int i = 3, j = 5; float f1 = 12.34, f2 = 23.45; cout << Max(i, j) << endl; cout << Min(f1, f2) << endl; cout << Max('a', 'b') } 程序的输出为: 5 12.34 b

  11. 14.2 类模板 14.2.1 定义模板类 利用类模板定义的类叫做模板类。定义模板类具有如下的一般形式: template<class T> class Class_Name { // Members; };

  12. 例:定义模板类 // ANYTYPE.H template<class T> class AnyType { private: T x, y; public: AnyType(T a, T b) : x(a), y(b) {} void SetX(T a) { x = a; } void SetY(T b) { y = b; } T GetX() { return x; } T GetY() { return y; } }; // End of ANYTYPE.H

  13. 上例中,模板类 AnyType 中所有成员函数均在类中定义成内联函数。实际上,与一般类相同,模板类中的任一成员函数均可以在类外定义。在类外定义成员函数的一般形式与定义模板函数基本相同: template<class T> type Class_Name<T> :: Func_Name(ages) { // Function_Body; } 请注意这里类名的写法:模板类与普通类的不同之处在于模板类的类名一定具有 Class_Name<T> 的形式。

  14. 例:定义一个栈模板类 // ANYSTACK.H #if !defined _ANYSTACK_H_ #define _ANYSTACK_H_ template<class T, int n = 10> class AnyStack { private: T Stack[n]; int TopMost; int Top; public: AnyStack() : TopMost(n), Top(0) {} int Push(T); int Pop(T&); }

  15. template<class T, int n> int AnyStack<T, n> :: Push(T Elem) {if(Top == TopMost) // 栈已满 return 0; Stack[Top ++] = Elem; return 1; } template<class T, int n> int AnyStack<T, n> :: Pop(T& rElem) {if(Top == 0) // 栈为空栈 return 0; rElem = Stack[-- Top]; return 1; } #dneif

  16. 14.2.2 使用模板类 与一般类一样,在使用一个类时必须先行说明属于该类类型的对象(或指针)。然而,模板类对象的说明形式与一般类对象有所不同,说明模板类对象具有如下的一般形式: Class_Name<type> Obj_Name; 其中:type为任一已存在的数据类型(包括类类型)。

  17. 例:使用 AnyStack 模板类 #inclucd <iostream.h> #include "anystack.h" void main() { AnyStack<int> iStk; AnyStack<float 5> fStk; int i, iE; float fE; for(i = 1; i < 6; i ++) { iStk.Push(i); fStk.Push(i * 3.14); }

  18. while(iStk.Pop(iE)) cout << iE << '\t'; cout << endl; while(fStk.Pop(fE)) cout << fE << '\t'; cout << endl; } 该程序的输出为: 1 2 3 4 5 3.14 6.28 9.42 12.56 15.70

  19. H ^ ^ Prev Info Next 综合举例 问题 设计一个双链表类,并为其提供相应的公有接口。 分析 所谓双链表是指一种线性表,该表由一个个叫做结点(Node)的元素组成,各结点分别有两个指针:一个指向其前趋(Previous);一个指向其后继(Next)。如下图所示。

  20. 从上图可以看出:双链表的设计可以分为两部分——结点的设计和链表的设计。为了便于链表对结点的访问,可以将链表类设计成结点类的友元。从上图可以看出:双链表的设计可以分为两部分——结点的设计和链表的设计。为了便于链表对结点的访问,可以将链表类设计成结点类的友元。 结点的运算(操作)主要包括:创建结点、销毁结点、访问结点的信息(Info)域、访问结点的链域(Prev 或 Next)。 双链表的运算主要包括:创建一个空链表、销毁整个链表、在链表中插入一个结点、删除链表中的一个指定结点、在链表中查找一个指定内容的结点。其中插入操作又可以分为:在链表尾部插入(也叫追加)、在某一指定结点之前插入(称为前插入)、在某一指定结点之后插入(称为后插入)。同样,删除操作也可以分为:自身删除、前删除和后删除。

  21. // OBJECT.H #if !defined _OBJECT_H_ #define _OBJECT_H_ class Object { public: Object() {} virtual ~Object() {} virtual int operator ==(Object&) = 0; virtual int operator >(Object&) = 0; virtual int operator <(Object&) = 0; virtual void Show() = 0; }; #endif

  22. // NODE.H #include "object.h" class NODE { private: Object * Info; NODE *Prev, *Next; public: NODE() : Info(0), Prev(0), Next(0) {} ~NODE() { delete Info; } void SetInfo(Object& rObj) { Info = rObj; } Object* GetInfo() { return Info; } void ShowInfo() { Info.Show(); } friend class DLIST; };

  23. // DLIST.H #if !defined _DLIST_H_ #define _DLIST_H_ #include "node.h" class DLIST { private: NODE *Head, *Tail; void DestroyList(); public: DLIST() : Head(0), Tail(0) {}

  24. void AppendNode(NODE*); void InsertPrev(NODE*, NODE*); void InsertNext(NODE*, NODE*); NODE* DeleteNode(NODE*); NODE* DeletePrev(NODE*); NODE* DeleteNext(NODE*); NODE* Lookup(Object&); void ShowList(); void DestroyList(); ~DLIST() { DestroyList(); } }; #endif

  25. n T H // DLIST.CPP #include "dlist.h" void DLIST :: AppendNode(NODE* node) { if(Head == 0) Head = Tail = node; else { Tail->Next = node; node->Prev = Tail; Tail = node; } }

  26. void DLIST :: InsertPrev(NODE* node, NODE* pPos) { node->Prev = pPos->Prev; node->Next = pPos; pPos->Prev = node; node->Prev->Next = node; } void DLIST :: InsertNext(NODE* node, NODE* pPos) { 作为习题请同学自己编写; }

  27. NODE* DLIST :: DeleteNode(NODE* node) { node->Prev->Next = node->Next; node->Next->Prev = node->Prev; node->Prev = node->Next = 0; return node; } NODE* DLIST :: DeletePrev(NODE* pPos) { return DeleteNode(pPos->Prev); }

  28. NODE* DLIST :: DeleteNext(NODE* pPos) { return DeleteNode(pPos->Next); } void DLIST :: ShowList() { NODE* pnode = Head; while(pnode) { pnode->ShowInfo(); pnode = pnode->Next; } }

  29. NODE* DLIST :: Lookup(Object& rObj) { NODE* pnode = Head; while(pnode) { if(*(pnode->Info) == rObj) // 调用重载了的关系运算符 return pnode; pnode = pnode->Next; } return 0; }

  30. void DLIST :: DestroyList() { NODE *pnode = Head; while(pnode) { Head = pnode->Next; delete pnode->Info; delete pnode; pnode = Head; } } // End of DLIST.CPP

  31. // COMPLEX.H #if !defined _COMPLEX_H_ #define _COMPLEX_H_ #include "object.h" class Complex : public Object { private: float Real; float Img; public: Complex() : Real(0), Img(0) {} Complex(float r, float i) : Real(r), Img(i) {} ~Complex() {}

  32. void SetReal(float r) { Real = r; } void SetImg(float i) { Img = i; } float GetReal() { return Real; } float GetImg() { return Img; } virtual int operator ==(Object&); virtual int operator >(Object&); virtual int operator <(Object&); virtual void Show(); }; #endif // End of COMPLEX.H

  33. // COMPLEX.CPP #include <iostream.h> #include "complex.h" int Complex :: operator ==(Object& rObj) { Complex &com = (Complex&)rObj; return (com.Real == Real && com.Img == Img); } int Complex :: operator >(Object& rObj) // 自编 int Complex :: operator <(Object& rObj) // 自编

  34. void Complex :: Show() { cout << Real << " + " << Img << 'i' << endl; } // End of COMPLEX.CPP

  35. // TESTLIST.CPP #include <iostream.h> #include "dlist.h" #include "complex.h" void main() { DLIST List; NODE *pn, node; Complex *pc, Key; for(int i = 1; i <= 5; i ++) { pc = new Complex(i * 3.5, i * 4.6); pn = new NODE; pn->SetInfo(pc);

  36. 该程序的输出为: 3.5 + 4.6i 7 + 9.2i 10.5 + 13.8i 14 + 18.4i 17.5 + 23i 3.5 + 4.6i 7 + 9.2i 14 + 18.4i 17.5 + 23i List.AppendNode(pn); } List.ShowList(); cout << endl; Key.SetReal(10.5); Key.SetImg(13.8); pn = List.Lookup(Key); if(pn) pn = List.DeleteNode(pn); List.ShowList(); delete pn; }

More Related