C++知识点总结

注记:面向对象编程(OOP)
1.头文件

#include<iostream>//输入输出流头文件
using namespace std;  //using编译指令。主要用于std,也可表示为std::,std为名称空间,也可变
#include<cmath>  //函数文件:sqrt(a)、pow(a,b)、rand()等函数
#include<climits> //符号常量表示类型限制,INT_MAX表示int能存储的最大值、LONG_MIN是long的最小值
#include<algorithm>//算术函数文件
#include<cstring> 可以使用字符串以及字符串的一些函数:strlen(str);  str.size();可有getline(cin,str);输入字符串
#include<cctype> //字符函数库:isalpha(ch);ch是否为字母,ispunct(ch),是否为标点,isdigits();是否为数字,isspace();是否为空白,islower()是否为小写字母,tolower(),返回小写,toupper()返回大写
#include<fstream> //文本文件操作的头文件,参见:https://blog.csdn.net/hbqjzx/article/details/86525693
1.ofstream outFile;//声明自己的ofstream对象
2.outFile.open("文件名");具体参见:https://blog.csdn.net/weixin_43971252/article/details/103999802

int main() =int main(void)   //表明函数不接受任何参数
{
  return 0;  //仅仅适用于main函数
}

2.输入输出

包含头文件为 #include<iostream>,则有cout、cin
cout<<"字符串"<<endl;  endl为换行
cin>>a;
读取一行字符串输入:getline()、get()
char name[20];
cin.getline(name,20);//将字符输入一个包含20个元素的name数组中,每次读取一行,换行符表示行尾
cin.get(name,20);同样,不过如果有连续行输入,则在中间加入cin.get(),若有读取空行,则需要添加cin.clear()来恢复
也有连续读行为:cin.getline(name,20).getline(array,10);
1.char ch;
2.cin.get(ch);//读取字符时,最好用get(),否则可能造成空字符未读入
cin.ignore(224,'\n');  //读取并丢弃接下来的224个字符,或到达第一个换行符
3.while(cin.fail()==false)//用fail()函数来检测是否到达最后一个输入,用于文件尾条件,EOF代表没有字符,所以也可以用while(ch!=EOF)
注:read():读取指定数目的字节、peek():返回输入中的下一个字符;gcount():返回最后一个非格式化抽取方法读取的字符数;putback()将一个字符插入到输入字符串中

如果为输入流,则为while(cin>>a){}
包含头文件为:#include<stdio.h> ,则有printf、scanf
printf("%d",a);
scanf("%d\n",&a);
cout.fill('*');将填充字符改为*
cout.precision(2);//设置精度为2,即保留两个数,四舍五入cout<<fixed<<a<<;//保留小数点后两位
cout.setf(ios_base::showpoint);//显示末尾的0(showpos:在正数前加+,uppercase:对于16进制输出,使用大写字母,E表示法,left:左对齐)

3.数据

变量名:只能使用字符字符、数字和下划线,第一个字符不能是数字,对长度没有限制,一般为第二个单词的首字母大写
数据类型:short(16位)、int(32位)、long(至少32位)、char(表示字符)、long long
浮点型:float、double、long double
位即bit,1字节=8bit,1KB =1024字节,1MB = 1024KB
字符A为65,a为97,A+32 = a;
转义序列:\\、\?、\"、
boo类型:只有真假
const:const int a;限定常量的符号名称
数组:类型 a[size]:数组下标都是从0开始   int a[] ={0,1,5,6};
二维数组:int a[][3] = {{1,2,4},{2,4,6},{7,5,9}};必须包含列数其他的方式参见:https://blog.csdn.net/Ginny97/article/details/109248707
字符串:形如:char a[]={'a','0','c'};或者char fish[] = "Bubbles";字符串结尾通常会有‘\0’字符(空字符)
string类:string s1,s2;(合并:string s3=s1+s2;附加:s1 += s2;)
string 的其他操作:strcpy(s1,s2);复制2到1中,strcat(s1,s2);将字符串2加到1末尾.strcmp(s1,s2),比较两者是否一致
auto 自动变量
static 静态持续变量,作用时间长,一直存在于程序执行期间,const类似于它

4.结构(类似数据存储,只不过存储的数据格式可以不同)

struct structname
{
   int ;
   float ;
};
int main()
{
  strcutname  guest = {1010.2}  //定义结构体内的某一个结构变量的初始化,逗号隔开

}
也有:
struct structname
{
   int ;
   float ;
}quest,quest2;//来创建结构变量
结构数组:structname array[100];则会有array[i].int;
共用体(union):类似结构,但是只能存储一种数据类型,比如int,则只能存储int、long、double(自行了解)

5.枚举

