C++语法入门


前言

介绍一些个人对C++语法的学习,正在慢慢完善


初识C++

#include <iostream> //引用输入输出流
/*引用注释*/
using namespace std; //使用命名空间std
int main() {		//主函数
	cin >> a;
    std :: cout << "int类型占用的空间:" << sizeof(int) << std::endl; 
    return 0;
}

大体上与C语言类似,有以下几个区别:

  • < iostream >与C不同的是C++的库可以不带.h
  • std命名空间,当不使用.h文件时类和函数都在std里声明,声明了std就可以去掉std::
  • cin、cout分别为输入输出流对象
  • <<、>>分别为插入运算符与提取运算符
  • endl为末尾结束换行,还具备了刷新数据打印缓冲区的功能
  • ::类标识符,表示后面属于前面,类似C结构体调用
  • return执行完后跳出函数

基于过程的程序设计

一、数据类型与基本运算

1.1 C++数据类型

数据类型声明
整数类型int
单精度浮点数float
双精度浮点数double
字符char
字符串string
布尔bool
  1. 常量

常量其实和变量没有多大区别,有名字,占据存储空间,可以是任何的基本类型,但只有一点不同,常量的值不允许变更。C++中的常量的声明需要使用const 关键字,而python中的常量默认约定是全大写表示。

int main(){ 
	const double pi {3.1415926};
	pi = 2.5 ; //将会出现编译错误 
	return 0 ; 
}
  1. 变量

1.可以包含字母 、 数字 和下划线
2.必须以字母或者下划线开始

int age ; //未初始化
int age1 = 21 ; // C 方式初始化
int age2 (21); //构造方法初始化
int age3 {21} ; //c++ 11标准开始的方式

1.2 C++运算符

  1. 算术运算符

基本运算符有+,-,*,/,%,运算中有一个数为float型数据,则运算结果为double型
强制类型转换运算符,格式:(类型名)表达式

(int)(x+y)
  1. 赋值运算符

赋值运算符就是=

  1. 逗号运算符

C++提供逗号运算符,表示表达式按顺序连接起来

a = 3*5,a*4

二、程序初步设计

2.1 C++输入与输出

任何编程语言都要输入和输出,python的输入输出是input 和 print , C语言的输入输出是 scanf 和 printf ,而C++的相对要复 杂些,它使用 std::cin 和 std::cout 来操作输入输出 。 C++的输入输出,需要导入iostream库

  • 2.1.1 输入
std::cout << "请输入您的年龄:"<<std::endl;

endl 来表示输出结束,它除了含有换行的功能之外,还具备了刷新数据打印缓冲区的功能

  • 2.1.2输出
//由于没有换行,两个单词会出于同一行。
std::cout << "Hello"; std::cout << " world";

//兼备换行的输出
std::cout << "Hello" << std::endl; std::cout << " world" << std::endl;

//可以连续输出打印,这其实是一种叫做:链式调用的手法
std::cout << "Hello " << " World" << " , I love C++!" << std::endl;

2.2 逻辑关系运算

  • 2.2.1 关系运算符
Operator符号
等于==
不等于!=
大于>
小于<
大于或等于>=
小于或等于<=
  • 2.2.2 逻辑运算符
Operator符号
&&
||
  • 2.2.3 三元表达式
char result = score > 90 ? 'A' : 'B';

2.3 条件选择结构

  • 2.3.1 if-else语句
if( score > 90){
	std::cout << "可以休息一天" << std::endl; }
else if(score > 80){
	std::cout << "可以休息半天" << std::endl; 
	}else{
		std::cout << "乖乖去写作业" << std::endl; 
}
  • 2.3.2 switch语句
switch (level){
	case 'A':
		std::cout << "优秀" << std::endl;
		break;
	case 'B': 
	std::cout << "良好" << std::endl;
	break;
}

2.4 循环结构

  • 2.4.1 while
int count = 0 ;
while(count < 10){
	std::cout << "红灯还在亮着..." << std::endl;
	//单位是毫秒
	Sleep(1000);
	count++;
}
  • 2.4.2 do-while
