String: 等号赋值
String s1//默认构造
Const char*str=”hello world”;
String s2(str);//s2 =”hello world”
String s3(s2);//s3=s2
String s4(10,’a’);//s4=aaaaaaaaaa
String赋值assign
Str1.assign(“hello world”)
Str1.assign(“hello world”,5);//把前5个字符赋给str1
Str2.assign(str1)//把str1给str2
String字符串拼接:
Str1 +=”hello”;//str1+hello Str1+=’a’;//加一个字符 str1+=str2//两个字符串拼接
Str3.append(“字符串”) str3.append(“”,4)//拼接前四个字符 str3.append(str2)
Str3.append(str2,0,3) 从str[0]开始,截取三个字符,然后拼接
String的查找和替换:
String str1=”abcdefg”;
Int pos=Str1.find(“de”) 返回3 pos==-1//未找到字符串
Str1.rfind(“de”) 返回3//rfind从右往左查找,find从左往右找
Str.replace(起始位置,替换之前去掉的的元素的个数,“替换的字符串”)
string的比较:
=返回0 >返回1 <返回-1
Str1.compare(str2)==0-------str1==str2
String字符串存取:
Str.size()//返回字符串的长度
Str[i]//取单个字符 //Str.at(i)
String的插入和删除:
Str.insert(1,”111”)//在str[1]的位置插入三个1
Str.erase(1,3)//在str[1]的位置删除三个字符
String的子串:
String substr(1,3)//从str[1]开始截取三个字符
Stoi(s)//将字符串转化为数字
To_string(123)//将数字转化为字符串
Stoi(string(1,a))//将字符转化为数字
To_string(1)[0]//将数字转化为字符
函数定义:1、返回值类型2、函数名3、参数列表4、函数体语句5、return表达式
返回值类型 函数名(形式参数列表)
{
函数体语句
Return 表达式
}
函数调用:函数名(实际参数)
值传递时,函数的形参的任何改变不会影响实参
如果函数不需要返回值,声明时可以写void,不需要写return
函数的常见样式:1、无参无返2、有参无返3、无参有返4、有参有返
1、void test01(){cout<<} 2、Voidtest02(int a){} 3、Void test03(){return 1000; } 4、Void test04(int a){return a;}
函数的声明:先声明,再使用函数,定义函数
返回值类型 函数名称(形参列表);//声明可以多次,定义只能有一次
函数的分文件编写:
步骤:1、创建后缀名为.h的头文件2、创建后缀名为.cpp的源文件3、在头文件中写函数的声明4、在源文件中写函数的定义
源文件:#include”swap.h”+函数的定义
头文件:#include<iostream> using namespace std; +函数的声明
用的时候在开头打#include “swap.h”
指针:
作用:可以通过指针间接访问内存
内存编号是从0开始记录的,一般用十六进制数字表示
可以利用指针变量保存地址 指针==地址
指针变量定义语法:数据类型*变量名
int a=10;
Int*p;
P=&a;//p为a的地址
或者int*p=&a;
使用指针:指针前加一个*代表 解引用,找到指针指向的内存中的数据
*p=1000;//修改为a=1000,*p=1000
指针所占的内存空间:指针也是一个数据类型(int*、char*)(在32位操作系统下占4个字节空间,在64位下占据8个字节
空指针和野指针:
空指针:指针变量指向内存中编号为0的空间 用途:初始化指针变量 注意:空指针指向的内存是不可以访问的
Int *p=NULL;//空指针的地址编号=NULL
0~255之间的内存编号是系统占用内存的,不可访问
野指针:指针变量指向非法的内存空间//在程序中避免出现野指针
Int*p=(随机选取的空间)(int*)0x10011
Const修饰指针:1、const修饰指针---常量指针 2、const修饰常量---指针常量3、const既修饰指针,又修饰常量
Const int*p=&a;//常量指针,指针的指向(p)可以修改,但是指针指向的值(*p)不可以改
Int * const p=&a//指针常量,const后面跟的是常量p,指针的指向p不可以改,指针的指向的值*p不可以改
Const int * const p=&a; //指针的指向和值都不可以改
指针和数组:利用指针访问数组中的元素
Int arr[10]={1,2,3,4,5,6,7,8,9,0};
Int*p=arr;//arr就是数组的首地址
P++//让指针向后偏移四个字节,地址就向后移,就是第二个元素的地址
指针和函数:利用指针作函数的参数,可以修改实参的值(why?)
地址传递:void swap02(int*p1,int*p2){int temp=*p1:*p1=*p2;*p2=temp;}Swap(&a,&b)
结构体:
结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
语法:struct 结构体名{结构体成员列表};//学生数据类型:姓名,年龄,分数(学生的属性)//本质是一些数据类型组合起来的数据类型
定义结构体:Struct student{string name; int age;int score;}s3;
方式:1、struct 结构体名 变量名2、struct结构体名 变量名={成员值1}
通过学生类型创建具体学生://struct可以省略
1、Struct student s1:s1.name=”cyw”;s1.age=18;s1.score=100;
2、struct student s2={“cyw”,18,100};
3、在定义结构体时顺便创建结构体变量 s3.name=”cyw”;s3.age=20;s3.score=60;
结构体数组:将自定义的结构体放入到数组中方便维护
语法:struct 结构体名 数组名[元素个数]={{},{},...,{}}//数据类型 数组名[元素个数]=
Ex:struct student{string name;int age;int score;};//定义结构体
Struct student arr[3]={{“cyw”,18,100},{“c”,19,89},{“q”,17,100}};//创建结构体数组
arr[2].name=”y”;//修改数组里面的元素
结构体指针:通过指针访问结构体中的成员
struct student{string name;int age;int score;};
Struct student s={“s”,18,100};
Struct student *p=&s;
Cout<<”姓名:”<<p->name<<”年龄:”<<p->age;//通过结构体指针访问结构体中的属性,需要利用”->”
结构体嵌套结构体:
struct student{string name;int age;int score;};
Struct teacher{int id;string name;int age;struct student stu;};//stu是变量名
Teacher t;
t.Stu.name=”c”;
结构体做函数参数:将结构体作为函数参数 1、值传递2、地址传递
Struct student {string name;int age;int score;};
Struct student s;
Void printstudent1(struct student s){cout<<s.name;}//值传递
Void printstudent2(struct student*p){cout<<p->name;}//地址传递
s.name=”c”;s.age=20;s.score=85;
Printstudent1(s);
Printstudent2(&s);
结构体中const使用场景:
加入const之后,一旦有修改的操作就会报错,可以防止我们的误操作
Int random=rand()%60+40//0+40~59+40
随机数种子:#include <ctime> int main{ srand((unsigned int)time(NULL));}
C++面向对象:
内存分区模型:代码区(存放函数体的二进制代码,由操作系统管理)、全局区(存放全局变量和静态变量以及常量)、栈区(由编译器自动分配释放,存放函数的参数值、局部变量等)、堆区(有程序员分配和释放,若程序员不释放,程序结束时由操作系统回收)
内存四区意义:不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程
程序编译后生成exe可执行程序,
未执行该程序前分为两个区域:代码区:存放CPU执行的机器指令(特点:共享(在内存中只有一份代码,可被频繁执行)、只读(防止程序意外修改指令))
全局区:全局变量(不在函数体(例:int main)里面的变量)和静态变量(static +普通变量)、常量(该区域的数据在程序结束后由操作系统释放)
常量:字符串常量、const修饰的全局变量
有局部的(局部变量、const修饰的局部变量)都不在全局区中
程序运行后的区域:
栈区:存放函数的参数值、局部变量(注:不要返回局部变量的地址)//当函数运行完,就清空数据了,但是第一次编译器会做保留
堆区:利用new可以将数据开辟到堆区
New 的基本语法:int*p=new int(10)
Delete p;//释放内存,无法再次访问
开辟数组:int* arr=new int [10];
引用:作用:给变量起别名 语法:数据类型 &别名=原名 通过两个变量名都可以修改值
引用的注意事项:必须初始化(int &b=a;//右边必须有值)引用一旦初始化,就不能发生改变
引用做函数参数:引用传递int swap(int &a.int &b){int temp=a;a=b;b=temp;} swap(a,b)//引用传递,形参会修饰实参
引用作函数返回值:
1、不要返回局部变量的引用int& test(){int a=10;return a;}×
2、函数的调用可以作为左值teat()=100;
常量引用:用来修饰形参,防止误操作
Const int& ref=10;//不允许修改ref了
函数的默认参数:语法:返回值类型 函数名(参数=默认值){} 如果传入了数据,就用自己的数据,如果没有就用默认值
注意事项:1、如果某个位置已经有了默认参数,那么从这个位置往后,从左到右都必须有默认值 2、函数声明有默认参数,函数实现就不能有默认参数
函数占位参数:用来作占位,调用函数时必须填补该位置 语法:返回值类型 函数名(数据类型){};
函数重载:作用函数名可以相同 满足条件:同一个作用域下、函数名称相同、函数参数类型不同或者个数不同或者参数顺序不同
注意事项:
1、引用作为重载条件fun(int &a)//int a=10;fun(a) fun(const int&a)//fun(10)
2、函数重载遇到默认参数 参数+默认参数和参数冲突(二义性 )(int a,int b=10)and(int a)
类和对象:
对象的三大特性:封装、继承、多态
具有相同性质的对象,可以抽象为类
封装:意义:将属性和行为作为一个整体,表现生活中的事物
Class circle//代表设计一个类,类后面紧跟着就是类名称
{//访问权限,公共权限
Public:
//属性(圆的半径)类中的属性和行为 我们统一称为成员
Int m_r;
//行为 成员函数、成员方法
//获取圆的周长
Double calculate(){return 2*pi*m_r}
};
Int main(){//通过圆类创建具体的圆(对象)
Circle cl;cl.m_r=10;
Cout<<”圆的周长为:”<<cl.calculate()<<endl;
}
类在设计时,可以把属性和行为放在不同的权限下,加以控制访问权限有三种:
- public 公共权限类内可以访问,类外可以访问
- protected 保护权限 类内可以访问,类外不可以访问
- private 私有权限 类内可以访问,类外不可以访问
struct默认权限为公共、class默认权限为私有
//成员属性设置为私有:1、可以自己控制读写权限 2、对于写可以检测数据有效性
Class person{
Public:
Void setname(string name)
{}
String getname(){return m_name}
Private:
string m_name;//可读可写
Int m_age;//只读
String m_idol;//只写
}
Int main(){
Person p;
P.setname(“”);
P.getname();
}
构造函数:主要作用于创建对象时为对象成员属性赋值,构造函数由编译器自动调用,无须手动调用
构造函数语法:类名(){}
- 构造函数,没有返回值也不写void
- 函数名称与类名相同
- 构造函数可以有参数,因此可以发生重载
- 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
析构函数语法:~类名(){}
- 析构函数,没有返回值也不写void
- 函数名称与类名相同,在名称前加上符号~
- 析构函数不可以有参数,因此不可以发生重载
- 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
构造函数的分类及调用:
两种分类方式:按参数分为:有参构造和无参构造 按类型分为:普通构造和拷贝构造
三种调用方式:括号法、显示法、隐式转换法
拷贝:person(const person &p){age=p.age}//将传入的人的所有属性,拷贝到我身上
调用:
//括号法:void test(){person p1;} test();//调用默认构造函数时不要加() person p1;
//显示法:person p2=person(10);//有参构造 person p3=person (p2)//拷贝构造
Person(10)//匿名对象 特点:当前行执行结束后,系统会自动回收掉匿名对象
注意事项:不要利用拷贝构造函数,初始化匿名对象,编译器会认为person(p3)是对象声明
//隐式转换法:person p4=10//相当于person p4=person (10)
拷贝构造函数:1、使用一个已经创建完毕的对象来初始化一个新对象
2、值传递的方式给函数参数传值
3、值方式返回局部对象
初始化列表:语法:构造函数():属性1(值1),属性2(值2)...{}
Class person{
public:
//Person(int a,int b){m_a=a;m_b=b; } //person p(10,20)
Person(int a,int b):m_a(a),m_b(b){}
int m_a;
int m_b;}
类对象作为类成员:c++类中的成员可以是另一个类的对象
静态成员:+static
静态成员变量:所有对象共享同一份数据、在编译阶段分配内存、类内声明,类外初始化(int person::m_a=100)
STL:
Vector//数组
Vector<int>v;
V.push_back//向v中插入数据
Vector<int>::iterator itBegin =v.begin();//通过迭代器访问 v.begin()是起始迭代器,指向容器中的第一个元素
Vector<int>::iterator itEnd=v.end();//v.end()终止迭代器 容器中最后一个元素的下一个位置
While(itBegin!=itEnd){cout<<*itBegin<<endl;*itBegin++;}//第一种遍历方法
For(vector<int>::iterator it=v.begin();it!=v.end();it++){cout<<*it;}//第二种遍历方法
Void myprint(int val){cout<<val<<endl;}
For_each(v.gegin(),v.end(),myprint());//第三种遍历方法
Vector中存放自定义数据类型,并打印输出
Push_back()//尾端插入 pop_back()//尾部删除
Vector<T>v; vector(v.begin(),v.end());//将v【begin(),end())区间的元素拷贝给本身vector(n,elem)//将n个elem拷贝给本身 vector(const vector &vec);//拷贝构造函数
V1=v;//重载等号操作符
v.Assign(v1.beg(),v1.end());//将[beg,end)区间中的数据拷贝赋值给本身
Assign(n,elem);//将n个elem拷贝赋值给本身
V.empty();//判断容器是否为空
v.capacity();//容器的容量
V.size();//返回容器中元素的个数
v.resize(int num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。若容器变短,则末尾超出容器长度的元素被删除
V.resize(int num,elem);//重新定义长度为num,若变长,则以elem填充新位置
Int random=rand()%60+40//0+40~59+40
随机数种子:#include <ctime> int main{ srand((unsigned int)time(NULL));}
C++面向对象:
内存分区模型:代码区(存放函数体的二进制代码,由操作系统管理)、全局区(存放全局变量和静态变量以及常量)、栈区(由编译器自动分配释放,存放函数的参数值、局部变量等)、堆区(有程序员分配和释放,若程序员不释放,程序结束时由操作系统回收)
内存四区意义:不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程
程序编译后生成exe可执行程序,
未执行该程序前分为两个区域:代码区:存放CPU执行的机器指令(特点:共享(在内存中只有一份代码,可被频繁执行)、只读(防止程序意外修改指令))
全局区:全局变量(不在函数体(例:int main)里面的变量)和静态变量(static +普通变量)、常量(该区域的数据在程序结束后由操作系统释放)
常量:字符串常量、const修饰的全局变量
有局部的(局部变量、const修饰的局部变量)都不在全局区中
程序运行后的区域:
栈区:存放函数的参数值、局部变量(注:不要返回局部变量的地址)//当函数运行完,就清空数据了,但是第一次编译器会做保留
堆区:利用new可以将数据开辟到堆区
New 的基本语法:int*p=new int(10)
Delete p;//释放内存,无法再次访问
开辟数组:int* arr=new int [10];
引用:作用:给变量起别名 语法:数据类型 &别名=原名 通过两个变量名都可以修改值
引用的注意事项:必须初始化(int &b=a;//右边必须有值)引用一旦初始化,就不能发生改变
引用做函数参数:引用传递int swap(int &a.int &b){int temp=a;a=b;b=temp;} swap(a,b)//引用传递,形参会修饰实参
引用作函数返回值:
1、不要返回局部变量的引用int& test(){int a=10;return a;}×
2、函数的调用可以作为左值teat()=100;
常量引用:用来修饰形参,防止误操作
Const int& ref=10;//不允许修改ref了
函数的默认参数:语法:返回值类型 函数名(参数=默认值){} 如果传入了数据,就用自己的数据,如果没有就用默认值
注意事项:1、如果某个位置已经有了默认参数,那么从这个位置往后,从左到右都必须有默认值 2、函数声明有默认参数,函数实现就不能有默认参数
函数占位参数:用来作占位,调用函数时必须填补该位置 语法:返回值类型 函数名(数据类型){};
函数重载:作用函数名可以相同 满足条件:同一个作用域下、函数名称相同、函数参数类型不同或者个数不同或者参数顺序不同
注意事项:
1、引用作为重载条件fun(int &a)//int a=10;fun(a) fun(const int&a)//fun(10)
2、函数重载遇到默认参数 参数+默认参数和参数冲突(二义性 )(int a,int b=10)and(int a)
类和对象:
对象的三大特性:封装、继承、多态
具有相同性质的对象,可以抽象为类
封装:意义:将属性和行为作为一个整体,表现生活中的事物
Class circle//代表设计一个类,类后面紧跟着就是类名称
{//访问权限,公共权限
Public:
//属性(圆的半径)类中的属性和行为 我们统一称为成员
Int m_r;
//行为 成员函数、成员方法
//获取圆的周长
Double calculate(){return 2*pi*m_r}
};
Int main(){//通过圆类创建具体的圆(对象)
Circle cl;cl.m_r=10;
Cout<<”圆的周长为:”<<cl.calculate()<<endl;
}
类在设计时,可以把属性和行为放在不同的权限下,加以控制访问权限有三种:
- public 公共权限类内可以访问,类外可以访问
- protected 保护权限 类内可以访问,类外不可以访问
- private 私有权限 类内可以访问,类外不可以访问
struct默认权限为公共、class默认权限为私有
//成员属性设置为私有:1、可以自己控制读写权限 2、对于写可以检测数据有效性
Class person{
Public:
Void setname(string name)
{}
String getname(){return m_name}
Private:
string m_name;//可读可写
Int m_age;//只读
String m_idol;//只写
}
Int main(){
Person p;
P.setname(“”);
P.getname();
}
构造函数:主要作用于创建对象时为对象成员属性赋值,构造函数由编译器自动调用,无须手动调用
构造函数语法:类名(){}
- 构造函数,没有返回值也不写void
- 函数名称与类名相同
- 构造函数可以有参数,因此可以发生重载
- 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
析构函数语法:~类名(){}
- 析构函数,没有返回值也不写void
- 函数名称与类名相同,在名称前加上符号~
- 析构函数不可以有参数,因此不可以发生重载
- 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
构造函数的分类及调用:
两种分类方式:按参数分为:有参构造和无参构造 按类型分为:普通构造和拷贝构造
三种调用方式:括号法、显示法、隐式转换法
拷贝:person(const person &p){age=p.age}//将传入的人的所有属性,拷贝到我身上
调用:
//括号法:void test(){person p1;} test();//调用默认构造函数时不要加() person p1;
//显示法:person p2=person(10);//有参构造 person p3=person (p2)//拷贝构造
Person(10)//匿名对象 特点:当前行执行结束后,系统会自动回收掉匿名对象
注意事项:不要利用拷贝构造函数,初始化匿名对象,编译器会认为person(p3)是对象声明
//隐式转换法:person p4=10//相当于person p4=person (10)
拷贝构造函数:1、使用一个已经创建完毕的对象来初始化一个新对象
2、值传递的方式给函数参数传值
3、值方式返回局部对象
初始化列表:语法:构造函数():属性1(值1),属性2(值2)...{}
Class person{
public:
//Person(int a,int b){m_a=a;m_b=b; } //person p(10,20)
Person(int a,int b):m_a(a),m_b(b){}
int m_a;
int m_b;}
类对象作为类成员:c++类中的成员可以是另一个类的对象
静态成员:+static
静态成员变量:所有对象共享同一份数据、在编译阶段分配内存、类内声明,类外初始化(int person::m_a=100)
STL:
Vector//数组
Vector<int>v;
V.push_back//向v中插入数据
Vector<int>::iterator itBegin =v.begin();//通过迭代器访问 v.begin()是起始迭代器,指向容器中的第一个元素
Vector<int>::iterator itEnd=v.end();//v.end()终止迭代器 容器中最后一个元素的下一个位置
While(itBegin!=itEnd){cout<<*itBegin<<endl;*itBegin++;}//第一种遍历方法
For(vector<int>::iterator it=v.begin();it!=v.end();it++){cout<<*it;}//第二种遍历方法
Void myprint(int val){cout<<val<<endl;}
For_each(v.gegin(),v.end(),myprint());//第三种遍历方法
Vector中存放自定义数据类型,并打印输出
Push_back()//尾端插入 pop_back()//尾部删除
Vector<T>v; vector(v.begin(),v.end());//将v【begin(),end())区间的元素拷贝给本身vector(n,elem)//将n个elem拷贝给本身 vector(const vector &vec);//拷贝构造函数
V1=v;//重载等号操作符
v.Assign(v1.beg(),v1.end());//将[beg,end)区间中的数据拷贝赋值给本身
Assign(n,elem);//将n个elem拷贝赋值给本身
V.empty();//判断容器是否为空
v.capacity();//容器的容量
V.size();//返回容器中元素的个数
v.resize(int num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。若容器变短,则末尾超出容器长度的元素被删除
V.resize(int num,elem);//重新定义长度为num,若变长,则以elem填充新位置
仿函数来改变默认排序:
Class mycompare{
Public:
Bool operator()(int v1,int v2){
//降序
Return v1>v1;
}
}
Map<int,int,mycompare>m;
For(map<int,int,mycompare>::iterator it=m.begin();it!=m.end();it++)
1、Pair<type,type>p(value1,value2); 2、pair<string,int>p2=make_pair(value1,value2);
Cout<<p.first<<p.second;
set容器默认排序规则从小到大,掌握如何改变排序顺序
Set/multiset容器:插入时会自动排序
构造:set<T>st;//T是数据类型
St.insert();//插入数据只有insert
Void printset(set<int>&s){
For(set<int>::iterator it =s.begin();it!=s.end();it++)//遍历
{Cout<<*it;}
}
Set容器特点:所有元素插入时候自动排序,不允许插入重复值
sort排序算法:sort(起始点,终点,顺序)默认情况下是升序从小到大
Sort(v.begin(),v.end(),greater<int>());降序排列
仿函数来改变默认排序: