C++中级学习笔记

1.内存分区模型:

C++程序在执行时,将内存大方向划分为四个区域

(1)代码区:存放函数体的二进制代码,由操作系统进行管理

(2)全局区:存放全局变量和静态变量以及变量

(3)栈区:由编译器自动分配释放,存放函数的参数值,局部变量等

(4)堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

四区的意义:不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程

在程序运行前:

  生成了exe可执行程序,未执行该程序前分为两个区域

  代码区:

         存放CPU执行的机器指令

         代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可

         代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令

  全局区:

         全局变量和静态变量存放在此

         全局区还包含了常量区,字符串常量和其他常量也存放在此

         该区域的数据在程序结束后由操作系统释放 

  栈区:

          由编译器自动分配释放,存放函数的参数值,局部变量等

          注意事项:不要返回局部变量的地址

          形参数据也会放在栈区

  堆区:

          由程序员分配释放,若程序员不释放,程序结束时由操作系统回收

          在C++中主要利用new在堆区开辟数据

#include<iostream>
using namespace std;int* func()
{//利用new关键字,将数据开辟到堆区int* p = new int(10);return p;
}
//这里函数中的p被释放之前,把地址传给了main中的P,以访问堆区的10
int main()
{//在堆区开辟数据int* p = func();//10 10 地址cout << *p << endl;cout << *p << endl;cout << &p << endl;system("pause");return 0;
}

  new操作符:

#include<iostream>
using namespace std;int* func()
{//在堆区创建整型数据//new返回的是 该数据类型的指针int* p = new int(10);return p;
}
void test01()
{int* p = func();cout << *p << endl;cout << *p << endl;cout << *p << endl;//堆区的数据由程序员管理//利用关键字delete释放delete p;//cout << *p << endl;该操作会报错,内存已经被释放
}
//利用new开辟堆区的数组
void test02()
{//创建10个整型的数组,返回数组的首元素地址int *arr =new int[10];//arr就变成了数组名arr[1] = 1;//释放数组需要加一个中括号delete[]arr;
}
int main()
{test01();system("pause");return 0;
}

2.引用

基本用法:

#include<iostream>
using namespace std;
//引用:给变量起别名
//语法:数据类型 &别名 = 原名;(数据类型得一样)
int main()
{int a = 10;int& b = a;cout << a << endl;cout << b << endl;b = 20;cout << a << endl;cout << b << endl;system("pause");return 0;
}

 注意事项:

(1)引用必须初始化

(2)引用一旦初始化后,就不可以更改

引用作函数传递参数:

#include<iostream>
using namespace std;
void func(int& a, int& b)
{int num = a;a = b;b = num;
}
int main()
{int a = 0;int b = 10;func(a, b);//引用传递,形参会修饰实参cout << a << endl;cout << b << endl;system("pause");return 0;
}

引用做函数返回值:

#include<iostream>
using namespace std;
//引用作函数返回值
//1.不要返回局部变量的引用
int& test01()
{static int a = 10;//静态变量放在全局区return a;
}
int main()
{int &num = test01();cout << num << endl;cout << num << endl;test01() = 1000;//如果函数的返回值是引用,这个函数调用可以作为左值cout << num << endl;cout << num << endl;system("pause");return 0;
}

引用的本质:

引用的本质是一个指针常量

常量引用:

#include<iostream>
using namespace std;
//加上const之后,值不可改,避免出现错误
void showNum(const int& a)
{cout << a << endl;
}
int main()
{//常量引用//使用场景:用来修饰形参,防止误操作//加上const之后,编译器将代码修改 int temp = 10;const int & ref =temp;//const int& ref = 10;int a = 1000;showNum(a);system("pause");return 0;
}

函数默认参数: 

#include<iostream>
using namespace std;//函数默认参数//int func(int a, int b, int c)可以这样写
//也可以下面这样写
//注意事项:
//如果在函数定义实现处写出默认值,就可以在main中省略后两个值的输入
//声明和实现处只能有一处默认值
//在函数内部不能再赋予其其他默认值
//语法: 返回值类型 函数名 (形参=默认值){}
int func(int a, int b=20, int c=30)
{return a + b + c;
}int main()
{cout << func(10, 20, 30) << endl;system("pause");return 0;
}