int count = 0 ;
do{
	std::cout << "红灯还在亮着..." << std::endl;
	//单位是毫秒
	Sleep(1000);
	count++;
}while(count < 10);
  • 2.4.3 for
for(int cout = 0 ; cout < 10 ; cout ++)
	std::cout << "红灯还在亮着..." << std::endl;
  • 2.4.4 continue 和 break

continue:跳出本次循环,进入下一个循环
break:跳出循环体

int number = 1 ;
while(number <= 20){
	if(number == 16){
		break;
	}
	//满足条件,表示当前的number是奇数。
	if(number % 2 != 0 ){
		continue;
	}
	std::cout << "当前打印的数字是: " << number << std::endl;
	number++;
}

三、函数

3.1 函数的定义

  • 3.1.1 无返回值无参数
void say_hello(){ 
	cout << "你好 " << endl; 
}
  • 3.1.2 无返回值有参数
void say_hello(string name){ 
	cout << "你好 "<< name << endl; 
}
  • 3.1.3 有返回值无参数
string say_hello(){ 
	return "你好 张三"; 
}
  • 3.1.4 有返回值有参数
string say_hello(string name){ 
	return "你好 "+ name; 
}

3.2 函数调用

#include <iostream> 
using namespace std; 
//函数声明,如果函数调用在函数定义之前,则需要进行函数声明,从而初始化函数
int add (int a , int b); 
int main(){ 
	cout << add(1 ,2)<< endl; return 0 ; 
}
//函数定义 ,函数的真正实现。 
int add(int a , int b){ 
	return a + b ; 
}

3.3 函数参数

  • 3.3.1 值传递
#include<iostream> 
using namespace std; 
void scale_number(int num); 
int main(){ 
	int number{1000}; 
	scale_number(number); 
	//打印number 1000 
	cout << number << endl; 
	return 0 ; 
}
void scale_number(int num){ 
	if(num > 100) num = 100; 
}
  • 3.3.2 传递引用
#include<iostream> 
using namespace std; 
void scale_number(int &num); 
int main(){ 
	int number{1000};
	scale_number(number); 
	//打印number100 
	cout << number << endl; 
	return 0 ; 
}
void scale_number(int &num){ 
	if(num > 100) num = 100; 
}

四、数组

4.1 声明和初始化

数组是一系列相同类型的元素,放置在连续的内存位置,数组中的元素都可以通过索引来单独操作它们。 若查看某个变量存储地址可以使用 取地址符 &

//1. 声明后再初始化
int scores [5];
scores[0] = 11; scores[1] = 22; scores[2] = 33; scores[3] = 44; scores[4] = 55; 
//2. 声明并初始化
int scores2 [5]{100,89,95,70,80};
//3. 自动推算数组大小
int scores3[]{22,33,44,55,66};

4.2 访问数组

4.2.1 获取数组中的某个元素

std::cout<<"数组的第一个元素是: "<< scores[0]<<std::endl;

4.2.2 遍历数组

int main(){ 
	//定义数组
	int scores[]{100,95,97,88,85,80,75};
	//直接指定数组
	for(int i = 0; i < 7; i++){
		std::cout << scores[i] << std::endl;
	}
	//手动计算数组长度
	int length = sizeof(scores) / sizeof(int);
	for(int i = 0 ; i < length; i++){
		std::cout << scores[i] << std::endl;
	}
	//c++11 提供的for循环
	for(int score : scores){
		std::cout <<score << std::endl;
	}
	return 0 ;
}

4.3 字符串

C++ 标准库提供了 string 类类型,支持上述所有的操作,另外还增加了其他更多的功能。需要引入 #include< string>,由于string类声明在命名空间 std ,所以在使用的首要注意 命名空间的联合使用 。

//引入string库 
#include <string> 
using namespace std; 
int mian(){ 
	string s1; 
	string s2 {"北京"}; 
	string s3{s2}; 
	string s4 = "你好"; 
	s1 = s3; 
	return 0 ; 
}

4.4 Vector

Vector其实很大程度上和数组一样,只是数组是固定长度,而vector是不定长度(动态增长)。vector 在C++STL(标准模板库)中的一个容器,可以看成是对容器的一种扩展。

  • 4.4.1 声明和初始化
