- #include
- #include
- #include
- using namespace std;
- //文本操作
- //程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放
- //通过文件可以数据持久化
- //c++中对文件操作包含头文件
- //文件类型分为两种:
- //1.文本文件 -文件以文本的ASCLL码形式存储在计算机中
- //2.二进制文件 - 文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们
- //操作文件的三大类
- //1.ofstream:写操作
- //2.ifstream:读操作
- //3.fstream: 读写操作
- //写文件
- //1.包含头文件
- //#include
- //2.创建流对象
- //ofstream ofs;
- //3.打开文件
- //ofs.open("文件路径",打开方式);
- //文件打开方式:
- //ios::in 读文件方式打开
- //ios::out 写文件方式打开
- //ios::ate 初始位置:文件尾
- //ios::app 追加文件方式打开
- //ios::trunc 如果文件存在先删除,再创建
- //ios::binary 二进制方式
- //文件打开方式可以配合使用,利用|操作符
- //4.写数据
- //ofs<<"写入的数据";
- //5.关闭文件
- //ofs.close();
- void test(){
- //1.包含头文件
- //2.创建流对象
- ofstream ofs;
- //3.指定打开方式
- ofs.open("text.txt",ios::out);
- //4.写内容
- ofs<<"姓名:张三"<
- ofs<<"性别:男"<
- ofs<<"年龄:25"<
- //5.关闭文件
- ofs.close();
- }
- //读文件
- //1.包含头文件
- //#include
- //2.创建流对象
- //ifstream ifs;
- //3.打开文件并判断文件是否打开
- //ifs.open("文件路径",打开方式);
- //4.读数据
- //四种方式读取
- //5.关闭文件
- //ifs.close()
- void test1(){
- //1、包含头文件
- //2、创建流对象
- ifstream ifs;
- //3、打开文件并判断文件是否打开
- ifs.open("text.txt",ios::in);
- if(!ifs.is_open()){
- cout<<"文件打开失败"<
- return;
- }
- //4、读数据
- //第一种
- char buf[1023] = {0};
- while(ifs >> buf) {
- cout<
- }
- // //第二种
- // char buf[1024] = {0};
- // while(ifs.getline(buf,sizeof(buf))) {
- // cout<
- // }
- // //第三种
- // string buf;
- // while(getline(ifs,buf)){
- // cout<
- // }
- //第四种
- // char c;
- // while((c = ifs.get()) != EOF){ //EOF end of file
- // cout<
- // }
- //5、关闭文件
- ifs.close();
- }
- //二进制文件
- //以二进制的方式对文件进行读写操作
- //打开方式要指定为ios::binary
- //二进制文件写文件
- //二进制方式写文件主要利用流对象调用成员函数write
- //函数原型:ostream&write(const char *buffer,int len);
- //参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数
- class Person{
- public:
- char m_Name[64];
- int m_Age;
- };
- void test2(){
- //1.包含头文件
- //2.创建流对象
- ofstream ofs;
- //3.打开文件
- ofs.open("person.txt",ios::out|ios::binary);
- //创建流对象和打开文件一起
- // ofstream ofs("person.txt",ios::out|ios::binary);
- //4.写文件
- Person p = {"张三",18} ;
- ofs.write((const char *)&p, sizeof(p));
- //5.关闭文件
- ofs.close();
-
- }
- //二进制文件读文件
- //函数原型:istream&read(char *buffer,int len);
- class Person1{
- public:
- char m_Name[64];
- int m_Age;
- };
- void test3(){
- //1.包含头文件
- //2.创建流对象
- ifstream ifs;
- //3.打开文件 判断文件是否打开成功
- ifs.open("person.txt",ios::in|ios::binary);
- if(! ifs.is_open()){
- cout<<"文件打开失败"<
- return;
- }
- //创建流对象和打开文件一起
- // ifstream ofs("person.txt",ios::out|ios::binary);
- //4.读文件
- Person1 p;
- ifs.read((char *)&p, sizeof(Person1));
- cout<<"姓名:"<
" 年龄:"< - //5.关闭文件
- ifs.close();
- }
- int main(){
- //文本文件写
- test();
- //文本文件读
- test1();
- //二进制文件写
- test2();
- //二进制文件读
- test3();
- }
模板:
- #include
- #include
- using namespace std;
-
- //1.2函数模板语句
- //c++另一种编程思想称为泛型编程,主要利用的技术就是模板
- //c++提供两种模板机制:函数模板和类模板
- //1.2.1函数模板作用:
- //建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表
- //语法: template
- // 函数声明或定义
- //template --- 声明创建模板
- //typename --- 表明其后面的符号是一种数据类型,可以用class代替
- //T --- 通用的数据类型,名称可以替换,通常为大写字母
-
- //函数模板
- template<typename T>
-
- void mySwap(T &a,T &b)
- {
- T temp = a;
- a = b;
- b = temp;
- }
- 两个整型交换函数
- //void swapInt(int &a,int &b)
- //{
- // int temp = a;
- // a = b;
- // b = temp;
- //}
- 交换两个浮点型函数
- //void swapDouble(double &a,double &b)
- //{
- // double temp = a;
- // a = b;
- // b = temp;
- // }
-
- void test01()
- {
- cout<<"************test01**********"<
- <<"***********函数模板*********"<
- int a = 10;
- int b = 20;
- // swapInt(a,b);
- //
- // double c = 1.1;
- // double d = 2.2;
- // swapDouble(c,d);
- // cout<<"c = "<
//函数模板两种使用方法 - //1、自动类型推导
- mySwap(a,b);
- cout<<"a = "<" b = "<
- //2、显示指定类型
- mySwap<int>(a,b);
- cout<<"a = "<" b = "<
- }
- //1.2.2 函数模板注意事项
- //注意事项:
- //1、自动类型推导,必须导出一致的数据类型T,才可以使用
-
- //2、模板必须要确定出T的数据类型,才可以使用
- //template
- //void func()
- // {
- // cout<<"func 调用"<
- // }
- //调用func()是错误的,必须明确func的数据类型
-
-
- //1.2.3 函数模板案例
- //案例描述:
- //利用函数模板封装一个排序的函数。可以对不同类型数组进行排序
- //排序规则从大到小,排序算法为选择排序
- //分别利用char数组和int数组进行测试
-
- //排序算法
- template <typename T>
- void mySort(T arr[], int len)
- {
- for(int i = 0;i < len;i++)
- {
- int max = i;
- for(int j = i+1; j
- {
- if(arr[max]
// 此处是max 不是 i,需要实时更新max的值 - {
- max = j;
- }
- }
- if(max!=i)
- {
- mySwap(arr[i],arr[max]);
- }
- }
- }
-
- // 6,432,432,32,32
- // i = 0; max = 0 j = 1 32
- // i = 1; max = 1 j = 2 432
- // i = 2; max = 2 j = 3 432
- // i = 3; max = 3 j = 4 max = 4 2
- // i = 4; max = 4 j = 5 max = 4 1
-
- //打印
- template <typename T>
- void show(T arr[],int len)
- {
- for(int i = 0; i < len;i++)
- {
- cout<
" "; - }
- cout<
- }
-
- void test02()
- {
- cout<<"************test02**********"<
- <<"********函数模板测试排序*******"<
- char charArr[] = "fdacbeg";
- int intArr[] = {6,432,432,32,32};
-
- int len = sizeof(charArr)/sizeof(charArr[0]);
- int size = sizeof(intArr)/sizeof(intArr[0]);
-
- show(charArr,len);
- mySort(charArr,len);
- show(charArr,len);
-
- show(intArr,size);
- mySort(intArr,size);
- show(intArr,size);
- }
- //1.2.4 普通函数与函数模板的区别
- //普通函数与函数模板区别
- //普通函数调用时可以发生自动类型转换(隐式类型转换)
- //函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
- //int myAadd(int a, int b)
- //{
- // return a + b;
- // }
- // myAadd(10,"c");//不会报错,隐式类型转换,转为ACI码相加
- //template
- //T myAdd02(T a, T b)
- //{
- // return a + b;
- //}
- // myAadd02(10,"c");//会报错,隐式类型不能转换
- //1.2.5普通函数与函数模板的调用规则
- //调用规则如下:
- //1.如果函数模板和普通函数都可以实现,优先调用普通函数
- //2.可通过空模板参数列表来强调调用函数模板
- //3.函数模板也可以发生重载
- //4.如果函数模板可以产生更好的匹配,优先调用函数模板
-
- //void myPrint(int a,int b)
- //{
- // cout<<"调用的模板"<
- // }
- //
- //template
- //void myPrint(T a,T b)
- //{
- // cout<<"调用的模板"<
- //}
- //template
- //void myPrint(T a,T b , T c)
- //{
- // cout<<"调用的重载的模板"<
- //
- //void test01()
- //{
- // int a = 10;
- // int b = 20;
- //
- // myPrint(a,b);//优先调用普通函数
- //通过空模板参数列表,强制调用函数模板
- // myprint<>(a,b);
- // myprint(a,b,c); 函数模板也可以发生重载
- //如果函数模板产生更好的匹配,优先调用函数模板
- // char c1 = "a";
- // char c2 = "b";
- // myprint(c1,c2); // 调用的是模板
- //}
- //1.2.6模板的局限性
- //模板的通用并不是万能的
- //例如
- //如果传入的 a 和 b 是一个数组,就无法实现了
- //template
- //void f(T a,T b)
- //{
- // a = b;
- //}
- //再例如:
- //template
- //void f(T a, T b)
- //{
- // if(a > b){
- //
- // }
- //}
- //在上述代码中,如果T的数据类型传入的是像Person这样的自定义数据类型,也无法正常运行
- class person{
- public:
- person(string name,int age){
- this->myname = name;
- this->myage = age;
- }
- string myname;
- int myage;
- };
- template<class T>
- bool equals (T &a,T &b)
- {
- if(a == b)
- {
- return true ;
- }
- else
- {
- return false;
- }
- }
- //利用具体化person的版本实现代码,具体化优先调用
- template<>bool equals(person &p1,person &p2){
- if(p1.myname == p2.myname && p1.myage == p2.myage){
- return true;
- }
- else{
- return false;
- }
- }
-
- void test03()
- {
- cout<<"************test03**********"<
- <<"********模板的局限性*******"<
- int a = 10;
- int b = 10;
- int ret = equals (a,b);
- if(ret){
- cout<<"a等于b"<
- }
- else{
- cout<<"a不等于b"<
- }
- }
-
- void test04()
- {
- cout<<"************test04**********"<
- <<"********模板的局限性*******"<
- person p1("tom",10);
- person p2("tom",10);
-
- bool ret = equals(p1,p2);
-
- if(ret){
- cout<<"p1 等于 p2"<
- }
- else
- {
- cout<<"p1 不等于 p2"<
- }
- }
- //1.3类模板
- //1.3.1类模板语法
- //类模板作用:
- //建立一个通用类,类中成员 数据类型可以不具体制定,用一个虚拟的类型来代表
- //语法:
- template<class NameType,class AgeType>
- //类
- class Person1{
- public:
- Person1(NameType name,AgeType age)
- {
- this->m_Name = name;
- this->m_age = age;
- }
- void showPerson()
- {
- cout<<"name:"<<this->m_Name<<" age: "<<this->m_age<
- }
- NameType m_Name;
- AgeType m_age;
- };
-
- void test05()
- {
- cout<<"************test05**********"<
- <<"************类模板************"<
- Person1
int>p1("孙悟空",999); - p1.showPerson();
- }
- //1.3.2类模板与函数模板区别
- //类模板与函数模板主要有两点
- //1.类模板没有自动类型推导的使用方式
- //Person1 p1("孙悟空",999);//错误无法自动类型推导
- //2.类模板在模板参数列表中可以有默认参数
- //template
- //Person1
p1("孙悟空",999); // 不会报错,有默认参数 - //1.3.3类模板中成员函数创建时机
- //类模板中成员函数和普通类中成员函数创建时机是有区别的:
- //类模板中的成员函数在调用时才创建
- class Person2
- {
- public:
- void showPerson2()
- {
- cout<<"person2 show"<
- }
- };
-
- class Person3
- {
- public:
- void showPerson3()
- {
- cout<<"person3 show"<
- }
- };
-
- template<class T>
- class Myclass
- {
- public:
- T obj;
- void fun1()
- {
- obj.showPerson2();
- }
- void fun2()
- {
- obj.showPerson3();
- }
- };
- void test06()
- {
- cout<<"************test06**********"<
- <<"********类模板的创建时机*******"<
- Myclass
m; - m.fun1();
- //m.fun2(); fun2 报错 ,Person2类只能使用fun1函数
-
- }
- //1.3.4类模板对象做函数参数
- //三种传入方式:
- //1.指定传入的类型 --- 直接显示对象的数据类型
- template<class T1,class T2>
- class Person4
- {
- public:
- Person4(T1 name, T2 age)
- {
- this->m_name = name;
- this->m_age = age;
- }
- void showPerson()
- {
- cout<<"姓名:"<
" 年龄:"< - }
- T1 m_name;
- T2 m_age;
- };
-
- void printPerson4_0(Person4
int >&p) //指定传入的类型 - {
- p.showPerson();
- }
- //2.参数模板化 ---将对象中的参数变为模板进行传递
- template<class T1,class T2>
- void printPerson4_1(Person4
&p) - {
- p.showPerson();
- // cout<<"T1的类型为:"<
- }
- //3.整个类模板化 ---将这个对象类型模板化进行传递
- template<class T>
- void printPerson4_2(T &p)
- {
- p.showPerson();
- // cout<<"T1的类型为:"<
- }
- void test07()
- {
- cout<<"************test07**********"<
- <<"********类模板对象做函数参数*******"<
- Person4
int>p("天蓬元帅",1999); - printPerson4_0(p);
- printPerson4_1(p);
- printPerson4_2(p);
- }
- //1.3.5类模板与继承
- //当子类继承的父类是一个类模板时,子类在声明的时候,要指出父类中T的类型
- //如果不指定,编译器无法给子类分配内存
- //如果想灵活指定出父类中T的类型,子类也需变为类模板
- //
- //template
- //class Base
- //{
- // T m;
- //};
- class Son:public Base //错误,必须要知道父类中的T类型,才能继承给子类
- //
- //class Son:public Base
- //{
- //
- //};
- //
- //template
- //class Son1:public Base
- //{
- // T1 obj;
- //};
- //Son1
s; // 调用 - //1.3.6 类模板成员函数类外实现
- template<class T1,class T2>
- class Person5
- {
- public:
- Person5(T1 name, T2 age);
- // {
- // this->m_name = name;
- // this->m_age = age;
- // }
- void showPerson();
- // {
- // cout<<"姓名:"<
- // }
- T1 m_name;
- T2 m_age;
- };
-
- //构造函数内外实现
- template<class T1,class T2>
- Person5
::Person5(T1 name, T2 age) - {
- this->m_name = name;
- this->m_age = age;
- }
- //成员函数类外实现
- template<class T1,class T2>
- void Person5
::showPerson() - {
- cout<<"姓名:"<
" 年龄:"< - }
- void test08()
- {
- cout<<"************test08**********"<
- <<"********类模板成员函数类外实现*******"<
- Person5
int>p("白骨精",999); - p.showPerson();
- }
- //1.3.7类模板分文件编写
- //问题:
- //类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到
- //解决:
- //解决1.直接包含.cpp源文件
- //解决2.将声明和实现写到同一个文件中,并更改后缀名.hpp..hpp是约定的名称,不是特定
- //1.3.8类模板与友元
- //全局函数类内实现-直接在类内声明友元即可
- //全局函数类外实现-需要提前让编译器知道全局函数的存在
-
- //类外实现
- template<class T1,class T2>
- class Person6;
-
- template<class T1,class T2>
- void printPerson2(Person6
p) - {
- cout<<"类外实现--姓名:"<
" 类外实现--年龄:"< - }
-
- template<class T1,class T2>
- class Person6
- {
- //全局函数,类内实现
- friend void printPerson(Person6
p) - {
- cout<<"类内实现--姓名:"<
" 类内实现--年龄:"< - }
- //全局函数 类外实现
- //加空模板参数列表
- //如果全局函数是类外实现,需要让编译器提前知道这个函数的存在
- friend void printPerson2<>(Person6
p); - public:
- Person6(T1 name,T2 age)
- {
- this->m_name = name;
- this->m_age = age;
- }
- private:
- T1 m_name;
- T2 m_age;
- };
-
- void test09()
- {
- cout<<"************test09**********"<
- <<"********全局函数类内实现*******"<
- Person6
int>p("张飞",456); - printPerson(p);
- Person6
int>p1("曹操",736); - printPerson2<>(p1);
- }
- int main()
- {
- test01();
- cout<
- test02();
- cout<
- test03();
- cout<
- test04();
- cout<
- test05();
- cout<
- test06();
- cout<
- test07();
- cout<
- test08();
- cout<
- test09();
- cout<
- system("pause");
- return 0;
- }
-
相关阅读:
Android 沉浸式状态栏(全透明状态栏)全适配方案。解决透明状态栏后依然有半透明灰色问题。
成功解决“IndexError: queue index out of range”错误的全面指南
第2-4-5章 规则引擎Drools高级语法-业务规则管理系统-组件化-中台
23.2 微服务SpringCloud基础实战(❤❤❤)
1. 微服务之Eureka服务注册发现
Oracle客户端工具安装(PL/SQL Developer 和 instantclient)小记
【Go】令牌桶限流算法
【算法|动态规划No.32 | 完全背包问题】完全背包模板题
【MySQL 系列】在 CentOS 上安装 MySQL
数据结构与算法-二分查找
-
原文地址:https://blog.csdn.net/qq_50934329/article/details/139761180