函数占位参数:

//函数占位参数
//返回值类型  函数名(数据类型,占位){}
//下面这个函数,使用int占在那里int还可以有默认值
void func(int a, int=10)
{cout << "this is func" << endl;}
int main()
{func(10, 10);system("pause");return 0;
}

函数重载:

//函数重载
//作用:函数名可以相同,提高复用性 
//函数重载满足条件:1 同一个作用域下 2 函数名称相同 3 函数参数类型不同 或者 个数不同 或者顺序不同
//函数的返回值不可以当作函数重载的条件
void func(long int b,int a)
{cout << "func的调用" << endl;
}void func(int a)
{cout << "func" << endl;
}
void func(long int a)
{cout << "func" << endl;
}
void func(int a,long int b)
{cout << "func" << endl;
}
int main()
{func(10);system("pause");return 0;
}

函数重载注意事项:

//1.引用作为函数重载的条件
//下面这两个这样写是被允许的 const也算不同类型的一种
void func(int& a)
{}
void func(const int& a)
{}
int main()
{//这样会调用上面的函数int a = 10;func(a);//这样会调用下面的参数//直接传入10,上面的函数不合法,传入下面的函数含有const,编译器会开辟出int t =10  int &a=t来使其合法func(10);system("pause");return 0;
}
//2.函数重载遇到默认参数
void func(int a,int b=10)
{}
void func(int a)
{}
int main()
{func(10);//这样会出现歧义,无法重载return 0;
}

类和对象

c++面向对象的三个特性:封装 继承 多态   万事万物都可以作为对象,对象上有其属性和行为 

设计一个圆类,来计算其周长

//创建全局变量
double pi = 3.14;
//class代表设计一个类,后面紧跟类的名称
class Circle
{//一个类需要具备的要素;访问权限,属性,行为//访问权限
public://属性int m_r;//行为//获取圆的周长double calculator(){return 2 * pi * m_r;}};
int main()
{//通过该类,创建具体的对象(实例化)Circle c1;//给圆对象进行属性的赋值c1.m_r = 10;//使用行为(函数)进行相应操作cout << "圆的周长为:  " << c1.calculator() << endl;system("pause");return 0;
}
#include<string>;class Student
{
public://字符串使用string,同时引用相应头文件string S_name;//idint S_studentcard;void S_showname(){cout << "学生的名字是" <<S_name << endl;}void S_showcard(){cout << "学生的学号是" << S_studentcard << endl;}
};
int main()
{Student ZZM;//字符串使用双引号,单字符使用单引号ZZM.S_name = "张泽明";ZZM.S_studentcard = 2023;ZZM.S_showcard();ZZM.S_showname();system("pause");return 0;
}

设计类时,可以把属性和行为放在不同的权限下,加以控制 

//三种访问权限:public(公共权限)protected(保护权限)private(私有权限)
//public  成员类内可以访问,类外也可以访问
//protected 类内可以访问 类外不可以访问 
//private   类内可以访问 类外不可以访问
//后两个在继承里面体现出区别看,子类可以访问父类中的保护内容,不可以访问私有内容
class person
{
public:string M_name;
private:string M_passport;
protected:string M_ID;
public:void func(){//类内可以访问M_ID = "123456";M_name = "zhangsan";M_passport = "123123";}
};
int main()
{//实例化对象person p1;p1.M_name = "nima";// 这类内容是访问不到的// p1.M_ID = "goode";//函数也一样p1.func();system("pause");return 0;
}

在C++中class和struct默认的访问权限不同
struct默认权限是 public
class默认权限是  private

默认权限就是,不进行权限设置,属性和行为的访问权限

权限设置技巧

class Person
{
public://通过行为的设置进行信息的读取void setname(string name){string M_name = name;}string getname(){return M_name;}private://将属性放置在私有权限内string M_name;string M_car;string M_id;
};