#include <vector> 
using namespace std; 
int main(){ 
	vector <char> vowels2(5); //声明一个初始大小为5的char类型 
	vector <char> vowels {'a' , 'e' , 'i' , 'o' ,'u'};
	return 0; 
}
  • 4.4.2 访问vector
#include <iostream> 
#include <vector> 
using namespace std; 
int main(){ 
	vector<int> test_score {100,90,85}; 
	//以数组方式
	cout << "第一个成绩是: " <<test_score[0] << endl;
	cout << "第二个成绩是: " <<test_score[1] << endl;
	cout << "第三个成绩是: " <<test_score[2] << endl;
	cout << "第三个成绩是: " <<test_score[3] << endl;//不会检查越界 
	//vector的语法
	cout << "第一个成绩是: " <<test_score.at(0) << endl;
	cout << "第二个成绩是: " <<test_score.at(1) << endl;
	cout << "第三个成绩是: " <<test_score.at(2) << endl;
	cout << "第三个成绩是: " <<test_score.at(3) << endl; // 抛出越界异常
	return 0 ; 
}
  • 4.4.3 操作vector

①修改vector中的元素

vector<int> test_score {100,90,85};
test_score.at(0) = 73;

②往vector中追加元素

vector<int> test_score {100,90,85};
test_score.push_back(80); // 100 , 90 , 85 , 80

③遍历vector

//使用下标遍历 
vector<int> scores{ 100 ,95 ,88 ,80 ,75}; 
for (int i = 0; i < scores.size(); ++i) { 
	cout << scores[i] << endl; 
}
//基于范围for遍历 
vector<int> scores2{ 100 ,95 ,88 ,80 ,75}; 
for(int score : scores2){ 
	cout << score << endl; 
}

五、指针

5.1 什么是指针

指针其实就是一个变量,不过它的值是一个内存地址 , 这个地址可以是变量或者一个函数的地址

5.2 声明和初始化

  • 5.2.1 声明指针
#include <iostream> 
int main(){ 
	//初始化指针 
	int a = 3 ; 
	int *p0 = &a; 
	//p0是一个指针,指向的是一个int类型的数据,这个 数据是3.
	//空指针,没有指向任何地方 
	int *p1 = nullptr;
	int *p2 = NULL;
	int *p3 = 0 ; 
	return 0 ; 
}
  • 5.2.2 栈内存
#include <iostream> 
int main(){ 
	int age = 88; 
	int *p = &age; 
	//函数执行结束, age所占用空间会自动回收 
	return 0 ; 
}
  • 5.2.3 堆内存
#include <iostream> 
int main(){ 
	//使用new的方式在堆内存中开辟空间。 
	int *p = new int(88); 
	//需要手动配合delete 删除 
	delete p ; 
	return 0 ; 
}

5.3 函数与指针

  • 5.3.1 参数传递指针

函数的参数,除了传递普通的变量,引用之外,还可以把指针当成参数来传递

#include <iostream>
using namespace std; 
//函数原型 
void double_data(int *int_ptr); 
int main(){ 
	int value{10}; 
	//修改前,输出为10 
	cout << value << endl; 
	//在函数内部修改value的值 
	double_data(&value); 
	//修改后,输出为20 
	cout << value << endl; 
}
void double_data(int *int_ptr){ 
	*int_ptr *=2; 
}
  • 5.3.2 函数返回指针

函数平常除了返回标准的数值之外,其实也可以返回指针。

#include <iostream> 
using namespace std; 
//返回两个参数中的最大者 
int *calc_largest(int *ptr1 , int *ptr2); 
int main(){ 
	int a = 100; 
	int b = 200; 
	//使用指针指向最大数值 
	int *largest_ptr = calc_largest(&a , &b); 
	//输出:200 
	cout << *largest_ptr << endl ; 
	return 0 ; 
}
int *calc_largest(int *ptr1 , int *ptr2){ 
	//解引用获取到数据后比较 : 
	if(*ptr1 > *ptr2){ 
		return ptr1; 
	}else{
		return ptr2; 
	} 
}