句法与结构类似:enum spectrum{red,orange,yellow,green,blue,violet,indigo,ultravuolet};
其中red、orange、yellow等作为符号常量,对应整数为0~7,即为枚举量,默认从0开始,也可自行设置(enum bits{one = 1,two = 2,...}或者enum{first,second= 100,third}),其中first默认为0,后面没有初始化的枚举量将比前面的枚举量大1.
若选取的数值不是枚举值,但是在枚举的取值范围内,那么依旧合法;
可以用枚举名声明变量:spectrum band;band = blue;

6.指针

指针是一个变量,存储值的地址,而不是值本身;指针需要初始化为一个确定的、适当的地址
一般可以使用new来实现内存分配:形如 int *p = new int;分配一个int内存//内存不够将引发new返回0,造成程序越界
使用delete来释放内存:delete p;//释放p指向的内存,但不会删除p指针本身(只能用delete来释放new分配的内存)
如果是动态数组,则为:int *p = new int [5];  delete [] p;,一一对应,p指向第一个元素的地址(p[0]、p[1]...代表实际元素)
注:一般结构标识符为结构名时,使用句点操作符.,若标识符为指向结构的指针,则使用箭头操作符->
int a = 5int *p = &a;//将p的值设置为 a 的地址;*p为a 的值,即*p为指针解引用
int *p = new int[5];
int *p = array;//其中有int array[] = {};有实参。
如果字符数组名前为char,则默认为带有指针,且指针指向字符串的开头
int main()
{
	char flower[10] = "rose";
	cout<<flower<<"s are red !"<<endl;
}
 输出为:roses are red !
如果是字符串:则需根据字符串的长度指定所需的空间:
p = new char[strlen(array)+1];  //得到新空间,加空字符时字符串长度与array一致
此时可以用函数strcpy(p,array);实现复制
使用new和delete搭配可以实现动态存储,可以做到一个函数存储,另一个函数释放。若只使用new,很容易引起内存泄漏,尤其在堆和堆栈中

7.循环

for循环
for(初始值;测试;更新操作){}
a++代表使用a 的当前值进行计算表达式,然后将a+1++a表示先将a加1,再用新的值进行表达式计算;
循环中虽然差别不大,但是对于类而言,前缀效率更高,故较多使用++a
优先级:*++p;先+*++*p;先*+*p++:先*+
特例:
char word = ">ate";//比较两者是否一致
for(char ch = 'a';strcmp(word,"mate");ch++)
假设为:string word = "?tae";
for(char ch = 'a';word!="mate";ch++)
while循环
while(测试条件){}
do 
{}while(测试条件)

8.分支语句和逻辑操作符

if语句
if(测试条件){}else{}
逻辑表达式:或 ||、与 &&、非!
?:操作符:a > b ? a : b;
switch
switch(变量,必须为一个整数值表达式)//可使用break来跳出
{
   case label1:   //label1可以为整数,也可以为'a'字符型
       操作;
   case label2:
   ....
   default :
}
break:使程序跳到循环体后面的语句执行;
continue:使程序跳过循环体中余下代码,开始新一轮循环;

9.函数

定义:两类,有返回值和无返回值
void function() {return;}    无返回值
type function() {return type}  返回值和函数类型一致
arra(const int a[],int n)//加const的目的是为了不改变原始数组
当用const去用于指针时,目的是为了不改变指针所指的值以及指针指向的位置
function(int a[][4],int size)相当于function(int (*a)[4],int size),size为行数
function(char *str,char ch)
若要返回一个字符串,则有 char *buildstr(char c,int m);    赋值为 char *p =builestr(ch,times);再使用过程中,可以在最后删除p:delete [] p;
结构与函数,直接定义结构为数据类型即可:function(structname name1,structname name2)
也可以传递结构的地址:function(const structname *p),在main函数中定义{ structname name;function(&name) }
string对象:function(string a[],int n)  用数组解决
递归:参见https://blog.csdn.net/u012936940/article/details/79672460
函数指针:1.获取地址:process(function);获取函数的地址返回    thought(think());调用think,获取其返回值,非地址
  2.声明函数指针:int *function() ,参见:https://blog.csdn.net/luoyayun361/article/details/80428882
  注:double (*pf) (int):意味着pf是一个指向函数的指针,double *pf (int):意味着pf()是一个返回指针的函数
  例:double pam(int);double (*p)(int); p = pam;  double x = pam(4)  double y = p(5)或者(*p)(5) ;   

10.函数进阶