 函数传入一个实例的格式

bool func(cube& c)
{

}

构造函数和析构函数:

//构造函数和析构函数是为了完成对象的初始化和清理操作
//如果我们不提供,编译器会自动提供(空实现)
//对象的初始化和清理
class person
{//1.构造函数,对象的初始化操作//没有返回值 不用写void//函数名与类名相同//构造函数可以有参数,可以发生重载//创建对象时,构造函数会自动调用,且只调用一次person(){}//2.析构函数 进行清理操作//没有返回值,不写void//函数名与类名相同 在名称前加上~//析构函数不存在参数,不能发生重载//对象在销毁前 会自动调用析构函数,而且只会调用一次~person(){}//system("pause")就是在这一步停止的意思
};

构造函数的分类和调用

//构造函数:
//两种分类方式:
//按参数分为:有参构造和无参构造 
//按类型分为:普通构造和拷贝构造
//三种调用方式:
//括号法 显示法 隐式转换法//分类
class person
{
public://构造函数person()//无参{}person(int a)//有参{}//拷贝构造函数person(const person &p){}//析构函数~person(){}
};
//构造函数的调用
int main()
{//1.括号法person p1;//无参person p2(10);//有参person p3(p2);//拷贝函数//注意事项,调用无参构造函数时,不要加()因为会被认为是一个函数声明//2.显示法person p4;person p5 = person(10);//有参person p6 = person(p5);//拷贝构造person(10);//匿名对象,执行此行之后,系统会立刻回收该对象//注意事项:不要利用拷贝构造函数初始化匿名对象,因为其相当于进行实例化//3.隐式转换法person p7 = 10;//相当于 person p7 = person(10);system("pause");return 0;
}

拷贝函数调用时机     

//通常有三种调用情况
class person
{
public:int M_age;person(){cout << "无参构造函数调用" << endl;}person(int a){cout << "有参构造函数调用" << endl;}person(const person& p){cout << "拷贝构造函数调用" << endl;}~person(){cout << "析构函数调用" << endl;}
};
//1.使用一个已经创建完毕的对象来初始化一个新对象
void test01()
{person p1 (20);person p2(p1);cout << p2.M_age << endl;
}
//2.值传递的方式给函数参数传值
void work(person p)
{}
void test02()
{person p;//这里调用一个拷贝函数,创建新的数据传入workwork(p);
}
//3值方式返回局部对象
person work2(person p)
{person p1;//调用拷贝函数,返回局部变量的值return p1;
}

构造函数的调用规则:

//默认情况下,编译器会给一个类添加三个函数
//1.默认构造函数(无参,函数体为空)
//2.默认析构函数(无参,函数体为空)
//3.默认拷贝构造函数,对属性进行值拷贝
//构造函数调用规则:
//如果用户定义有参构造函数,编译器不再提供默认无参构造函数,但是会提供默认拷贝函数(没有默认构造函数,调用报错)
//如果用户定义拷贝构造函数,编译器不会再提供其他构造函数(同理)

深拷贝与浅拷贝 

//浅拷贝:简单的拷贝赋值操作
//深拷贝:在堆区重新申请空间,进行拷贝操作
class person
{
public:person(){cout << "无参构造函数调用" << endl;}person(int age, int height){m_age = age;int* m_height = new int(height);cout << "有参构造函数调用" << endl;}person(const person& p){m_age = p.m_age;//m_height = p.m_height;编译器实现这行代码的时候,会导致堆区数据被重复释放,所以要重新申请重新使用int m_height = new int(*p.m_height);}~person(){//析构代码,将堆区开辟数据做释放操作if (m_height!=NULL){delete m_height;m_height = NULL;}}int m_age;int* m_height;
};

 初始化列表

//c++的初始化列表
class person
{
public:person(int a, int b, int c) :m_a(a), m_b(b), m_c(c){}int m_a;int m_b;int m_c;
};

 类对象作为类成员 

//类对象作为类成员
//构造函数:先调用成员的构造函数
//析构函数:先调用自身的析构函数
class phone
{
public:phone(string pname){p_name = pname;}string p_name;
};
class person
{
public://这里类似于隐式转换 phone p = p_name;person(string age, string p_name) :m_age(age), p(p_name){}int m_age;phone p;
};

 静态成员:

class person
{
public://静态成员//所有成员使用一个数据//编译时就分配内存//类内声明,类外初始化static int m_A;//静态成员同样具有访问权限
private:static int m_b;
};
//类外初始化 person:: 代表person下的成员
int person::m_A = 10;
int person::m_b = 20;
void test01()
{//静态成员的两种访问方式//通过对象进行访问person p;cout << p.m_A << endl;//通过类进行访问cout << person::m_A << endl;
}