5.4 引用

引用,顾名思义是某一个变量或对象的别名,对引用的操作与对其所绑定的变量或对象的操作完全等价。引用在使用时,有几个要注意的地方:

  1. &不是求地址运算符,而是起到标志作用
  2. 引用的类型和绑定的变量类型必须相同 (指针也一样) 3. 声明引用的同时,必须对其进行初始化,否则报错。
  3. 引用不是定义一个新的变量或对象,因此内存不会为引用开辟新的空间存储这个引用
  4. 不能建立数组的引用。因为数组是一个由若干个元素所组成的集合,所以无法建立一个数组的别名。
int main(){ 
	//语法:类型 &引用名=目标变量名; 
	int a = 3 ; 
	int &b = a ; 
	//此时a也会变成33 
	b = 33; 
	vector<string> names {"张三" , "李四" ,"王五"}; 
	// 这仅仅是改变了str的值,并不会改变vector里面的元素
	for(auto str:names){ str = "赵六"; }
	//此处不会产生新的变量,所以修改的都是vector里面的元素
	for(auto &str : names){ str = "赵六" ; }
	return 0 ; 
}

六、自定义数据类型

6.1 结构体

结构体与数组的区别就是,结构体可以包含不同类型的数据项

struct Student		//用struct来声明结构体
{int num;
char name[20];
char sex;
int age;
float score;
}student1 = {10001,"zhang Xin",'F',20,18};	//初始化
Student student2 = {10002,"Wang Li",'F',20,68};

结构体指针3种形式等价:
①结构体变量.成员名。如stu.num
②(*p).成员名。如(*p).num
③p -> 成员名。如p -> num

6.2 枚举类型

如果变量的值确定,则可以定义枚举类型

enum weekday	//用enum申明枚举类型
{
	sun,mon,tue,wed,thu,fri,sat
};

6.3 用typedef声明新的类型名

typedef float REAL;		//用REAL代表float类型

6.4 new和delete运算符

C++用new和delete取代malloc与free来动态分配和撤销存储空间

p = new Student; 	//用new开辟一个存放Student型数据的空间,地址赋给p
delete p;

面向对象的程序设计

七、类和对象的特性

对象是一类东西, 而类是构成对象的一个基石,从而描述对象的特征

7.1 类

#include<string> 
#include <iostream> 
using namespace std; 
class student{ 
	private: 
		string name; // 姓名 
		int age; //年龄 
	public: 
		void read(){ 
			std::cout << "学生在看书" << std::endl; 
		} 
};

7.2 对象

  • 7.2.1 在栈中创建对象

用这种方法创建的对象,内存分配到栈里(Stack)。 直接使用 来访问成员。当程序对象所在的代码块结束运行(方法运行结束),对象会自动删除,内存自动释放。

#include<iostream> 
using namespace std; 
class student{ 
	public: 
		void run(){ 
			cout << "学生在跑步" << endl; 
		} 
};
int main(){ 
	//对象存储于栈内存中 
	student stu1 ; 
	stu1.run(); 
	return 0 ; 
}
  • 7.2.2 在堆中创建对象

这种方法创建的对象,内存分配到堆里(Heap)。一般使用* 或者 - >调用对象的方法。箭头操作符”->"将解引用(dereferencing* )和成员使用(member access.)结合起来

#include<iostream> 
#include<string> 
using namespace std; 
class student{ 
	public: 
		void run(){ 
			cout << "学生在跑步" << endl; 
		}

};
int main(){ 
	//对象存储于栈内存中 new 关键字是在堆中申请内存 
	student *s3 = new student; 
	s3->run(); 
	//采用解引用的方式之后,再进行成员访问 
	(*s3).run(); 
	return 0 ; 
}

7.3 访问修饰符

c++ 对于成员的访问有三种访问操作符 public | private | protected , 默认情况下是private

  1. public : 公开权限,任何位置都可以访问
  2. private : 私有权限,只能自己内部访问及其友元类和函数
  3. protected : 受保护权限,只能在自己内部、子类及友元类和函数访问