内联函数:
速度快、但是占内存  (空间换取时间)
其主要是对于内联代码,无需跳跃到另外一个位置处执行代码,即不用来回跳跃地址,常规函数,需要跳到函数地址执行,再跳回执行下一步代码地址。
内联函数偏向用于代码执行时间很短,或者经常被调用的代码,内联函数不能递归
内联函数的格式:inline double function()   //函数定义与声明均要加关键字inline
补充知识点:宏定义:类似#define SQUER X*X 这种就是宏,不加引号
引用变量:
即变量的别名,主要用于函数的形参,使得原始数据可以被直接引用,而不是拷贝
创建引用变量:int a; int &b = a;//其中&为类型标识符,而不是取地址符,即指向int的引用
作为函数参数时,即为 int a,b; void function(&b,&a),即可进行传递
引用用于结构:const structname &function(structname &name);
引用用于类对象:const string & function(string s1,string s2);
默认参数:
int function(int a=1,int b=0)//设置默认参数
函数重载即,函数多态
函数名相同,当函数输入不同,结果不同:int function(int a) int function(int a,int b),输入自动选择函数
函数模板
即内置函数,直接使用函数即可,重载模板为同功能,输入不同;
显示具体化:即只交换或者改变结构中部分变量:template <class 类名>   void swap(类名 &name,类名 &name)
函数定义为: template<> void function<structname> (structname &name,structname &name)

11.对象和类

类的默认访问为private,结构的默认访问为public
class 类名
{  
  float   ;
public:
void function();  //类声明中的函数均自动成为内联函数
};
定义成员函数时,表示为: void 类名::function(),
类构造函数:默认构造函数为:**类名::类名(){}**,目的是为了将对象初始化,
析构函数:将创建的对象清除,自动调用:**类名::~类名()**      //构造函数与析构函数一般要联用
具体可参见:https://blog.csdn.net/wue1206/article/details/81137353
this指针
每个成员函数(包括构造和析构)都有一个this指针,指针指向调用对象,相当于存放着这个类的地址
具体参见:https://blog.csdn.net/m0_37925202/article/details/78334358
简单点解释为:如果一个类D,两个对象A、B,有内部成员函数top()比较两者某一属性,则有
 top = A.top(B);或者 top = B.top(A);函数定义为:const D &D::top(const D &B) const{},则此时函数调用过程中A为隐式,B为显式,那么this指针就指向A的地址,反之若参数为A,则this为B的地址
this指针只能在一个类的成员函数中调用,它表示当前对象的地址。下面是一个例子:
    void Date::setMonth( int num ) 
    { 
     month = num;             // 这三句是等价的 
     this->month = num; 
     (*this).month = num; 
    }
对象数组  
要创建类对象数组,则**这个类必须有默认构造函数**;
若有类D,构造对象数组为: D a[10];
初始化数组元素为:D a[10]  = {D(数据1、数据2...),D(数据1,数据2...)};
修改类的私有部分和实现文件属于实现更变,修改类的公有部分属于接口变更,
**实现**改变了类的内部工作原理,**接口**改变了使用类的人的编码方式

12.使用类

操作符重载
操作符重载是一种C++多态
参见 http://www.cnblogs.com/ZY-Dream/p/10068993.html
形如:重载+(类D)
D operator+ (const D &d){}   d为对象    //在类外,依旧要 D::D operator+ (const D &d),作用域下
举个例子:Int为一个类
bool operator ==(const Int&a) {
    if (i == a.i) return true;
    else return false;
}
void operator +=(const Int&a) {
    i += a.i;
}
友元(友元有三种:友元函数、友元类、友元成员函数)
友元的目的是为了赋予其与类相同的访问权限,
友元函数:形如: friend D operator*(double , const D &d);//函数声明用friend,即将原型放于类声明中
重载:矢量类
转换函数、类型转换       //自行了解 https://blog.csdn.net/qq_23851075/article/details/52723684

13.类和动态内存分配

返回对象: D function(const D &d1,const D &d2)  =  const D & function(const D &d1,const D &d2)   ,但是第二种用引用,效率更高
queue队列:https://blog.csdn.net/qq_41856733/article/details/84202010
扩充:

14.类继承

