Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
C++期末复习超详细总结知识点(期末冲刺),希望能够帮助你!!!。
更新时间:2022年8月21日
pdf版下面评论置顶有链接
c++面向对象程序设计课后习题答案(谭浩强版)
与C++题库
刷题部分!更新一下:习题和笔记pdf版均在置顶评论,自取
学校考试一般比较简单,更多在于概念和语法的考察,包括一些细节知识点在选择判断等。
是根据老师的PPT与自己所学进行总结的,基本不涉及偏难怪知识点,重点是为了期末考试。
全文长10400多字,基本可以囊括90%的考试知识点
个人感觉知识掌握了就是多做做习题,毕竟考试偏应试,想提高分请一定多做题!!!!
考试加油!!!!
只是知识点总结,请一定要理解记忆,由于博主这学期也要考,时间有限,难免有不全有误之处,望谅解。
10.时间充足者可以按如下顺序学习,更有利于掌握。
.cpp
作为后缀的作用:整型变量表示的是整数类型的数据
作用:利用sizeof关键字可以统计数据类型所占内存大小
作用:用于表示小数
浮点型变量分为两种:
一个整型常量可以用3种不同的方式表示:
一个浮点数可以用两种不同的方式表示:
作用:字符型变量用于显示单个字符
语法:char ch = 'a';
注意1:在显示字符型变量时,用单引号将字符括起来,不要用双引号
注意2:单引号内只能有一个字符,不可以是字符串
C和C++中字符型变量只占用1个字节。
字符常量只能包括一个字符,如′AB′
是不合法的
字符常量区分大小写字母,如′A′
和′a′
是两个不同的字符常量
字符型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元
作用:用于表示一串字符
两种风格
char 变量名[] = "字符串值"
char str1[] = "hello world";
注意:C风格的字符串要用双引号括起来
string 变量名 = "字符串值"
string str = "hello world";
注意:C++风格字符串,需要加入头文件==#include<string>==
字符串常量为双引号
常考:字符串 "abc"
在内存中占几个字节?
答:占4个字节,而不是3个字节,编译系统会在字符串最后自动加一个′\0′
作为字符串结束标志。但′\0′
并不是字符串的一部分,它只作为字符串的结束标志
常考: 字符串常量″abc\n″
包含几个字符?
答:不是5个而是4个字符,其中“\n”
是一个转义字符,但它在内存中占5个字节
作用:布尔数据类型代表真或假的值
bool类型只有两个值:
bool类型占1个字节大小
关键字:cin、cout
语法: cin >> 变量1>>变量2>>....>>变量n
、cout<<表达式1<<表达式2<<...<<表达式n
cout<<a,b,c; //错误,不能一次插入多项 cout<<a+b+c; //正确,这是一个表达式,作为一项 cin>>a>>b>>c>>d;
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
+ | 正号 | +3 | 3 |
- | 负号 | -3 | -3 |
+ | 加 | 10 + 5 | 15 |
- | 减 | 10 - 5 | 5 |
* | 乘 | 10 * 5 | 50 |
/ | 除 | 10 / 5 | 2 |
% | 取模(取余) | 10 % 3 | 1 |
++ | 前置递增 | a=2; b=++a; | a=3; b=3; |
++ | 后置递增 | a=2; b=a++; | a=3; b=2; |
– | 前置递减 | a=2; b=–a; | a=1; b=1; |
– | 后置递减 | a=2; b=a–; | a=1; b=2; |
注意:
常考:
前置后置运算符单独使用没有什么区别
前置递增先对变量进行++,再计算表达式
后置递增先计算表达式,后对变量进行++
请详细看下方代码并理解
//递增 int main() {
//后置递增 int a = 10; a++; //等价于a = a + 1 cout << a << endl; // 11 //前置递增 int b = 10; ++b; cout << b << endl; // 11 //区别 //前置递增先对变量进行++,再计算表达式 int a2 = 10; int b2 = ++a2 * 10; cout << b2 << endl; //110 //后置递增先计算表达式,后对变量进行++ int a3 = 10; int b3 = a3++ * 10; cout << b3 << endl; //100 system("pause"); return 0; }
作用:用于将表达式的值赋给变量
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
= | 赋值 | a=2; b=3; | a=2; b=3; |
+= | 加等于 | a=0; a+=2; | a=2; |
-= | 减等于 | a=5; a-=3; | a=2; |
*= | 乘等于 | a=2; a*=2; | a=4; |
/= | 除等于 | a=4; a/=2; | a=2; |
%= | 模等于 | a=3; a%2; | a=1; |
作用:用于表达式的比较,并返回一个真值或假值
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
== | 相等于 | 4 == 3 | 0 |
!= | 不等于 | 4 != 3 | 1 |
< | 小于 | 4 < 3 | 0 |
> | 大于 | 4 > 3 | 1 |
<= | 小于等于 | 4 <= 3 | 0 |
>= | 大于等于 | 4 >= 1 | 1 |
注意:C和C++ 语言的比较运算中, “真”用数字“1”来表示, “假”用数字“0”来表示。
作用:用于根据表达式的值返回真值或假值
运算符 | 术语 | 示例 | 结果 |
---|---|---|---|
! | 非 | !a | 如果a为假,则!a为真; 如果a为真,则!a为假。 |
&& | 与 | a && b | 如果a和b都为真,则结果为真,否则为假。 |
|| | 或 | a || b | 如果a和b有一个为真,则结果为真,二者都为假时,结果为假。 |
!
非为三者中运算符最高的作用: 通过三目运算符实现简单的判断
语法:表达式1 ? 表达式2 :表达式3
如果表达式1的值为真,执行表达式2,并返回表达式2的结果;
如果表达式1的值为假,执行表达式3,并返回表达式3的结果。
作用:执行多条件分支语句
语法:
switch(表达式) {
case 结果1:执行语句;break; case 结果2:执行语句;break; ... default:执行语句;break; }
作用:满足循环条件,执行循环语句
语法: while(循环条件){ 循环语句 }
解释:只要循环条件的结果为真,就执行循环语句
作用: 满足循环条件,执行循环语句
语法: do{ 循环语句 } while(循环条件);
注意:与while的区别在于do…while会先执行一次循环语句,再判断循环条件(这里常考两者区别,记住无论怎样,do…while都会必然执行一次循环语句)
int main() {
for (int i = 0; i < 10; i++) {
cout << i << endl; } system("pause"); return 0; }
作用: 用于跳出选择结构或者循环结构
作用:在循环语句中,跳过本次循环中余下尚未执行的语句,继续执行下一次循环
注意:continue并没有使整个循环终止,而break会跳出循环
数组:所谓数组,就是一个集合,存放相同类型的数据元素
一维数组定义的三种方式:
数据类型 数组名[ 数组长度 ];
(常用,了解其余两种即可)数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};
数据类型 数组名[ ] = { 值1,值2 ...};
int score[10]; int score2[10] = {
100, 90,80,70,60,50,40,30,20,10 }; int score3[] = {
100,90,80,70,60,50,40,30,20,10 };
int a[10]={
0,1,2,3,4,5,6,7,8,9};
int a[10]={
0,1,2,3,4};
int a[10]={
1,1,1,1,1,1,1,1,1,1}; int a[10]={
1*10}; // 错误写法,不能给数组整体赋初值
int a[5]={
1,2,3,4,5}; // 可以写成 int a[]={
1,2,3,4,5};
二维数组定义的四种方式:
数据类型 数组名[ 行数 ][ 列数 ];
数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
int arr[2][3]; int arr2[2][3] = {
{
1,2,3}, {
4,5,6} }; int arr3[2][3] = {
1,2,3,4,5,6 }; int arr4[][3] = {
1,2,3,4,5,6 };
定义:
char c[10] = {
′I′,′ ′,′a′,′m′,′ ′,′h′,′a′,′p′,′p′,′y′};
赋值:
只能对字符数组的元素赋值,而不能用赋值语句对整个数组赋值
char c[5]; c={
′C′,′h′,′i′,′n′,′a′}; //错误,不能对整个数组一次赋值 C[0]=′C′; c[1]=′h′; c[2]=′i′; c[3]=′n′; c[4]=′a′; //对数组元素赋值,正确 int a[5],b[5]={
1,2,3,4,5}; a=b; //错误,不能对整个数组整体赋值 a[0]=b[0]; //正确,引用数组元素
字符串连接函数 strcat
字符串复制函数 strcpy
字符串比较函数 strcmp
字符串长度函数 strlen
作用:将一段经常使用的代码封装起来,减少重复代码
函数的定义一般主要有5个步骤:
1、返回值类型
2、函数名
3、参数表列
4、函数体语句
5、return 表达式
语法:
返回值类型 函数名 (参数列表) {
函数体语句 return表达式 }
示例:定义一个加法函数,实现两个数相加
//函数定义 int add(int num1, int num2) {
int sum = num1 + num2; return sum; }
功能:使用定义好的函数
语法: 函数名(参数)
int result = add(10,20);
函数定义里小括号内称为形参,函数调用时传入的参数称为实参
例如此处的num1,num2
为形参,10,20
为实参
函数不能嵌套定义但是可以嵌套调用(常考)
//声明可以多次,定义只能一次 //声明 int max(int a, int b); int max(int a, int b); //定义 int max(int a, int b) {
return a > b ? a : b; } int main() {
int a = 100; int b = 200; cout << max(a, b) << endl; system("pause"); return 0; }
在C++中,函数的形参列表中的形参是可以有默认值的。
语法: 返回值类型 函数名 (参数= 默认值){}
int func(int a, int b = 10, int c = 10) {
return a + b + c; } //1. 如果某个位置参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值 //2. 如果函数声明有默认值,函数实现的时候就不能有默认参数 int func2(int a = 10, int b = 10); int func2(int a, int b) {
return a + b; } int main() {
cout << "ret = " << func(20, 20) << endl; cout << "ret = " << func(100) << endl; system("pause"); return 0; }
C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置
语法: 返回值类型 函数名 (数据类型){}
//函数占位参数 ,占位参数也可以有默认参数 void func(int a, int) {
cout << "this is func" << endl; } int main() {
func(10,10); //占位参数必须填补 system("pause"); return 0; }
作用:函数名可以相同,提高复用性
函数重载满足条件:
注意: 函数的返回值不可以作为函数重载的条件
//函数重载需要函数都在同一个作用域下 void func() {
cout << "func 的调用!" << endl; } void func(int a) {
cout << "func (int a) 的调用!" << endl; } void func(double a) {
cout << "func (double a)的调用!" << endl; } void func(int a ,double b) {
cout << "func (int a ,double b) 的调用!" << endl; } void func(double a ,int b) {
cout << "func (double a ,int b)的调用!" << endl; } //函数返回值不可以作为函数重载条件 //int func(double a, int b) //{
// cout << "func (double a ,int b)的调用!" << endl; //} int main() {
func(); func(10); func(3.14); func(10,3.14); func(3.14 , 10); system("pause"); return 0; }
C++中有以下五个运算符不能重载
成员访问运算符 | 成员指针访问运算符 | 域运算符 | 长度运算符 | 条件运算符 |
---|---|---|---|---|
. | .* | :: | sizeof | ?: |
重载运算符规则:
什么时候应该用成员函数方式,什么时候应该用友元函数方式?二者有何区别呢?()
operator
函数有一个参数operator
函数有两个参数“>>”
(流插入运算符)和“<<”
(流提取运算符)的函数作为友元函数或者普通函数重载,而不能将它们定义为成员函数,因为参数为两个单目运算符:只有一个操作数,如 !,-(负号),&,*,++,–
双目运算符:*,/,%,+,-,==,!=,<,>,<=,>=,&&,||
inline int max(int a,int b);
语法:
template<typename T> 函数声明或定义
解释:
template — 声明创建模板
typename — 表面其后面的符号是一种数据类型,可以用class代替
T — 通用的数据类型,名称可以替换,通常为大写字母
只适用于函数体相同、函数的参数个数相同而类型不同的情况,如果参数的个数不同,则不能用函数模板。
指针的作用: 可以通过指针间接访问内存
指针变量定义语法: 数据类型 * 变量名;
int main() {
//1、指针的定义 int a = 10; //定义整型变量a //指针定义语法: 数据类型 * 变量名 ; int * p; //指针变量赋值 p = &a; //指针指向变量a的地址 cout << &a << endl; //打印数据a的地址 cout << p << endl; //打印指针变量p //0073F8BC //0073F8BC //2、指针的使用 //通过*操作指针变量指向的内存 cout << "*p = " << *p << endl; // *p = 10 system("pause"); return 0; }
指针变量和普通变量的区别
总结1: 我们可以通过 & 符号 获取变量的地址
总结2:利用指针可以记录地址
总结3:对指针变量解引用,可以操作指针指向的内存
总结4:所有指针类型在32位操作系统下是4个字节(了解)
const修饰指针有三种情况
int main() {
int a = 10; int b = 10; //const修饰的是指针,指针指向可以改,指针指向的值不可以更改 const int * p1 = &a; p1 = &b; //正确 //*p1 = 100; 报错 //const修饰的是常量,指针指向不可以改,指针指向的值可以更改 int * const p2 = &a; //p2 = &b; //错误 *p2 = 100; //正确 //const既修饰指针又修饰常量 const int * const p3 = &a; //p3 = &b; //错误 //*p3 = 100; //错误 system("pause"); return 0; }
技巧:看const右侧紧跟着的是指针还是常量, 是指针就是常量指针,是常量就是指针常量
作用:利用指针访问数组中元素
int main() {
int arr[] = {
1,2,3,4,5,6,7,8,9,10 }; int * p = arr; //指向数组的指针 cout << "第一个元素: " << arr[0] << endl; //1 cout << "指针访问第一个元素: " << *p << endl; //1 for (int i = 0; i < 10; i++) {
//利用指针遍历数组 cout << *p << endl; p++; } system("pause"); return 0; }
作用:利用指针作函数参数,可以修改实参的值(地址传递)
//值传递 void swap1(int a ,int b) {
int temp = a; a = b; b = temp; } //地址传递 void swap2(int * p1, int *p2) {
int temp = *p1; *p1 = *p2; *p2 = temp; } int main() {
int a = 10; int b = 20; swap1(a, b); // 值传递不会改变实参 swap2(&a, &b); //地址传递会改变实参 cout << "a = " << a << endl; cout << "b = " << b << endl; system("pause"); return 0; }
int a[10]; int *p = &a[0]; // 等价于 int *p = a; *p = 1; // 等价于 a[0] = 1; *(p+1) = 2; // 等价于 a[1] = 2; // 所以 *(p+1) = a[1]; *(p+2) = a[2];
void main() {
int array[10]; // 用数组名作形参,因为接收的是地址,所以可以不指定具体的元素个数 f(array,10); } // 形参数组 f(int arr[],int n) {
.... }
void main() {
int a[10]; // 实参数组 f(a,10); } // 形参指针 f(int *x,int n) {
... }
总结:如果不想修改实参,就用值传递,如果想修改实参,就用地址传递
// 类型名 * 函数名(参数列表) int * a(int x,int y);
作用: 给变量起别名
语法: 数据类型 &别名 = 原名
int main() {
int a = 10; int &b = a; cout << "a = " << a << endl; cout << "b = " << b << endl; // 10 // 10 b = 100; cout << "a = " << a << endl; cout << "b = " << b << endl; // 100 // 100 system("pause"); return 0; }
引用必须初始化
int &c; // 错误,引用必须初始化
在声明一个引用后,不能再使之作为另一变量的引用
作用:函数传参时,可以利用引用的技术让形参修饰实参
优点:可以简化指针修改实参
//1. 值传递 void mySwap01(int a, int b) {
int temp = a; a = b; b = temp; } //2. 地址传递 void mySwap02(int* a, int* b) {
int temp = *a; *a = *b; *b = temp; } //参数:把地址传进去,用指针接收 //3. 引用传递 void mySwap03(int& a, int& b) {
int temp = a; a = b; b = temp; } //参数:别名,下面的a是上面的a的别名,用别名操作修改可原名操作修改是一样的 int main() {
int a = 10; int b = 20; // 值传递,形参不会修饰实参 mySwap01(a, b); cout << "a:" << a << " b:" << b << endl; // a:10 b:20 // 地址传递,形参会修饰实参 mySwap02(&a, &b); cout << "a:" << a << " b:" << b << endl; // a:20 b:10 // 引用传递,形参会修饰实参 mySwap03(a, b); cout << "a:" << a << " b:" << b << endl; // a:20 b:10 system("pause"); return 0; }
作用:引用是可以作为函数的返回值存在的
//数据类型后加&,相当于用引用的方式返回 int& test02() {
// 必须使用静态变量,需加 static 关键字 static int a = 20; return a; } int main(){
int& ref2 = test02(); system("pause"); return 0; }
在C++中 struct和class唯一的区别就在于 默认的访问权限不同
区别:
构造函数语法:类名(){}
(构造和析构很容易出选择题,特点要记住)
析构函数语法: ~类名(){}
~
class Person {
public: //构造函数 Person() {
cout << "Person的构造函数调用" << endl; } //析构函数 ~Person() {
cout << "Person的析构函数调用" << endl; } }; void test01() {
Person p; //在栈上的数据,test01()执行完毕后,释放这个对象 } int main() {
test01(); system("pause"); return 0; }
构造函数按参数分为: 有参构造和无参构造
调用方式:括号法
class Person {
public: //无参(默认)构造函数 Person() {
cout << "无参构造函数!" << endl; } //有参构造函数 Person(int a) {
age = a; cout << "有参构造函数!" << endl; } //析构函数 ~Person() {
cout << "析构函数!" << endl; } public: int age; }; //2、构造函数的调用 //调用无参构造函数 void test01() {
Person p; //调用无参构造函数 } //调用有参的构造函数 void test02() {
// 括号法,常用 Person p1(10); }
语法:构造函数():属性1(值1),属性2(值2)... {}
class Person {
public: 传统方式初始化 //Person(int a, int b, int c) {
// m_A = a; // m_B = b; // m_C = c; //} //初始化列表方式初始化 Person(int a, int b, int c) :m_A(a), m_B(b), m_C(c) {
} void PrintPerson() {
cout << "mA:" << m_A << endl; cout << "mB:" << m_B << endl; cout << "mC:" << m_C << endl; } private: int m_A; int m_B; int m_C; }; int main() {
Person p(1, 2, 3); p.PrintPerson(); system("pause"); return 0; }
C++类中的成员可以是另一个类的对象,我们称该成员为 对象成员
例如:
class A {
} class B {
A a; }
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员
静态成员分为:
class Person {
public: static int m_A; //静态成员变量 //静态成员变量特点: //1 在编译阶段分配内存 //2 类内声明,类外初始化 //3 所有对象共享同一份数据 private: static int m_B; //静态成员变量也是有访问权限的 }; int Person::m_A = 10; int Person::m_B = 10; void test01() {
//静态成员变量两种访问方式 //1、通过对象 Person p1; p1.m_A = 100; cout << "p1.m_A = " << p1.m_A << endl; Person p2; p2.m_A = 200; cout << "p1.m_A = " << p1.m_A << endl; //共享同一份数据 cout << "p2.m_A = " << p2.m_A << endl; //2、通过类名 cout << "m_A = " << Person::m_A << endl; //cout << "m_B = " << Person::m_B << endl; //私有权限访问不到 } int main() {
test01(); system("pause"); return 0; }
示例2:静态成员函数
class Person {
public: //静态成员函数特点: //1 程序共享一个函数 //2 静态成员函数只能访问静态成员变量 static void func() {
cout << "func调用" << endl; m_A = 100; //m_B = 100; //错误,不可以访问非静态成员变量 } static int m_A; //静态成员变量 int m_B; // private: //静态成员函数也是有访问权限的 static void func2() {
cout << "func2调用" << endl; } }; int Person::m_A = 10; void test01() {
//静态成员变量两种访问方式 //1、通过对象 Person p1; p1.func(); //2、通过类名 Person::func(); //Person::func2(); //私有权限访问不到 } int main() {
test01(); system("pause"); return 0; }
常函数:
常对象:
形式 | 含义 |
---|---|
Time const t1 | t1 是常对象,其值在任何情况下都不能改变 |
void Time::fun() const | fun 是 Time类中的常成员函数,可以引用,但不能修改本类中的数据成员 |
Time * const p | p 是指向Time对象的常指针,P的值不能改变 |
const Time *p | p是指向 Time 类常对象的指针,其指向的类对象的值不能通过指针来改变 |
Time &t1 = t; | t1是Time类对象t的引用,二者指向同一段内存空间 |
继承的好处:可以减少重复的代码
继承的语法:class 子类 : 继承方式 父类
class A : public B;
A 类称为子类 或 派生类
B 类称为父类 或 基类
继承方式一共有三种:
简单的说:
构造函数的主要作用是对数据成员初始化
派生类是不能继承基类的析构函数,也需要通过派生类的析构函数去调用基类的析构函数
继承中 先调用父类构造函数,再调用子类构造函数,析构顺序与构造相反
构造函数
单继承:一个派生类只从一个基类派生
多继承:一个派生类有两个或多个基类的称为多重继承
多态性是指具有不同功能的函数可以用同一个函数名,这样就可以用一个函数名调用不同内容的函数
多态分为两类
什么是虚函数?
virtual
声明成员函数为虚函数虚函数的作用:
虚函数的使用方法:
virtual
声明成员函数为虚函数。这样就可以在派生类中重新定义此函数,为它赋予新的功能,并能方便地被调用
virtual
C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。因此在派生类重新声明该虚函数时,可以加virtual,也可以不加,但习惯上一般在每一层声明该函数时都加virtual,使程序更加清晰
class Animal {
public: //Speak函数就是虚函数 //函数前面加上virtual关键字,变成虚函数,那么编译器在编译的时候就不能确定函数调用了。 virtual void speak() {
cout << "动物在说话" << endl; } }; class Cat :public Animal {
public: void speak() {
cout << "小猫在说话" << endl; } }; class Dog :public Animal {
public: void speak() {
cout << "小狗在说话" << endl; } }; //我们希望传入什么对象,那么就调用什么对象的函数 //如果函数地址在编译阶段就能确定,那么静态联编 //如果函数地址在运行阶段才能确定,就是动态联编 void DoSpeak(Animal & animal) {
animal.speak(); } // //多态满足条件: //1、有继承关系 //2、子类重写父类中的虚函数 //多态使用: //父类指针或引用指向子类对象 void test01() {
Cat cat; DoSpeak(cat); Dog dog; DoSpeak(dog); } int main() {
test01(); system("pause"); return 0; }
多态满足条件
纯虚函数是在声明虚函数时被“初始化”为0的函数。声明纯虚函数的一般形式是
virtual 函数类型 函数名 (参数表列) =0;
纯虚函数没有函数体
最后面的 =0
,并不表示函数返回值为0,它只告诉编译系统“老子是纯虚函数”
纯虚函数只有函数的名字而不具备函数的功能,不能被调用
凡是包含纯虚函数的类都是抽象类
一个基类如果包含一个或一个以上纯虚函数,就是抽象基类。抽象基类不能也不必要定义对象、
C++中对文件操作需要包含头文件 < fstream >
文件类型分为两种:
操作文件的三大类:
写文件步骤如下:
包含头文件
#include <fstream>
创建流对象
ofstream ofs;
打开文件
ofs.open(“文件路径”,打开方式);
写数据
ofs << “写入的数据”;
关闭文件
ofs.close();
文件打开方式:
打开方式 | 解释 |
---|---|
ios::in | 为读文件而打开文件 |
ios::out | 为写文件而打开文件 |
ios::ate | 初始位置:文件尾 |
ios::app | 追加方式写文件 |
ios::trunc | 如果文件存在先删除,再创建 |
ios::binary | 二进制方式 |
注意: 文件打开方式可以配合使用,利用|操作符
**例如:**用二进制方式写文件 ios::binary | ios:: out
示例:
#include <fstream> void test01() {
ofstream ofs; ofs.open("test.txt", ios::out); ofs << "姓名:张三" << endl; ofs << "性别:男" << endl; ofs << "年龄:18" << endl; ofs.close(); } int main() {
test01(); system("pause"); return 0; }
总结:
读文件与写文件步骤相似,但是读取方式相对于比较多
读文件步骤如下:
包含头文件
#include <fstream>
创建流对象
ifstream ifs;
打开文件并判断文件是否打开成功
ifs.open(“文件路径”,打开方式);
读数据
四种方式读取
关闭文件
ifs.close();
示例:
#include <fstream> #include <string> void test01() {
ifstream ifs; ifs.open("test.txt", ios::in); if (!ifs.is_open()) {
cout << "文件打开失败" << endl; return; } //第一种方式 //char buf[1024] = { 0 }; //while (ifs >> buf) //{
// cout << buf << endl; //} //第二种 //char buf[1024] = { 0 }; //while (ifs.getline(buf,sizeof(buf))) //{
// cout << buf << endl; //} //第三种 //string buf; //while (getline(ifs, buf)) //{
// cout << buf << endl; //} char c; while ((c = ifs.get()) != EOF) {
cout << c; } ifs.close(); } int main() {
test01(); system("pause"); return 0; }
总结:
以二进制的方式对文件进行读写操作
打开方式要指定为 ios::binary
二进制方式写文件主要利用流对象调用成员函数write
函数原型 :ostream& write(const char * buffer,int len);
参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数
示例:
#include <fstream> #include <string> class Person {
public: char m_Name[64]; int m_Age; }; //二进制文件 写文件 void test01() {
//1、包含头文件 //2、创建输出流对象 ofstream ofs("person.txt", ios::out | ios::binary); //3、打开文件 //ofs.open("person.txt", ios::out | ios::binary); Person p = {
"张三" , 18}; //4、写文件 ofs.write((const char *)&p, sizeof(p)); //5、关闭文件 ofs.close(); } int main() {
test01(); system("pause"); return 0; }
总结:
二进制方式读文件主要利用流对象调用成员函数read
函数原型:istream& read(char *buffer,int len);
参数解释:字符指针buffer指向内存中一段存储空间。len是读写的字节数
示例:
#include <fstream> #include <string> class Person {
public: char m_Name[64]; int m_Age; }; void test01() {
ifstream ifs("person.txt", ios::in | ios::binary); if (!ifs.is_open()) {
cout << "文件打开失败" << endl; } Person p; ifs.read((char *)&p, sizeof(p)); cout << "姓名: " << p.m_Name << " 年龄: " << p.m_Age << endl; } int main() {
test01(); system("pause"); return 0; }
标准输出流:cout 、cerr、clog
cerr、clog流对象都是标准错误流,都是在终端显示器上显示出错信息
标准输入流:cin、get、getline
get函数读入一个字符,getline读入一行字符
eof函数:文件结束
peek函数:peek函数的作用是观测下一个字符。
putback函数:其作用是将前面用get或getline函数从输入流中读取的字符ch返回到输入流,插入到当前指针位置,以供后面读取
ignore函数:函数作用是跳过输入流中n个字符,或在遇到指定的终止字符时提前结束
C++处理异常的机制是由3个部分组成的,即检查(try)、抛出(throw)和捕捉(catch)。
命名空间的作用是建立一些互相分隔的作用域,把一些全局实体分隔开来,以免产生名字冲突
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章