#include<iostream> 
#include<string> 
using namespace std; 
class student{ 
	private: //表示下面的成员为私有 
		string name; // 姓名 
		int age; //年龄 
	public: //表示下面的函数为公开 
		void run(){} }
;
int main(){ 
	student stu ;
	stu.name = "张三" ; // 禁止访问 , 会报错 
	stu.run(); //允许访问 
	return 0 ; 
}

7.4 实现类的成员函数

  1. 成员函数可以在类里面直接实现,也可以在类的外部实现
  2. 可以在类的外部实现成员函数 , 但是需要使用类名::函数名来标记函数
#include <iostream> 
#include <string> 
using namespace std; 
class student{ 
	private : 
		int age ; 
		string name; 
	public : 
		void read(string bookname){ 
			cout<< bookname << endl; 
		}
		void speak(string something); 
};

void student::speak(string something){ 
	cout << "说说说---" << something << endl; 
}
int main(){ 
	student stu;
	stu.read("哈利波特"); 
	stu.speak("我喜欢看哈利波特"); 
	return 0 ;
}

八、类和对象的使用

当定义一个类后,它的对象在未来的操作中,总会不可避免的总会碰到如下的行为:创建 、拷贝 、赋值 、移动 、销毁 。这些操作实际上是通过六种特殊的成员函数来控制的:构造函数 、析构函数、拷贝构造函数 、拷贝赋值函数 、移动构造函数、移动赋值函数 。默认情况下,编译器会为新创建的类添加这些函数 (默认不会添加移动构造和移动赋值),以便它的对象在未来能够执行这些操作。

8.1 构造函数与析构函数

  1. 构造函数是类的一种特殊的成员函数,它会在每次创建对象时执行。它与类名同名,没有返回值,可以被重载,通常用来做初始化工作。
  2. 析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。不能被重载,一般用于释放资源。
#include <iostream> 
#include <string> 
using namespace std; 
class student{ 
	string name; 
	int age ; 
	public : 
		//构造函数 
		student(){ 
			cout << "执行无参构造函数" <<endl;	
		}
		student(string name ){ 
			cout << "执行含有一个参数的参构造函数" <<endl;
		}
		student(string name , int age ){ 
			cout << "执行含有两个参数的构造函数" <<endl; 
		}//更好的构造方式 
		student(string name ,int age):name{name},age{age}{ 
			cout << "执行有参构造函数" <<endl; 
		}
		//析构函数{} 
		~student(){ 
			cout << "执行析构函数" <<endl; 
		} 
};
int main(){ 
	student *s1 = new student(); 
	student s2{"张三"}; 
	student s3{"张三",28};
	//释放对象 
	delete s1; 
	return 0 ; 
}

8.2 拷贝构造函数

C++中经常使用一个常量或变量初始化另一个变量,表面上相当于将s1中每个数据成员的值复制到s2中。实际上,系统调用 了一个拷贝构造函数。

class student{ };
int mian(){
	int a = 3; 
	int b = a; 
	student s1; 
	student s2 = s1; 
	return 0 ; 
}
  • 8.2.1 浅拷贝

指的是在对象复制时,只对对象中的数据成员进行简单的赋值,编译器提供的拷贝操作即是浅拷贝,默认拷贝构造函数执行的也是浅拷贝。如果数据中有属于动态成员 ( 在堆内存存放 ),那么浅拷贝只是做指向而已,不会开辟新的空间。
默认情况下,浅拷贝已经足以应付日常的需求了,但是当类中的成员存在动态成员(指针)时,浅拷贝往往会出现一些奇怪的问题。由于address是指针类型,如果是浅拷贝, 那么两个指针会指向同一个位置。

  • 8.2.2 深拷贝

深拷贝 也是执行拷贝,只是在面对对象含有动态成员或指针时,会执行新内存的开辟,而不是作简单的指向。在发生对象拷贝的情况下,如果对象中存在动态成员,就不能仅仅简单地赋值了,而应该重新分配空间。