基类:
class D
{
private:
public: 
};
派生类:子类:
class A: public D    //A继承D的公有属性,包括数据成员和方法
{
};   //子类需要自己的构造函数和额外的成员函数
子类的构造函数要求:1.基类对象首先被创建;2.应初始化新增的数据成员;3.应通过成员初始化列表将基类信息传递给基类构造函数
多态公有继承
1.在子类中重新定义基类的方法;2.使用虚方法,这两种情况需要多态公有继承
virtual 只用于类声明的方法中:参见 https://blog.csdn.net/haoel/article/details/1948051
父类一般析构函数为虚析构函数,防止出错:
构造函数不能是虚函数,析构函数应当是虚函数,除非类不用做基类,友元不能是虚函数,只有成员函数才能做虚函数,如果定义的类作为基类,则将那些在派生类中重新定义的类方法声明为虚拟的,即同方法虚拟
若基类方法声明被重载了,则在子类中需要重新定义所有的基类版本
包含纯虚函数的类只能做基类;纯虚函数,结尾=0
protected 在类外,保护成员与私有成员一致,但对于子类,保护成员与公有成员一致
在项目中,在类定义中先被声明的函数先初始化
补充:私有继承:使用私有继承,则基类的公有成员和保护成员将成为子类的私有成员,即为class D:private: B.
虚基类:即使得多个类派生的对象只能继承一个基类对象,用于多重继承
析构函数执行顺序与构造函数相反:构造:父到子,析构:子到父。
包含:参见:https://blog.csdn.net/powder_snow/article/details/79367836
C++添加了四个类型转换运算符,以便更严格地限制类型转换。
dynamic_cast;
const_cast;
static_cast;
reinterpret_cast.
友元、异常、参见:https://blog.csdn.net/dxy18861848756/article/details/113871493
RTTI只适用于包含虚函数的类

15.string类及模板库

参见:https://blog.csdn.net/qq_32900237/article/details/89328478
智能指针的创建需要包含头文件memory;其是一种类,即其对象的特征类似于指针
只能对new分配的内存使用auto_ptr对象,不能对new[]使用
STL模板库:(11个容器种类:deque、list、queue、priority_queue、stack、vector、map、multimap、set、multiset、bitset)
vector模板类
常用函数:
empty():判断向量是否为空,为空返回真,否则为假
begin():返回向量(数组)的首元素地址
end(): 返回向量(数组)的末元素的下一个元素的地址
clear():清空向量
front():返回得到向量的第一个元素的数据
back():返回得到向量的最后一个元素的数据
size():返回得到向量中元素的个数
push_back(数据):将数据插入到向量的尾部
pop_back():删除向量尾部的数据
.....
//例子
#include<iostream>
#include<vector>
using namespace std;
int main()
{
	vector<int>vec;
for (int i = 1; i <= 5; i++)
{
	vec.push_back(i);
}
for (int i = 0; i < vec.size(); i++)
	cout << vec[i] << endl;
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
{
	cout << *it <<" ";
}
system("pause");
return 0;
list模板类(双向链表)
常用函数:
初始化: a(n,t);由n个t值组成的序列
begin():返回list容器的第一个元素的地址
end():返回list容器的最后一个元素之后的地址
rbegin():返回逆向链表的第一个元素的地址(也就是最后一个元素的地址)
rend():返回逆向链表的最后一个元素之后的地址(也就是第一个元素再往前的位置)
front():返回链表中第一个数据值
back():返回链表中最后一个数据值
empty():判断链表是否为空
size():返回链表容器的元素个数
clear():清除容器中所有元素 =erase(begin(),end());
insert(pos,num):将数据num插入到pos位置处(pos是一个地址)
insert(pos,n,num):在pos位置前插入n个元素num
insert(pos,i,j):在pos位置前插入区间[i,j]的元素
erase(pos):删除pos位置处的元素
erase(pos,qos):删除[pos qos]之间的元素
push_back(num):在链表尾部插入数据num
pop_back():删除链表尾部的元素
push_front(num):在链表头部插入数据num
pop_front():删除链表头部的元素
sort():将链表排序,默认升序
......
成员函数:
merge(list)  合并
remove(val)  删除val值的所有
quique()  将重复元素删除为一个
map模板类
常用函数:
begin():返回容器第一个元素的迭代器
end():返回容器最后一个元素之后的迭代器
rbegin()rend()clear():清除容器中所有元素
empty():判断容器是否为空
insert(p1):插入元素  p1 是通过pair函数建立的映射关系对
insert(pair<char, string>('S', "shenzhen")): 插入元素
size():返回容器中元素的个数
count():返回指定键对应的数据的出现的次数
get_allocator():返回map的配置器
swap():交换两个map容器的元素
revers(): 反转
.....
pair<class a,class b>   //成对存在
迭代器:形如:vector<int> ::iterator it;数组为单向迭代器,list为双向迭代器    //
for(it=v.begin(); it!=v.end(); it++)
set模板类
可翻转、可排序,关键字唯一
常用函数:
begin();第一个元素
成员函数:
sort()
copy()
find()
set_difference()
transform()
next_permutation()自动提供唯一的排列组合    while(next_permutation(begin(),end())){cout<<;}//全排列,唯一

16.文件输入和输出

参见:https://blog.csdn.net/zouxu634866/article/details/88139382
以及 https://blog.csdn.net/shs1992shs/article/details/83043522

致谢:C++ Primer Plus 至此结束,后续会对内容进行不断的补充,谢谢~~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值