 静态函数

//静态函数
//所有对象共享一个函数
//静态函数只能访问静态成员变量
class person
{//静态函数同样存在权限访问问题
public:static void func(){m_a = 20;//m_b = 20;不能访问该变量}static int m_a;int m_b;
};
int person::m_a = 10;
void func()
{//两种访问方式person p;p.func();//类名访问person::func();
}

成员变量和成员函数分开存储:

class person
{//空对象大小是1//c++编译器会给每个空对象分配一个字节空间,为了区分空对象占内存的位置//非静态成员变量属于类上int m_a;//静态成员变量不属于类上static int m_b;//非静态成员函数不属于类上void func(){}//静态成员函数不属于类上static void func(){}
};
int person::m_b = 10;
void test01()
{person p;cout << sizeof(p) << endl;
}int main()
{test01();system("pause");return 0;
}

this指针:

//this指针的作用(每个非静态成员函数都有,不用定义直接调用)
//1.解决名称冲突,当形参和变量名称一样时
class person
{
public:person(int age){//this指向的是被调用成员函数所属的对象,就是创建的person pthis->age = age;}//这里使用person的引用才能对创建的对象进行数据修改,不然就是简单的数据拷贝不能叠加person& addage(person p){this->age += p.age;//返回对象本身使用*thisreturn *this;}int age;
};
//2.返回对象本身用*this
void test01()
{person p1(10);person p2(10);//链式编程思想p1.addage(p2).addage(p2).addage(p2);}

空指针访问成员函数:

class person
{
public:void func(){//一般这里会隐形地给出this->m_age,因此使用空指针指向这个函数就会出现问题//使用if判断一下,为空就直接returncout << m_age << endl;}int m_age=18;
};
void test01()
{person *p=NULL;p->func();
}
int main()
{test01();return 0;
}

常函数:

class person
{//const本质上是修饰的this指针常量,使得指针常量指向的值也不能修改void func()const{this->m_a = 10;this->m_b = 10;}int m_a;mutable int m_b;//被mutable修饰的量可以在常函数中进行修改
};

常对象:

void test01()
{//常对象不能修改成员属性//mutable修饰的可以修改const person p1;//常对象不能调用普通成员函数,能调用常函数
}

全局函数作友元:

//友元使对象可以访问private的属性数据
class Building
{//friend 放在函数前面friend void test01(Building* B);
public:string livingroom;
private:string bedroom;
public:Building(){livingroom = "kt";bedroom = "ws";}};
void test01(Building *B)
{cout << B->livingroom << endl;cout << B->bedroom << endl;
}

 类作友元:

class Building
{friend class goodgay;
public://在类外写函数,类内的函数就不能有函数体包括大括号{}Building() ;string livingroom;
private:string bedroom;
};
class goodgay
{
public:goodgay() ;void visit() ;
private:Building* building;
};
Building::Building()
{livingroom = "keting";bedroom = "woshi";
}
goodgay::goodgay()
{building = new Building;
}
//注意类外写函数的格式
void goodgay::visit()
{cout << building->bedroom<<endl;cout << building->livingroom<<endl;
}
void test01()
{goodgay g1;g1.visit();
}
int main()
{test01();system("pause");return 0;
}

 成员函数作友元:

friend goodgay::visit();

运算符重载的格式实际上就是函数的格式再稍微改变一下

加号运算符重载:

//运算符重载:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
//运算符重载也能发生函数重载
//1.成员函数作运算符重载
class person
{
public:person(int a, int b){m_A = a;m_B = b;}person operator+(person& p){this->m_A += p.m_A;this->m_B += p.m_B;return *this;}int m_A ;int m_B ;
};
//2.全局函数作运算符重载
person operator+(person& p1, person& p2)
{person temp(0,0);temp.m_A = p1.m_A + p2.m_A;temp.m_B = p1.m_B + p2.m_B;
}
void test01()
{person p1(10, 10);person p2(10, 10);person p3(0, 0);p3 = p1 + p2;cout << p3.m_A << endl << p3.m_B<<endl;}
int main()
{test01();system("pause");return 0;
}

移位运算符重载:

//cout是ostream类的一个对象
//不能使用成员函数进行移位运算符重载,因为产生不了相应的效果
class person
{
public:friend ostream& operator<<(ostream& cout, person& p);person(int a,int b){m_a = a;m_b = b;}
private:int m_a;int m_b;
};
//返回值为ostream&,符合链式编程思想
ostream& operator<<(ostream& cout, person& p)
{cout << p.m_a << p.m_b;return cout;
}
void test01()
{person p1(10, 10);cout << p1 << endl;
}

递增运算符重载:

//成员函数实现递增运算符重载
class intage
{friend ostream& operator<<(ostream& cout, intage i);
public:intage(int a){m_num = a;}//前置递增//必须使用intage&,不然就会出问题intage& operator++(){m_num++;return*this;}//占位参数实现后置递增,加上一个int代表后置递增//这里必须使用intage,因为返回的temp是局部变量,会被释放掉,不过还是会出问题intage operator++(int){int temp = m_num;m_num++;return temp;}private:int m_num;
};
//全局函数实现<<重载
ostream& operator<<(ostream&cout,intage i)
{cout << i.m_num;return cout;
}
void test01()
{intage in = 10;cout << ++(++in) << endl;cout << in << endl;cout << (in++)++<< endl;cout << in<< endl;
}
int main()
{test01();system("pause");return 0;
}

赋值运算符重载:

//c++编译器会给一个类添加一共四个函数
//默认构造函数,默认析构函数,默认拷贝构造函数
//赋值运算符 operator=,对属性进行值拷贝
//可以解决浅拷贝导致的指针重复释放的问题

关系运算符重载(大于 小于 不等于 等于==)

跟前几个差不多

函数调用运算符重载,就是()

在类中重载的(),被称为仿函数,也跟上面的差不多

继承:

利用继承,可以减少重复代码

//继承语法:class 子类:继承方式 父类
class base
{
public:void b(){cout << 123 << endl;}
};
class child :public base
{};

 继承方式:

子类的对象模型:

class base
{
public:int m_a;//private仍然被继承下来,但是被隐藏,没法调用
private:int m_b;
protected:int m_c;};
class son :public base
{
public:int m_d;
};
void test01()
{//结果是16,子类会继承父类中的所有数据cout << sizeof(son) << endl;
}
int main()
{test01();system("pause");return 0;
}

构造和析构的顺序:

先构造父类,再构造子类,析构相反

继承中,同名成员处理方式 

class base
{
public:void func() {};void func(int a) {cout << a << endl;};int m_a;
};
class son :public base
{
public:void func() {};int m_a;
};
void test01()
{son s;//调用子类,直接调用s.m_a;s.func();//调用父类,就加作用域即可s.base::func(100);s.base::m_a;
}
int main()
{test01();system("pause");return 0;
}

同名静态成员的处理方式:

//同名静态成员属性
class base
{
public:static int m_a;
};
int base::m_a = 100;
class son :public base
{
public:static int m_a;
};
int son::m_a = 50;
void test01()
{//1.通过作用域访问//2.通过类名进行访问cout << son::m_a << endl;cout << son::base::m_a << endl;//静态成员函数也一样
}

继承的语法:

//多继承
class son :public base1, public base2
{};

菱形继承:

两个类同时继承自一个类,再同时继承给一个子类,那么该子类对于第一个类的数据继承了两份

class animal
{
public:int m_a;
};
//利用虚继承解决菱形继承问题
//虚继承,继承一个指针列表,指向该数据(大概)
class sleep:virtual public animal{};
class tuo:virtual public animal{};
class sleeptuo:public sleep,public tuo{};
void test01()
{sleeptuo st;//不会报错st.m_a;
}

 多态:

//静态多态:函数重载 运算符重载属于静态多态
//动态多态:派生类和虚函数实现运行时多态
//二者区别:
//静态多态:函数地址早绑定 编译阶段确定函数地址
//动态多态:函数地址晚绑定 运行阶段确定函数地址
//多态满足条件:1.有继承关系2.子类重写父类中的虚函数
//多态使用条件:父类指针或引用指向子类对象
class animal
{public://添加virtual使地址晚绑定,传入参数之后再绑定,使speak处于多种状态virtual void speak(){cout << 1;}
};
class cut :public animal
{
public:void speak(){cout << 2;}
};
class dog :public animal
{
public:void speak(){cout << 3;}
};
void dospeak( animal& animal)
{animal.speak();
}
void test()
{cut c;dospeak(c);dog d;dospeak(d);
}
int main()
{test();system("pause");return 0;
}

 多态实现计算机类

#include<iostream>
using namespace std;
#include<string>
//利用多态实现计算机类
// 开闭原则:多扩展进行开放,对修改进行关闭
//多态的好处:
//1.组织更加清晰
//2.可读性强
//3.利于前期和后期的维护
//创建一个计算机的抽象类
class AbstrateCalcultor
{
public:virtual	int getResult(){return 0;}int Num1=0;int Num2=0;
};
//加法类
class AddCalcultor :public AbstrateCalcultor
{int getResult(){return Num1 + Num2;}
};
//减法类
class SubCalcultor :public AbstrateCalcultor
{int getResult(){return Num1 - Num2;}
};
//乘法类
class MutiCalcultor :public AbstrateCalcultor
{int getResult(){return Num1 * Num2;}
};
void test01()
{AbstrateCalcultor* abs = new AddCalcultor;abs->Num1 = 1;abs->Num2 = 2;cout << abs->Num1 << "+" << abs->Num2 << "=" << abs->getResult() << endl;
}
int main()
{test01();system("pause");return 0;
}

 纯虚函数和抽象类

class base
{
public://类中只要有一个纯虚函数,就被称为抽象类//纯虚函数virtual void func() = 0;//抽象类的特点://1.无法实例化对象//2.子类必须重写父类中的纯虚函数,否则也无法实例化对象
};
class son :public base
{
public:virtual void func(){cout << "abs" << endl;}
};

 虚析构和纯虚析构

//虚析构和纯虚析构
//为了解决父类指针释放子类对象的问题
//子类出现开辟数据然后释放的操作时需要
//存在纯虚析构函数的类也称为抽象类
class Animal
{
public:virtual void speak() = 0;Animal(){cout << 1 << endl;}//虚析构virtual ~Animal(){cout << 2 << endl;}//纯虚析构,需要在外面实现一下virtual ~Animal() = 0;
};
Animal::~Animal()
{}
class Cat :public Animal
{
public:virtual void speak(){cout << *Name << "在说话" << endl;}Cat(string C_Name){Name = new string(C_Name);cout << 3 << endl;}~Cat(){cout << 4 << endl;if (Name != NULL){delete Name;Name = NULL;}}string* Name;
};
void test01()
{Animal* an = new Cat("name");an->speak();//delete的是父类指针,无法进入子类虚构代码,因此使用虚析构delete an;
}
int main()
{test01();system("pause");return 0;
}
//析构函数的调用时机:创建实例向其中传值或者其他实例的时候
//析构函数的调用时机:销毁实例或者数据的时候

文件操作

//程序运行时产生的数据属于临时数据,运行结束就会被释放掉,通过文件可以将数据永久化
//使用文件要包含头文件文件流<fstream>
//文件类型:
//1,文本文件:以文本的ASCII形式存储
//2,二进制文件:文本以二进制形式存储,一般不能直接读取
//操作文件的三大类:
//1.ofstream 写操作
//2.ifstream 读操作
//3.fstream  读写操作

写文件:

//1.包含头文件
#include<fstream>
//2.创建流对象(写操作)
ofstream ofs;
void test()
{//3.打开文件ofs.open("666.txt", ios::out);//4.写文件ofs << "123" << endl;ofs << "456" << endl;ofs << "789" << endl;//5.关闭文件ofs.close();
}
int main()
{test();system("pause");return 0;
}

读文件:

#include<fstream>
//读文件
ifstream ifs;
void test()
{ifs.open("666.txt", ios::in);//判断是否读取成功if (!ifs.is_open()){cout << "读取失败" << endl;}//三种读取数据的方式// 一行一行地读的//char buf[1024] = { 0 };while (ifs >> buf){cout << buf << endl;cout << 1;}//char buf[1024] = { 0 };while (ifs.getline(buf, sizeof(buf))){cout << buf << endl;cout << 1;}//string buf;while (getline(ifs, buf)){cout << buf << endl;}//关闭文件ifs.close();
}
int main()
{test();system("pause");return 0;
}

 二进制文件:

 写文件

#include<fstream>
class Person
{
public:char Name[64];int Age;
};
//创建流对象和打开文件可以写在同一个地方
ofstream ofs("write.txt", ios::out | ios::binary);
void test()
{Person p = { "张三",18};//写文件ofs.write((const char*)&p,sizeof(&p));ofs.close();}
int main()
{test();return 0;
}

读文件 

#include<fstream>
class Person
{
public:char Name[64];int Age;
};
ifstream ifs;
void test()
{Person p;ifs.open("write.txt", ios::in | ios::binary);//判断是否读取成功if (!ifs.is_open()){}ifs.read(( char*) & p, sizeof(Person));cout <<p.Name << endl << p.Age << endl;
}
int main()
{test();system("pause");return 0;
}

 

 

 

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/13092.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

基于深度卷积二元分解网络的齿轮和轴承故障特征提取方法

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

Qml-Timeline的使用

Qml-Timeline的使用 Timeline的概述 Timeline&#xff1a;根据关键帧及其缓和曲线指定项目的值属性currentFrame : double&#xff1a;当前帧 属性enabled : bool&#xff1a;是否使能时间线 属性endFrame : double&#xff1a;结束帧值 属性startFrame : double&#xff1a;…

Vue指令详解——以若依框架中封装指令为例分析

自定义指令 在Vue.js中&#xff0c;自定义指令提供了一种非常灵活的方式来扩展Vue的功能。以下是对Vue中自定义指令的详细解释&#xff1a; 一、自定义指令的基本概念 自定义指令允许开发者直接对DOM元素进行低层次操作&#xff0c;而无需编写大量的模板或者JavaScript代码。…

基于微信小程序的大学生心理健康测评系统设计与实现,LW+源码+讲解

摘 要 随着移动互联网的发展&#xff0c;理论和技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对高校教师成果信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性…

一步到位:用Python实现PC屏幕截图并自动发送邮件,实现屏幕监控

软件测试资料领取&#xff1a;[内部资源] 想拿年薪40W的软件测试人员&#xff0c;这份资料必须领取~ 软件测试面试刷题工具&#xff1a;软件测试面试刷题【800道面试题答案免费刷】 在当前的数字化世界中&#xff0c;自动化已经成为我们日常生活和工作中的关键部分。它不仅提…

jwt用户登录,网关给微服务传递用户信息,以及微服务间feign调用传递用户信息

1、引入jwt依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency> 2、Jwt工具类&#xff0c;生成token以及解析token package com.niuniu.gateway.uti…

基于Multisim数字电子秒表计时器电路(含仿真和报告)

【全套资料.zip】数字电子秒表电路Multisim仿真设计数字电子技术 文章目录 功能一、Multisim仿真源文件二、原理文档报告资料下载【Multisim仿真报告讲解视频.zip】 功能 数字电子秒表电路 1.秒表由3个显示器显示&#xff0c;其中显示分辩率为1s&#xff0c;计时范围是6分59…

手把手教你30秒下载Typora通用版(mac、win适用)

话不多说&#xff01; 1、去官网选择mac版本下载安装&#xff1a; typora下载 然后打开 typora 包内容找到 / Applications / Typora . app / Contents / Resources / TypeMark / 用编辑器打开上面文件夹&#xff0c; vscode 示例&#xff1a; 找到 page - dist / static / …

鸿蒙ZRouter动态路由框架—生命周期管理能力

文章目录 基本使用(单个页面生命周期&#xff09;页面的全局生命周期监听工作流程图源码 ZRouter从1.1.0版本开始支持生命周期函数管理能力&#xff0c;主要有以下特点&#xff1a; 不影响你原有的生命周期业务逻辑&#xff0c;对NavDestination页面保持着零侵入性&#xff0c;…

英伟达GB200、B200、H200、H100、A100、4090的参数对比

以下是英伟达GB200、B200、H200、H100、A100、4090的参数对比&#xff1a; 型号 架构 制造工艺 晶体管数量 显存类型 显存容量 显存带宽 CUDA核心数 其他主要特性 GB200 Blackwell 未知 2个B200 GPU共4160亿 HBM3e 每颗B200 GPU 192GB&#xff08;总384GB&#x…

IntelliJ+SpringBoot项目实战(五)--配置Druid在线监控数据库

阿里的Druid插件有可视化监控数据库性能的界面。在SpringBoot中集成Druid后&#xff0c;可以进入可视化Html界面监控数据库运行情况。本文先介绍Druid的管理界面&#xff0c;然后在介绍Druid的详细配置。 首先访问http://localhost:8001/druid/ ,打开登录页面&#xff1a; 然后…

2024年小红书代运营公司推荐:品牌种草新阵地

2024年小红书代运营公司推荐&#xff1a;品牌种草新阵地 随着今年双十一的落幕&#xff0c;各大平台通过各具特色的活动实现了优异的表现&#xff0c;标志着国内电商市场全面进入了全域运营的新时代。未来&#xff0c;电商行业将呈现“货架电商内容电商”相结合的趋势。小红书作…

什么是闰秒?

闰秒概念是 1972年提出的&#xff0c;之所以有这个概念&#xff0c;主要是因为由于潮汐等自然现象的影响&#xff0c;地球的自转速度并不是恒定的。 所以&#xff0c;每隔一段时间世界标准时间「协调世界时&#xff08;UTC&#xff09;」会依据地球围绕太阳运动计算的「世界时…

PySide6百练成真(9)

资源的加载 给控件加上图标 1.内置图标 2.自定义资源文件 3.Rcc的使用(基于designer) 4.如果获取资源文件 rcc的使用,基于xml文件 内置图标 from PySide6.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget, QLineEdit, QToolBox, QMainWindow, QPushButton,QSt…

cmake vscode

cmake_minimum_required(VERSION 3.20.0) project(my_hello) //指定项目 set(CMAKE_CXX_STANDARD 11) //指定c的版本 include_directories( P R O J E C T S O U R C E D I R / i n c l u d e ) / / 包含头文件的目录 / / 指定可执行文件生成目录 s e t ( E X E C U T A B L E…

李耳著《老子》与董仲舒著《道德经》有何区别?

马王堆帛书《老子》的发现&#xff0c;确实为研究《道德经》提供了更为接近原始的版本&#xff0c;其内容与传世本存在诸多不同之处&#xff0c;这些差异不仅体现在文字和篇章结构上&#xff0c;更在于思想内涵和哲学意蕴的深度。以下是具体分析&#xff1a; 版本命名&#xff…

5. ARM_指令集

概述 分类 汇编中的符号&#xff1a; 指令&#xff1a;能够编译生成一条32位机器码&#xff0c;并且能被处理器识别和执行伪指令&#xff1a;本身不是指令&#xff0c;编译器可以将其替换成若干条指令伪操作&#xff1a;不会生成指令&#xff0c;只是在编译阶段告诉编译器怎…

游戏行业使用高防独立IP有什么好处?

独立的IP就是您的虚拟主机自己有一个单独的IP地址&#xff0c;这样&#xff0c;您的用户除了记住您的域名外&#xff0c;在浏览器的地址栏敲入您的IP地址也能访问到您的网站。如果没有独立IP的话&#xff0c;别人要访问您的网站只能敲入域名才行。 而高防ip是指高防机房所提供的…

Android ANR分析总结

1、ANR介绍 ANR&#xff08;Application Not Responding&#xff09;指的是应用程序无响应&#xff0c;当Android应用程序在主线程上执行长时间运行的操作或阻塞I/O操作时发生。这可能导致应用程序界面冻结或无法响应用户输入。 1、Service ANR&#xff1a;前台20s&#xff0…

【comfyui教程】comfyui攻略:故障报错应对指南!

前言 ComfyUI的常见故障和解决&#xff0c;赶紧收藏起来&#xff0c; 在探索ComfyUI的曲折旅途中&#xff0c;最让人心生畏惧的莫过于那漫天的红色方框和层出不穷的报错信息。它们如同不息的风暴&#xff0c;一波未平&#xff0c;一波又起&#xff0c;令无数热忱的初学者在这…