#include <iostream> 
#include <string> 
using namespace std; 
class student { 
	public: 
		string name; 
		string *address=nullptr; 
		student(string name , string * address):name(name),address(address){ 
			cout << "执行构造函数" << endl; 
		}
		//深拷贝 
		student(const student & s){ 
			cout << "调用了拷贝构造函数" << endl; 
			name = s.name; 
			if(address == nullptr){ 
				//开辟新的空间 
				address = new string(); 
				*address = *s.address; 
			} 
		}
		//析构函数 
		~student(){ 
			cout << "调用了析构函数" << endl; 
			if(address != nullptr){ 
				delete address; address = nullptr; 
			} 
		}
};
int main(){ 
	string *address= new string("深圳"); 
	student s1("张三" , address); 
	//此处会执行拷贝。 
	student s2 = s1; 
	cout << s1.name << " : " << *(s1.address) << endl;
	cout << s2.name << " : " << *(s2.address) << endl;
	//修改第一个学生的地址为:北京 
	*(s1.address) = "北京"; 
	//第二个学生的地址不会变成北京 
	cout << s1.name << " : " << *(s1.address) << endl;
	cout << s2.name << " : " << *(s2.address) << endl;
	return 0 ; 
}

九、重载、继承和派生

9.1 运算符重载

重载就是对已有的东西赋予新的含义

运算符重载一般格式:
函数类型 operator 运算符名称 (型参表)
{对运算符的重载处理}

int operator + (int a,int b)
{return (a+b);}

9.2 继承和派生

继承和派生的概念
一个新类从已有的类建立一个新类就是继承,而新产生的子类就是类的派生

派生类的声明方式:
> class 派生类名:[继承方式] 基类名
{
派生类新增加的成员
};

注:如果不写继承方式,默认为private(私有的)

Class Student { //声明基类
public: //基类公用成员
	void get_value() //输入基类数据的成员函数
	{cin>>num>>name>>sex;}
	void display() //输出基类数据的成员函数
	{
		cout<<" num: "<<num<<endl;
		cout<<" name: "<<name<<endl;
		cout<<" sex: "<<sex<<endl;
	}
private : //基类私有成员
	int num;
	string name;
	char sex;
};
class Student1: public Student { //以public方式声明派生类Student1
public:
	void get_value_1() //输入派生类数据
	{cin>>age>>addr;}
	void display_1()
	{
		cout<<" num: "<<num<<endl; //试图引用基类的私有成员,错误
		cout<<" name: "<<name<<endl; //试图引用基类的私有成员,错误
		cout<<" sex: "<<sex<<endl; //试图引用基类的私有成员,错误
		cout<<" age: "<<age<<endl; //引用派生类的私有成员,正确
		cout<<" address: "<<addr<<endl;
	} //引用派生类的私有成员,正确
Private:
	int age;
	string addr;
};

十、多态性和虚函数

10.1 多态性概念

多态性:向不同的对象发送同一个消息,不同的对象在接收时会产生不同的行为(即方法)。

多态性分类:
静态多态性是通过函数重载实现的
动态多态性的特点是: 不在编译时确定调用的是哪个函数,而是在程序运行过程中才动态地确定操作所针对的对象。动态多态性是通过虚函数(virtual function)实现的。

10.2 利用虚函数实现动态多态性

虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数

#include <iostream>
#include <string>
using namespace std;
//声明基类Student
class Student {
	public:
		Student(int, string,float);//声明构造函数
		void display(); //声明输出函数
	protected://受保护成员,派生类可以访问
		int num;
		string name;
		float score;
};
//Student类成员函数的实现
Student∷Student(int n, string nam,float s) //定义构造函数
	{num=n;name=nam;score=s;}
void Student∷display()//定义输出函数
	{cout<<"num:"<<num<<"\\nname:"<<name<<"\\nscore:"<<score<<"\\n\\n";}
//声明公用派生类Graduate
class Graduate:public Student {
	public:
		Graduate(int, string, float, float);//声明构造函数
		void display(); //与基类的输出函数同名
	private:
		float wage;
};
// Graduate类成员函数的实现
Graduate∷Graduate(int n, string nam,float s,float w):Student(n,nam,s),wage(w) {}
void Graduate∷display()//定义输出函数
	{cout<<"num:"<<num<<"\\nname:"<<name<<"\\nscore:"<<score<<"\\nwage="<<wage<<endl;}
