/*C++知识点干货整理*/
最基础的-类:
class test
{
private:
public:
};
知识点1:指针数组
int* a;
a=new int[n];
知识点2:类的继承与派生
class A{
protected:
public:
};
class B:public A
{
protected:
public:
B(int aa,int bb):A(aa)
};
知识点3:运算符重载
//如果放在类内,作为友元函数,前面加friend
// >>重载:
istream& operator>>(istream& os,A& a)
{
a.input();
return os;
}
// <<重载:
ostream& operator<<(ostream& os,A& a)
{
a.output();
return os;
}
// 双目运算符重载
A operator+(A a)
{
A temp;
temp.x1=x1; //x1为运算符左边的类中的x1
temp.x2=a.x2; //a.x2为运算符右边的类中的x2
return temp;
}
bool operator>(line l)//也可以是bool类型的
{
if(len>l.len) return true;
else return false;
}
//单目运算符重载
常规:
A operator++()//++i
{
++i;
return *this;
}
A operator++(int m)//i++
{
A old=*this;
++(*this);
return old;
}
对于数组如果要重载要用vector,使用int* a的话要重载=,且i++的重载也不一样
test operator++(int m)//i++
{
test old(3);
int i;
for(i=0;i<n;++i)
{
old.a[i]=a[i];
}
++(*this);
return old;
}//记住old要一项一项赋值
test& operator=(const test& t)//重载=
{
if(a!=t.a)
{
n=t.n;
for(int i=0;i<n;i++)
{
a[i]=t.a[i];
}
}
return *this;
}//a要一项一项重新赋值,(const test& t)也要注意
知识点4:容器
//vector
^声明vector容器及其迭代器
vector<>a;
vector<>::iterator p;//<>中可以是不同的数据类型
^几个重要函数
a.push_back(temp);
a.begin();
a.end();//注意:a.end()是数组的最后一个数值+1
a.size();//数据量
a.eraze(p);//删除元素
^sort函数排序
sort(a.begin(),a.end(),cmp)//从大到小
sort(a.begin(),a.end())//从小到大
^排序规则函数 以结构体为例
static bool cmp(S s1,S s2)
{
return s1.score>s2.score;//这是从大到小排序
}
^迭代器指向结构体的数据
p=a.begin();
cout<<p->number<<endl;
^习题中出现的函数
char c=getch();
system("cls");//清屏
^检索
find函数用法:find(a.begin(),a.end(),temp)//find(起点,重点,要检索的数据)
复合元素检索规则函数:
struct S
{
int index;//加入此项可进行任意字段的检索
int number;
int score;
bool operator==(S s)
{
if(index=1) return number=s.number; //检索number
if(index=2) return score=s.score; //检索score
}
}//return中的=可以改成>和<,find函数则变为可检索大于temp和小于temp的元素
复合元素检索FIND函数
void Find()
{
S temp;
cout<<"input mode:";cin>>temp.index;
if(temp.index==1) cout<<"input find:";cin>>temp.number;
if(temp.index==2) cout<<"input find:";cin>>temp.score;
p=a.begin();
while(true)
{
p=find(p,a.end(),temp);
if(p!=a.end()) cout<<p->number<<"-"<<p->score<<endl;
else break;
++p;
}
}
//list
在某位置增加元素:a.insert(p,c);
//map
^增加元素只能用a.insert(pair<key,data>(key,data));
^使用iterator指向时,key为p->first,data为p->second,如果data为结构体,则(p->second).number来指向
^map中的find(s)查找的是键值
知识点5:计时器与多线程
//头文件
#include <windows.h>
#include <list>
#include <iomanip>
#include "basic.cpp"
//basic.cpp
^光标移动到指定坐标处
void gotoxy(int x,int y)
{
HANDLE h;//句柄,对象的索引
COORD c;//结构体,坐标值
c.X=x;
c.Y=y;
h=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(h,c);
}
^隐藏光标
void hide_cursor()
{
HANDLE h_GAME = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursor_info;
GetConsoleCursorInfo(h_GAME,&cursor_info);
cursor_info.bVisible=false; //不显示光标
SetConsoleCursorInfo(h_GAME,&cursor_info);
}
^显示光标
void show_cursor()
{
HANDLE h_GAME = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursor_info;
GetConsoleCursorInfo(h_GAME,&cursor_info);
cursor_info.bVisible=true; //显示光标
SetConsoleCursorInfo(h_GAME,&cursor_info);
}
^设置文本颜色
void color(int a)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}
//数据类型
clock_t t1;
t1=clock();
//常用函数
GetAsyncKeyState();//键盘输入
gotoxy(x,y);
hide_cursor();//隐藏光标
show_cursor();//显示光标
//key名称
VK_ESCAPE ESC
VK_SPACE 空格
VK_RETURN 回车
VK_UP 上
VK_DOWN 下
VK_LEFT 左
VK_RIGHT 右
VK_SHIFT shift
VK_LSHIFT 左shift
VK_RSHIFT 右shift
VK_CONTROL ctrl
VK_LCONTROL 左ctrl
VK_RCONTROL 右ctrl
VK_MENU Alt
VK_LMENU 左Alt
VK_RMENU 右Alt
VK_LBUTTON 鼠标左键
VK_RLBUTTON 鼠标右键
VK_TAB tab
知识点6:字符串
//头文件
#include<string>
#include<sstream>
//声明
string s1;
string s1="abcde";
string s1=s2;
string s1=(n,"c");//n为长度,c为字符,s1为n个c的字符串
//连接
s=s1+s2;
//常用函数
s.size();//长度 (数据类型为:string::size_type)
s.insert(n,"");//s.insert(开始位置,串)
s.erase(m,n);//s.erase(开始位置,长度)
s.replace(m,n,"");//s.replace(开始位置,替换长度,替换串)
s.max_size();//求最大长度(数据类型为:string::size_type)
s.substr(m,n);//取子串 s.substr(开始位置,终止位置)
//实例
#1<查找子串> s.find(s,开始位置)
若未找到,则s.find(s,0)==string::npos;
#2<模糊查询>
#3<数据处理>
string s="12-34-56-78-90";
string t;
long n1,n2,pos=0;
while(true)
{
n1=s.find("-",pos);
n2=s.find("-",n1+1);
t=s.substr(n1+1,n2-n1-1);
cout<<t<<endl;
pos=n2;
if(pos+1>=s.size()) break;
}
string s="-王小一-67-李小二-89-张小三-95-";
string t1,t2;
long n1,n2,n3,pos=0;
while(true)
{
n1=s.find("-",pos);
n2=s.find("-",n1+1);
n3=s.find("-",n2+1);
t1=s.substr(n1+1,n2-n1-1);
t2=s.substr(n2+1,n3-n2-1);
cout<<t1<<endl;
cout<<t2<<endl;
pos=n3;
if(n3+1>=s.size()) break;
}
#4<倒序>
string reverse(string s)
{
string::size_type i,n=s.size();
string temp=s;
for(i=0;i<n;++i)
{
temp[i]=s[n-i-1];
}
return temp;
}//这种方法倒序的汉字会乱码
#5<变码>
string change(string& s)//加引用,否则有些编译器无法正确返回
{
string::size_type i,n=s.size();
for(i=0;i<n;++i)
{
s[i]=s[i]+n;//n为int
}
return s;
}
#6<解析词条>
string s="a b",s1,s2;
string::size_type n1,n2;
n1=0;
n2=s.find(" ",n1);
s1=s.substr(n1,n2-n1);//s1="a"
/**********************************/
n1=n2+1;
while(true)
{
if(s[n1]==' ')
++n1;
else
break;
}//找到了另一段词条
n2=s.size();
s2=s.substr(n1,n2-n1);//s2="b"
#7<是否为数字> isdigit(s[i])
int flag=1;
for(i=0;i<n;++i)
{
if(!isdigit(s[i]))
{
flag=0;
break;
}
}
#<转int>
int str2num(string s)
{
stringstream ss;
int temp;
ss<<s;
ss>>temp;
return temp;
}
知识点7:文件与数据库
//头文件
#include <fstream>
//读写文件(基础)
ofstream f1("t.txt",ios::out)//写文件
ifstream f2("t.txt",ios::in)//读文件
if(f1)
{
f1<<s<<endl;
f1.close();
}
else cout<<"write file error!"<<endl;
if(f2)
{
f2>>s;
cout<<s<<endl;
f2.close();
}
else cout<<"read file error!"<<endl;
//文件名作形参
string read_file(string filename)
{
ifstream f(filename.c_str(),ios::in);//.c_str
string s;
if(f)
{
getline(f,s);//把f的第一行读出来(可以读空格)
f.close();
}
else cout<<"open file error!"<<endl;
return s;
}
//使用getline()读取很多行
while(getline(f,s))
{
cout<<s<<endl;
}
//在已有文件尾添加内容
ofstream f;
f.open("test.txt",ios::app);
f<<endl;
f<<n<<endl;
//读取多行并压入容器
ifstream f;
vector<int> a;
f.open("test.txt",ios::in);
int temp;
while(!f.eof())//文件流、文件句柄、结束标志:.eof()
{
f>>temp;
a.push_back(temp);
}
cout<<accumulate(a.begin(),a.end(),0)<<endl;//自动求和 accumulate(起点,终点,初值)
^注意:以上方法读取整数,若结尾有回车或空格,则文件的最后一项整数会被压入数组两次
//二进制文件
^字符串分配空间:s.resize(n)
^指针操作读:seekg(0,ios::)
^指针操作写:seekp(0,ios::)
^当前位置:f.tellg() f.tellp()
^参照位置:
ios::beg文件头
ios::cur当前位置
ios::end文件尾
^文件读写
f.read((char*)变量,长度)
f.write((char*)变量,长度)
^指针锁定
指针进入.eof()位置时将锁定,要使用f.clear()解除锁定
^fstream ("test.txt",ios::in|ios::out|ios::binary);//in&out以读写方式打开 binary以二进制方式打开文件
^应用实例
string s="123";
int n=123;
f.write((char*)s.c_str(),s.size());
f.write((char*)&n,sizeof(n));
^软件汉化
转化前后字符串应等长,一个汉字等于两个英文字母
&以下知识点不是基础知识点,建议先学习上面七个知识点再学习以下知识&
&以下知识点请靠例程理解&
知识点8:模板
template<class T>
T add(T a,T b)
{
return a+b;
}
void Swap(T& a,T& b)//注意:swap与库函数重名
{
T temp;
temp=a;
a=b;
b=temp;
}
T str2T(string s)
{
stringstream ss;
T temp;
ss<<s;
ss>>temp;
return temp;
}
使用时:add<>(a,b)//<>内可为int/double,为函数return的数据类型
类模板(示例):
template <class T>//模板语句
class test
{
private:
T a,b;
public:
test(T aa,T bb)
{
a=aa;
b=bb;
}
//注意:参数不能是(string s),要与a、b的类型T匹配
int str2num(T s)
{
int temp;
stringstream ss;
ss<<s;
ss>>temp;
return temp;
}
void add()
{
if(typeid(T)==typeid(int))//判断模板参数的类型
{
cout<<a+b<<endl;
}
if(typeid(T)==typeid(string))//判断模板参数的类型
{
cout<<str2num(a)+str2num(b)<<endl;
}
}
};
int main()
{
test <int> t1(1,2);//注意:多了"<int>"一节,是类型实参
t1.add();
//==================
test <string> t2("10","20");//注意:多了"<string>"一节,是类型实参
t2.add();
return 0;
}
知识点9:虚函数
示例:
class A
{
protected:
int m;
public:
A(int mm)
{
m=mm;
}
virtual void output()
{
cout<<"m="<<m<<endl;
}
};
class B:public A
{
protected:
int n;
public:
B(int mm,int nn):A(mm)
{
n=nn;
}
virtual void output()
{
cout<<"n="<<n<<endl;
}
};
int main()
{
A a(10);
B b(20,30);
A* p;
p=&b;
p->output();
return 0;
}
知识点10:析构函数
在class中:
~test() {}
示例:
~test()
{
delete(a);//释放数组a空间
}
知识点11:命名空间
using namespace ns1;
class test{};
using namespace ns2;
class test{};
int main()
{
ns1::test t1;
ns2::test t2;
}
知识点12:异常处理
//手动抛出异常数据
示例:
class test
{
private:
double m,n;
public:
test(double mm,double nn)
{
m=mm;n=nn;
}
void ave() throw(int)
{
if(n>1)
cout<<m/n<<endl;
else if(n==1)
throw 1;
else if(n==0)
throw 0;
}
};
int main()
{
test t1(10,6),t2(10,1),t3(10,0);
try
{
t1.ave();
t2.ave();
t3.ave();
}
catch(int n)
{
if(n==1)
cout<<"devided by 1!"<<endl;
else if(n==0)
cout<<"devided by 0!"<<endl;
}
return 0;
}
//使用异常类
class test
{
private:
double m,n;
public:
test(double mm,double nn)
{
m=mm;n=nn;
}
void ave() throw(invalid_argument)
{
if(n>1)
cout<<m/n<<endl;
else if(n==1)
throw invalid_argument("devided by 1");
else if(n==0)
throw invalid_argument("devided by 0");
}
};
int main()
{
test t1(10,6),t2(10,1),t3(10,0);
try
{
t1.ave();
t2.ave();
t3.ave();
}
catch(exception& e)
{
cout<<"error:"<<e.what()<<endl;
}
return 0;
}
//手工调试:预编译指令
#pragma once//防止重复包含文件
#include <iostream>
#include <iostream>
using namespace std;
#define _DEBUG//调试开关
class test
{
private:
int n;
public:
test(int nn)
{
n=nn;
#ifdef _DEBUG
cout<<"test::test()"<<endl;
#endif
}
void square()
{
cout<<"square="<<n*n<<endl;
}
~test()
{
#ifdef _DEBUG
cout<<"test::~test()"<<endl;
#endif
}
};
int main()
{
test t(5);
t.square();
#ifdef _DEBUG
cout<<"================="<<endl;
#endif
return 0;
}
#####*****end*****#####
本资料集锦依照刘东明老师“高级语言程序设计Ⅱ”课程编辑,代码从课上练习及课后习题中整理,教材《C++语言简例教程》-电子科技大学出版社-刘东明著。
整理者:newenergy_freshman
本资料中有内容为个人理解,部分代码可能不规范,欢迎读者指正
联系方式:985498066@qq.com
本资料只可作学习用,禁止用作商业用途,转载请注明出处。