//主函数
int main()
{
	Student stud1(1001,"Li",87.5); //定义Student类对象stud1
	Graduate grad1(2001,"Wang",98.5,1200);//定义Graduate类对象grad1
	Student pt=&stud1;//定义指向基类对象的指针变量pt,指向stud1
	pt->display(); //输出Student(基类)对象stud1中的数据
	pt=&grad1;//pt指向Graduate类对象grad1
	pt->display();//希望输出Graduate类对象grad1中的数据
	return 0;
}

10.3 纯虚函数与抽象类

纯虚函数:在声明虚函数时被“初始化”为0的函数。作用是在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义。其格式为:
virtual 函数类型 函数名 (参数表列) =0;

抽象类:这种不用来定义对象而只作为一种基本类型用作继承的类,称为抽象类(abstract class),由于它常用作基类,通常称为抽象基类(abstract base class)。

十一、输出输入流

C++的输入输出流是指由若干个字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一个对象。总之,流是与内存缓冲区相对应的,或者说,缓冲区中的数据就是

ios是“输入输出流”,streambuf是处理“流缓冲区”的类,包括缓冲区起始地址、读写指针和对缓冲区的读写操作,是数据在缓冲区中的管理和数据输入输出缓冲区的实现。I/O类库中的常用流类:

在这里插入图片描述

11.1 标准输出流与输入流

在这里插入图片描述

11.2 文件流与文件操作

  1. 文件的打开与关闭

一般形式为:
文件流对象.open(磁盘文件名,输入输出方式);
文件输入输出方式设置值:

方式作用
ios::in以输入方式打开文件
ios:out以输出方式打开文件,如果文件存在,则将其原有内容清除
ios::app以输出方式打开文件,写入的数据添加在文件末尾
ios::ate打开已有文件,文件指针指向文件末尾
ios::trunc打开文件,如果文件存在则删除其数据;不存在则创建文件
ios:binary以二进制方式打开一个文件
ios::nocreate打开一个已有文件,如果文件不存在,则打开失败
ios::noreplace如果文件不存在则建立文件,如果存在则操作失败
ios::in | ios::out以输入输出方式打开文件
ios::binary | ios::out以二进制方式打开一个输出文件
ios::in | ios::binary以二进制方式打开一个输入文件
ofstream outfile;//定义ofstream类(输出文件流类)对象outfile
outfile.open("f1.dat",ios∷out);//使文件流与f1.dat文件建立关联
outfile.close();//将输出文件流所关联的磁盘文件关闭所谓关闭

outfile.open("f2.dat",ios∷app|ios∷nocreate);此时文件流outfile与f2.dat建立关联,并指定了f2.dat的工作方式。
  1. 对二进制文件的读写

字符指针buffer指向内存中一段存储空间。len是读写的字节数。其一般格式为:

istream& read(char *buffer,int len);
ostream& write(const char *buffer,int len);

C++扩展

一、C++工具

1.异常处理

异常处理指的是,对运行时出现的差错以及其他例外情况的处理 。C++异常处理由3个部分组成:检查(try)、抛出(throw)和捕捉(catch)。如果出现异常,可以发出一个信息,由上级捕捉信息后处理

void f3()
{double a=0;
try		//在try中包括要检测的部分
	{throw a;}   //throw执行后会立刻返回上一级函数
catch(float)	//用catch捕捉异常并处理

	{cout << "ERROR!" << endl;}
}

2.命名空间

可以使用 using namespace指令,这样在使用命名空间时就可以不用在前面加上命名空间的名称。这个指令会告诉编译器,后续的代码将使用指定的命名空间中的名称。
本质上,命名空间就是定义了一个范围。它可作为附加信息来区分不同库中相同名称的函数、类、变量等。

#include <iostream>
using namespace std;
int main(){
	cout<<"hi c++" << endl;
	return 0 ;
}

结语

关于python语法的学习见以下文章
https://blog.csdn.net/weixin_44567668/article/details/125189798

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别问,问就是全会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值