C/C++基础学习笔记
1 注释
1.1 行注释
块注释:
(1)#if 0
#endif
(2)/* */
<>:表示系统文件
<stdlib.h>+syetem 调用windows中的程序
1.2 QT中
ctlr+I 自动对齐
ctlr+/ 自动注释
1.3 VS 2013中
system需要调用#include windows.h使用
防止命令框闪关:system("pause");
math.h 中 pow(x,y) x的y次方
2 字节概念:
位(0,1)简称bit --8个位>字节 简称BYTE --2个字节> 字 简称WORD --2个字> 双字 简称DWORD
sizeof():配合%lu输出,表示在内存当中所占位置大小
#define MAX 100 宏常量
const int max=0; 常量定义 max的值不能被改变
volatile 程序不会被优化
redisdter 放在寄存器中,建议指令
常量中除了字符串常量有内存地址外,其余的都没有地址
int类型占4个字节
char类型中:
"\b "退格一个一个末尾字符
"\t" 横向制表符,一个 Tab 位
输出特殊字符需要加转义字符:\
char 'a’常量,内存只存一个字符 a
char a 字符变量
'\0' 表示ASCII码值为0的字符
0 表示数字 0
'0'字符0标的ASCII码制为48
"0"由0字符+字符串结尾的默认值
输出类型:
putchar 输出一个字符
printf 输出一个字符串 %s 输出是一个字符串
%p输出打印地址
%和d之间加个数字,决定它输出字节数 “-” 左对齐
%c输出单个字符
%.和f之间加数字,决定输出几个小数
%p:输出某个数的地址
%d:按十进制输出:
%o:按八进制输出
%x:按十六进制输出
%u;按无符号位输出
%数字1.数字2f(lf),数字1输出字节数 数字2输出小数点数
scanf_s 输入
需要写入地址:&
输入字符时时:注意字符会被回车键接受(一般用getchar接受)
b=a++ 先做表达式值,在自加
b=++a 先自加,在做表达式
getchar() 与printf("%d",a);等待输入一个字符,然后输出他的ASCII码值
输入一个字符串:gets(a) a必须为一个字符串数组,用puts输出
变量的定义:
形式:数据类型 变量名:
变量的初始化:数据类型 变量名=初始值;
整数与整数相除一定是个整数。
输入输出文件需要包含头文件 stdio.h
输出的值一定初始化
例:i=2;j=i*i++ 得出来的值j为6;
if中:无大括号的情况下,默认带下面一个语句
switch()
{
case 常量表达式1:
语句1;
case 常量表达式2:
语句1
case 常量表达式3:
语句1
}
语句后要加break;执行符合值的语句后退出
最后加default:执行没有符合条件的default后的语句:
for(赋值语句1;判断语句2(不可缺少);表达式语句3)//没有语句2时,默认为1,进入死循环
语句1:初始运行一次->对语句2进行判断(为真进入循环体,执行语句3;为假跳出循环体)
while(表达式)//没有表达式时,直接编译不通过
负数在计算中放的是补码
原码、反码、补码:
正数的补码为源码,
负数的补码到源码:符号位不变,按位取反,再加1;
数组的定义:
类型 数组名[常量] 定义的常量个数 下角标总数为常量-1;存储地址相邻
定义方法:未对数组进行复制,电脑随机分配数
只定义一部分,数组后面只默认为零
数组名[常量]={值} 数组统一赋值
数组名[]={值,值二.......} 常量由值数决定
"asdsad"后面自带\0
注意:初始值中间用 , 分开
求数组大小 运用sizeof(a)/sizeof(a[0])
随机数函数:
rand() 产生随机数不变
srand(常量) 常量不变,产生的随机数不变 注意:不产生数,只是一个种子,将种子
给rand产生随机数
运用rand 和% 确定随机数范围
例:
结合时间使用:
srand(int(x=time(NULL)));
rand();
例 产生27到127的随机数 rand%101+27
gets()输入一个字符串放进数组,认为回车代表输入完成,空格只是字符串中的一部分而已
fgets(开始存的起始地址,输入的个数,stdin) stdin表示输入
多文件编译:
#ifndef 常量名
#define 常量名
#endif 常量名
指针
* 解引用 单目运算符
形式 *指针变量 把指针变量指向的内存空间的数据取出来
*是简介索引,是把指针变量保存的数当成地址,去地址里面取数据,能取几个字节,取决于指针变量的修饰符
*p *p表指针指向变量的值,p代表指向变量的地址//定义一个指针变量,而指针变量p只储存地址
*p 只能接受地址,不能直接负常量
*p 输出指针的到的值
p 输出为地址 (p-p1)得出俩个的距离值
*p 如果没有进行取值赋值,不能直接赋值。例:int *p ,i=1 *p=2 定义直接报错 经过取址后:p=&a; *p=2 输出后 i连同*p的值一起改变为2
指针只有接受过非指针地址后,才能接受赋值(或定义的时候间接赋值:int a=0;int *p=&a)
用相同数据类型的指针,不要混用。必须使用相同类型的指针
统一系统下,不管指向什么样类型的变量,地址大小总是一样的
void *p 无类型的指针
int *p p=NULL; 空指针,没有明确的指向某块变量。NULL在c语言里面是一个宏,值为零
针对数组,关于指针变量的取指能力
常量指针
int a
const int *p=a//p是一个变量,可指向一个变量或者常量
p可以指向一个int类型的地址,不可以通过*p改变内存值。但可以指向其他地址
例:指针常量
int const *p2;//const在*之前,用以修饰地址类型,表示不能通过*p去修改
const在*之后,用以修饰指针变量
int *const p2=&a//p是一个常量,不可以指向其他数据空间地址,p2指向固定的变量地址,可以通过*p2读写这个变量的值
const int *const p//既不可以改变指向的地址,也不能通过*p改变值
指针指向数组时
int a[100]
p=a;
p=p+4等价p[0+4]
指针计算,改变的是地址
p:指针变量的的地址
*p:指向的地址的值
&p:取指针变量p在内存中的地址
char *str="hello itcast"//字符串常量,不能修改
c语言中所有数据类型都可以理解成一个char类型的数组
二级指针赋值:必须先取一级指针地址
字符串
字符串指针数组中,只要获得首地址,即可打印出字符串
例 char *str="hello itcast";printf("%s",str)
main(char argc,char **args) main函数参数 输入的数字的地址自动填充给args[i]
字符串查找:例:strstr(str1,str2)//str1和str2为字符串。
字符串的分割:运用指针接受后,可进行多次分割:例char *strl strl=strtok(数组首地址,"分割符号"),后循环判断while(strl)strl=strtok(NULL,"分割标志")
清空函数:例memset(a,0,8),数组名,被覆盖后显示的值,覆盖内存大小(字节)
覆盖函数:memcpy(a,b,字节数),将b中多少个字节数拷贝到a中
auto(自动变量):一般情况下函数内部定义的变量都是动态auto类型的便量。只在自己作用域有效
static(静态变量):只初始化一次,与大括号的出现无关。程序开始时被创建,程序结束生命周期结束。.注意:不能在其他文件试用。有同名时,优先使用本区域的作用域的值。
变量冲突的概念:变量名相同,作用域也相同,就会冲突
在代码块外定义的变量,即默认为全局变量或者叫文件变量
extern :声明文件至之外的东西
内存分区的意义:
代码区:存放代码,只能执行--------只读区
静态区:全局变量和静态变量全在其中。只在程序消失的时候才会释放。静态函数只影响他所作用的区域,其他文件不可见,它在代码区 (常量区:const类型的常量、字符串常量----------只读区;全局区:;静态区:;)
栈区:自动变量,函数的形参,函数的返回值。一种先进后出的
堆区:需要手动分配(malloc())和释放(free())。malloc(常量值)// 在堆中分配常量值个字节空间,返回的是一个void *类型。需要手动释放free():1.一定要释放,不然会造成内存泄漏2.一定不能多次释放,释放前要接受首地址。(1)数组大小不确定或者很大的时候,使用堆-(2)malloc分配的值是随机、不确定的--------例:char *s=malloc(10);strcpy(s,”abcd”);printf(“%s”,s); free(s)
malloc的参数是指定分配的大小,单位:字节。要用memset清空
calloc的第一个参数是指定单位的数量,第二个参数是指定一个单位的大小,内存自动清空
rellaoc(扩大的名字,扩大后 的大小)。用realloc增加的空间也不会自动清零
概念:函数不能直接返回auto类型的地址
结构体的定义和初始化:
struct 结构体类型名
{ 结构体成员的数据类型 结构体成员的名};
例: struct student st;//定义一个student类型的结构体变量,名字叫 std。
结构体变量的初始化:(1) struct 结构体类型名 结构体变量名={初值},按照成员顺序赋值
(2)struct 结构体类型名 结构体变量名={结构体成员名};指定成员进行赋值。
结构体变量之间的赋值是可以用“=”,实际上就是内存拷贝。如果是结构体指针,也要开闭堆空间。如果结构体成员中有指针,注意需要指针先指向堆,让指针有明确的地址。结构体中的堆内存需要释放干劲(注意结构体成员中数组和指针对堆的释放,释放后把它定义为空)
结构体中:在变量的时候,使用 . 例 (*p).结构体成员。在地址的时候,使用->,例 p->结构体成员名
typedef
typedef unsigned int size_t; 结构体成员间的赋值:字符串用strcpy,整型和字符可以直接用 =;
文件操作中,
文件的读取(用 r 模式打开):
getc:要读取所有字符,文件内容以“EOF”结尾 例:利用while(c!=EOF)循环c=getc(p) 一个个接收,之后输出c;
fgets: 读取一行字符串,如何到文件以结尾停止:(1)用feof函数,例if(feof(p)) break;//到结尾跳出循环。例:fgets(buf,sizeof(buf),p);(2)例:while(fgets(buf,sizeof(buf),p)!=NULL),如果函数值返回为NULL,及到达文件末尾,跳出循环。
fscanf:按格式读取文件中的数据到某个变量中去。例:fscanf(p,”%s%d”,s,&a),返回值为匹配的项数
文件的输入(用 w 模式打开):
putc 写入一个字符或者一个整型;例:putc(1,2); 1:需要写入的字符,2:被写入文件的指针
fputs 写入一个字符串;例:fputs(1,2) 1:需要写入的字符串,2:被写入文件的指针(字符串的输入接受用fgets(buf,sizeof(buf),stdin))
fprintf:将数据中变量,输出到文件中。例:fprintf(p,”%s%d”,a,b);
文件拷贝的实现:
先读出文件中数据,c=getc(p);然后写入另一个文件,putc(c,p1);循环读取,因为文件最后以EOF结尾
C++:
C++分配堆,直接用关键词 new,释放用delete关键词(数组释放[]p)
函数重载的规则:函数名同名,但是参数类型、个数不同
pthread(线程程序)在Linux系统下编译。gcc main.c –o app –std=c99(如果在编译过程中出现c99)
pow函数的使用方法?
这俩条指令在那里使用: 删除文件remove(filename)
改名文件rename(oldname,newname)
static的作用:延长了局部变量的生命周期;限定了访问作用域;避免命名控件污染;
缓冲区分类:
行缓冲(针对终端):’\n’;fflush;缓冲区满;结束程序;遇到输入时
全缓冲(针对磁盘文件):fflush;缓冲区满;正常结束程序
无缓冲(stderr)
终端输出:stdout stderr(无缓冲)
数据类型的理解:int a=10; a代表的是一个内存空间的标识符号而已。
typedef的用法:1、typedef struct person(类型) p(别名);2、typedef struct person{ }别名;3、typedef char *pointer; pointer p1,p2;得出p1和p2为指针类型。定义出来的为 *p1,*p2; 目的,增加程序的可移植性。
指针只是保存了数据的首地址,必须根据指针类型,才能知道取多少字节
void *指针主要用于数据的封装
sizeof()函数返回值为无符号整型。
sizeof碰到数组参数时:1、数组名出现在表达式(在形参)中,那么数组名就表示指向数组首元素的指针;2、在对数组名&arr取地址,或者使用sizeof(数组名)之外,数组名就是首元素指针
const:全局的时,放在常量区,数据被初始化后,不能修改。为局部时,放在栈区,数据被初始化后,可以通过间接,指针方式修改(day01-源码-全局静态区)
void:1、无类型,表示编译都不知道要分配多少内存;2、主要用在函数的参数和函数的返回值中;3、不能去定义变量
字符串中:同一字符串中,右边字符的地址高于左边字符地址
sscanf: 1、%*s或%*d 跳过数据 2、%[width]s 读指定宽度的数据3、%[a - z] 匹配a到z中任意字符(尽可能多的匹配),没匹配的到就跳出4、% [aBc] 匹配a、B、c中一员,贪婪性,没有匹配到其中数据,函数结束5、%[^a] 匹配非a的任意字符,贪婪性 匹配到a,函数就结束 6、%[^a - z] 表示读取除a - z以外的所有字符,匹配到其中数据,结束函数 不符合要求,就跳出函数,在sscanf ”参数” 在其参数中输入摸个字符。也不会写入数据中
const int *p:常量指针,指向的的值不能改变,不能通过*p去修改它指向的值
int const *p:指针常量,指向的地址不能改变,不能去修改p指向的地址,可以通过*p去修改他指向的值
一级指针传地址给二级指针,注意数组指针的运用。
<<:左移位运算符,a<<b,表是a乘以2的b次方
>>:右移运算符,a>>b,表是a除以2的b次方
VS中,打开文件路径表示用 \\ ;
运用^进行值交换:a = a ^ b; b = a ^ b; a = a ^ b;
三目运算符:表达式?参数1:参数2;表达式为真,返回参数1;表达式为假,返回参数2
链表数据的插入,在数据后插入,和前面链表数据比较。在数据前插入,和后面链表数据比较
C++语法
作用域运算符 ::访问全局变量,否则就近原则
命名空间的使用,头文件声明空间,另外文件实现头文件的时候,需要带上空间名+函数,主函数调用也需要带上空间名+函数(命名空间的使用.cpp)
结构体中可以定义函数,定义:struct+结构体名字{}; 变量定义:结构体名字 变量名字
三目运算符,返回的是一个左值,例:a=10,b=20(a > b ? a : b) = 100。返回的变量将会被改变为100;结果返回b,然后对b进行重新赋值
引用:& 被引用变量必须先初始化,引用与被引用类型必须相同
理解成内存块进行重命名,理解成操作内存
函数返回引用,可以作为左值,值可以用引用接,变量接
命名空间:数据类型优先于命名空间,命名空间优先与类。C++中所有数据都是基于命名空间上操作。
命名空降使用规则:1:命名空间必须在全局范围内写
2:命名空间可以嵌套命名空间
3:命名空间是开放的,即可以随时把新的成员加入已有的命名空间中
4:匿名命名空间的使用等价于 = static int count = 0;
类:
类的概念:为一种自定义数据类型
编译器自动对类有默认的三个函数:构造函数、拷贝函数、析构函数
对类中的析构函数和构造函数:
class 类名
{
类名(){代码语句};//定义一个类变量后,系统会自动调用构造一次构造函数。执行顺序:分配内存->调用构造函数。注意:可以重载,可以有参
类名(const 类名 &变量)
~类名(){代码语句};//定义一个类变量后,系统会自动调用构造一次构造函数。
执行顺序:销毁对象前,调用析构函数。注意:调用几次构造函数,就会调用几次析构函数
}
类中的构造规则:先成员构造,在类本身构造,析构与构造循序相反。在继承中:先父后子
动态成员的创建:运用new(分配某种数据类型内存)和delete;(见C++中的基本语法->类的基本概念)
类中的静态成员:(为所有对象共有,所以没有this指针)
静态成员函数:静态成员函数只能访问静态成员变量
由于静态成员函数,没有this指针,所以不能访问。
静态成员变量:静态成员变量 声明周期:整个程序 作用域:MyClass类
静态成员变量必须类内声明,类外定义
类的大小:由对象中的非静态的成员变量决定
mutable关键字,可以使数据不受const影响
类的三大特性:
封装:对函数和变量封装,控制访问权限
字符串类封装注意事项:
加号的重载,需要借助第三方临时类,
加等号的重载,需要借助另外一个指针,存放数据最开始指向的数据
数组类的定义:
运用一级指针存放地址
数组、字符串封装:
运用一级指针
函数重载(同一作用域下):
一般在类中进行重载,主要是类中运算符的重载
概念:函数同名,但是必须满足以下其中几个要求:1、参数个数不同 2、参数类型不同
3、参数顺序不同(匹配从严到妥协)
友元函数声明:友元成员函数(注意类内声明,类外定义),友元类、全局友元函数
运算符的重载:成员函数中 成员类 operator运算符(类2){}其中隐藏一个this指针,如果设计类的私有变量,可进行友元函数声明。
常用重载运算符格式:
类内重载:
=: 类名& operator=(const 类名 变量)
前置++: 类名& operator++(){数据++,return *this};
后置++: 类名 operator++(int) {借用第三个变量储存 this ,数据++,return 返回第三变量(未++ this)}
+= :类名& operator+=(const 类名 变量)
[]:类型& operator[](int index)
全局函数重载:(如果访问类内私有变量,进行友元声明)
>>:istream & operator>>(istream &in,类名 &变量)
<<:ostream & operator<<(ostream &in,类名 &变量)
继承:
继承父类的访问权限:继承权限越来约严格,继承父类属性。只是访问权限有限制,主要目的是继承父类中的方法
靠近静态变量最近的那个类的作用域
多态实现原理:父类为虚函数声明(例:virtual 类型 函数名()=0;),同时父类虚析构。具体由子类实现
父类和子类有同名成员函数时,定义子类对象时,优先调用子类成员函数,父类的成员函数被隐藏,需要借助作用域声明
友元:
关键字:friend
友元解决问题: 授权某个函数 某个类 某个成员函数可以访问类内部的私有成员
全局友元函数:类内声明,类外实现
友元类:进行友元类在类内声明声明
友元成员函数:进行友元类内声明,类外实现,同时被有的类,需要提前声明。
类似于继承
异常处理:
throw 抛出异常数据类型,需要进行严格类型匹配,运用catch接收异常数据,catch(数据类型)与throw抛出数据类型必须相同,否则调用catch(…) (见源码中)
标准的输入输出
cin
概念:流中的函数(针对的是缓存区到变量中;键盘->缓存区(黑窗口中数据)->变量中)
cin.get():按个读取缓存区中的数据,知道将所有数据读完,注意:缓存区中的数据会读入其中
cin.get(数据地址,读取个数):按行读取,遇到’\n’,读取结束。注意:不会读取缓存区中的’\n’;
cin.getlin(数据地址,读取个数):按行读取,遇到’\n’,读取结束。注意:会读取缓存区中的’\n’;单不会写入到数据地址中
cin.ignore(参数):忽略某个位置上的数据。也可以理解成,结合cin.get()使用,也可以理解成,读取缓存区中小标为多少的数据
cin.peek():窃取缓存区中的某个数据,不破换缓存区中的数据结构
cin.putback(参数):将参数放入缓存区中。
cout
cout.put(字符).put(字符):字符单个输入,后面可以无限.put(参数)
cout.write(数据地址,参数值):参数个数决定输出多少个数据
cout.width(参数值):输出数据所占宽度,默认右对齐,只对当前最近的一个数据有效
cout.fill(字符):字符的自动填充
cout.setf(ios::参数):参数包含:left和right
文件的读取
头文件:fstream
写文件:
打开方式:ofstream 类名(“文件目录”,ios::out) 以写的方式打开文件。成功 类名 为非空
例:ofstream os(“文件目录”,ios::out) 类名为一个指针
写文件的三种方式:类名<<数据地址 ; (将指针指向的数据,写入文件中)
类名.write(数组首地址,字节数);
类名.put(参数);
读取文件:
打开方式:ifstream类名(“文件目录”,ios::in) 主要知道读到什么时候结束
读取文件结束的俩种函数:(类名.get())!=EOF;
while(!类名.eof()) 未读到末位,返回值为空
例:while(!ifs.eof){char buf[128]={0}; ifs.getline(buf,1024);cout<<buf<<buf} 文件按行读取
类名.read(buf,参数) 文件按字节数读取 主要运用于对象中
STL
vector 容器:
格式: vector<数据类型> 变量名 运用其头文件<vector>和算法头文件<algorithm> 去操作其内部函数 运用 变量名.begin() 和变量名.end(),去遍历数据 其俩个返回值为指针 v.push_back(数据),去初始化容器。 (见 myself_sound code\C++语法函数)
注:不定类型容器变量名:Var
int类型变量名:number
char类型变量 ch
ch*类型变量:ch*
string类型变量:str
不确定数据类型(包括类):elem
|
string类型容器 |
vector类型容器 |
deque类型容器 |
||||
概念 |
主要针对字符串 (只对字符) |
内存连续(类似数组概念) |
内存连续(自留头空间和尾空间,双端队列) |
||||
构造方式 |
相同 |
1、 容器类型 Var 2、 容器类型 Var(n个数,elem数据类型) 注:n个elem拷 贝给Var 3、 容器类型 Var(Var 2) 注:拷贝构造 4、 容器类型 Var(Var 2.begin(),Var 2.end()) 将此区间的数据,拷贝给Var |
|||||
不同: string容器针对string类和字符,而另外容器可以针对任何数据类型
|
|||||||
重载方式 |
相同 |
1、 Var(容器变量名2.begin(),容器变量名2.end()) 将此区间的数据,拷贝给本身 2、=重载 Var = Var 1 |
|||||
不同 |
1、 Var.assign(char *或者string类型) 2、 Var.assign(ch*,number)将ch*前number个字符赋给Var 3、 Var.assign(number,ch)将number个ch赋给Var 4、 Var.assign(str,number1, number2)将str中的number1到number2中间的字符赋给Var
|
1、 Var.assign(number,elem) 将n个elem(数据)拷贝给Var; 2、 Var.swap(Var1) 数据交换 |
|||||
大小操作 |
相同 |
1、 Var.size();//返回容器中实际元素 2、 Var..empty();//判断容器是否为空 3、 Var. resize (num);//重新指定长度,变短丢弃原来的数据,变长默认值填充 4、 Var.resize(num, elem); //重新指定长度,变短丢弃原来的数据,变长默elem填充 注:string类型只能填充char类型 |
|||||
不同 |
Var.reserve(数值) 数据不进行初始化 |
|
|||||
插入和删除 |
相同 |
1、Var.insert(number,emle,); //在number位置插入数据 2、Var.insert(number, number1, ch);//在指定number位置插入number1个字符c 3、Var.erase(number, number1);//删除从number位置开始的number1个字符 |
1、 Var.push_back(elem) //将数据从尾插(reserve和resize区别) 2、 Var.pop_back();//删除容器最后一个数据 3、 Var.insert(const_iterator pos, number,ele);//迭代器指向位置pos插入number个元素ele. (为俩个参数是,即在指定位置插入第二个参数) 4、 Var.insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,(是否俩个都能) 5、 Var.erase(const_iterator pos);//删除迭代器指向的元素 6、 Var.erase(beg,end);//删除[beg,end)区间的数据,返回Var的类型。
|
||||
不同 |
Var.push_front() |
1Var.push_front(elem);//在容器头部插入一个数据 Var.pop_front();//删除容器第一个数据
|
|||||
|
|||||||
|
set容器中的迭代器:删除操作之后的数据,迭代器依旧有效
容器中常用API总结
数据类型:T 变量:Var
概
念 |
|
string容器 |
vector容器 |
deque容器 |
list 容器 |
set/multiset 容器 |
map/multimap 容器 |
stack 容器 |
queue容器 |
||||||||||||||
迭代器 |
有 |
有 |
有 |
有 |
有 |
有 |
无 |
无 |
|||||||||||||||
随机访问 |
支持 |
支持 |
支持 |
不支持 |
不支持 |
不支持 |
不支持 |
不支持 |
|||||||||||||||
构
造
方
法 |
默认构造函数 |
类型 < T > Var 注:Var可以为char *和string |
map/multimap < T ,T1> m |
类型 < T > Var
|
|||||||||||||||||||
拷贝构造 |
类型 < T > Var(Var1) 注:Var可以为char *和string |
map/multimap < T ,T1> m(m 1) |
类型 < T > Var(Var1)
|
||||||||||||||||||||
区间拷贝构造 |
无 |
数据类型 Var 1(Var 2.begin(),Var 2.end())Var2区间的数据拷贝给Var 1 |
无 |
无 |
无 |
无 |
|||||||||||||||||
重复构造(某种数据类型重复构造) |
类型 Var(n,elem) 将n个数据拷贝给给类名 注:string中,数据只能是char类型 |
|
|
|
|
||||||||||||||||||
赋 值 方 法 ( 改 变 原 有 数据 ) |
= 重载操作 |
Var=Var |
|||||||||||||||||||||
区间赋值法 |
|
Var.assign(Var2.begin(),Var2.end) . Var2区间的数据拷贝给Var 1 |
|
|
|
|
|||||||||||||||||
同一数据重复赋值 |
Var(n,elem) 将n个数据拷贝给给类名 注:string中,数据只能是char类型 |
|
|
|
|
||||||||||||||||||
asssign指定赋值(只针对string容器) |
Var.assign (Var1,num,num2) 将Var1从num开始num2个字符赋值给字符串(Var需要为string类型,一个参数时直接将Var1赋值给 Var) Var.assign(Var2) 注:Var2为char*类型,将Var2赋值给Var Var.assign(Var2,n)注:Var2为char*类型,将Var2前n个字符赋值给Var |
|
|
|
|
||||||||||||||||||
swap()交换赋值 |
|
Var.swap(Var1),将Var1的值交换给Var
|
|
|
|||||||||||||||||||
概
念 |
|
string容器 |
vector容器 |
deque容器 |
list 容器 |
set/multiset 容器 |
map/multimap 容器 |
stack 容器 |
queue容器 |
||||||||||||||
迭代器 |
有 |
有 |
有 |
有 |
有 |
有 |
无 |
无 |
|||||||||||||||
随机访问 |
支持 |
支持 |
支持 |
不支持 |
不支持 |
不支持 |
不支持 |
不支持 |
|||||||||||||||
数
据
查
找
方
法 |
Var[pos]:会出现越界问题 |
Var[pos],返回容器pod位值的值,同时可以同Var[pos]=Var2,去修改数据类型,注:string类型数据时,Var2只能为char类型 |
|
|
|
|
|
||||||||||||||||
Var.at(pos):不会出现越界问题 |
Var.at(pos),返回容器pos位值的值,同时可以同Var[pos]=Var2,去修改数据类型,注:string类型数据时,Var2只能为char类型 |
|
|
|
|
|
|||||||||||||||||
运用find |
Var.find(Var1,ch) 返回在Var1中字符ch第一次出现的位置值(整型数据),结合[],at(),可以进行替换操作 Var.rfind(ch) 返回字符最后返回在Var1中一次出现的位置值(整型数据),注:Var数据类型可以为char,char*,string |
|
|
|
Var.find(key);//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回 变量.endl(); 注意map中是操作键值
|
|
|
||||||||||||||||
查找返回迭代器 |
|
count(key);//查找键key的元素个数 lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器。 upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器。 equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器。 注:为set和map容器所有函数,其他容器没有,定义迭代器接收 类型<容器接收数据类型>::iterator it) |
|
|
|||||||||||||||||||
|
|
Var.front();//返回第一个数据。 Var.back();//返回最后一个数据(queue容器相同) ;
|
|
|
Var.top();//返回栈顶元素 |
|
|||||||||||||||||
|
string容器 |
vector容器 |
deque容器 |
list 容器 |
set/multiset 容器 |
map/multimap 容器 |
stack 容器 |
queue容器 |
|||||||||||||||
数
据
删
除
操 作
|
erase()容器共有,参不同作用不同 |
|
Var.erase(const_iterator start, const_iterator end);//删除迭代器从start到end之间的元素 Var.erase(pos);//删除迭代器指向的元素(pos为指向的第几个位置) 注:在map和setp中:删除容器中键值为pos(可以为任何类型)的对组。
Var.clear();//删除容器中所有元素
|
|
|
||||||||||||||||||
pop方法删除 |
|
Var.pop_back();//删除最后一个元素 。 |
|
|
Var.pop();//从栈顶移除第一个元素
|
Var.pop();//从队头移除第一个元素 |
|||||||||||||||||
|
Var.pop_front();//删除容器第一个数据 |
||||||||||||||||||||||
romove方法删除 |
|
|
|
remove(elem);//删除容器中所有与elem值匹配的元素(在map中指的是键值) 注:remove_if(elem)在set和map中elem表示为bool函数时,表示按条件删除 |
|
|
|||||||||||||||||
|
string容器 |
vector容器 |
deque容器 |
list 容器 |
set/multiset 容器 |
map/multimap 容器 |
stack 容器 |
queue 容器 |
|||||||||||||||
数 据 的 插 入
|
push方法 |
|
pushu_back()尾部插入 |
|
|
push(elem);//注:stacks是栈顶添加元素 queue是往队尾添加元素 |
|||||||||||||||||
|
push_front(elem);//在容器开头插入一个元素 |
|
|
||||||||||||||||||||
insert方 法 插 入 |
Var.insert (pos, n,emlem);//在pos位置插入n个元素 |
|
|
|
|
||||||||||||||||||
Var.insert(pos,s); //指定位置插入字符串(s可以为string和char*类型)
|
|
insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置。
|
Var.insert(elem);//在容器中插入元素。 |
1.通过pair的方式插入对象 Var.insert(pair<int, string>(3, "小张")); 2.通过pair的方式插入对象 Var.inset(make_pair(-1, "校长")); 3.通过value_type的方式插入对象 Var.insert(map<int, string>::value_type(1, "小李")); 4.通过数组的方式插入值 Var [3] = "小刘"; (此方式如果插入相同的键值,实值发生改变第二次插入的值,其他不会) |
|||||||||||||||||||
|
|
|
Var.insert(pos,beg,end);//在pos位置插入[beg,end]区间的数据 |
|
|
|
|
|
|||||||||||||||
|
|
string容器 |
vector容器 |
deque容器 |
list 容器 |
set/multiset 容器 |
map/multimap 容器 |
stack 容器 |
queue 容器 |
||||||||||||||
|
|
|
单口容器, 随机迭代器 |
双口容器 |
|
容器插入的数据会自动派好序,set不可以插入重复数据。默认升序。加前缀(multi)可以插入重复数据,改变排序方式在构造的时候,载入一个队形,对象内部有bool函数,例:struct MyComapre{bool operator ()(int v1, int v2){return v1 > v2;}}; map容器的方式是通过键值(第一个参数) |
|
|
常用算法
参数Var:容器变量名
参数B:Var.beign()
参数 E:Var.endl()
参数:Data某种类型数据
迭代器D:与容器所存数据类型相同 例:vector<int>::iterator it
函数名及作用 |
要求 |
返回值 |
参数 |
范例 |
|
for_each 遍历算法, |
有迭代器 |
无(当第三个函数为结构提函数,返回容器中对象类型值) |
(B,E,函数对像) 注:或者直接用Ladma表达式 |
struct Print {void operator()(int v1){cout << v1 << "___";}}; for_each(v1.begin(), v1.end(),[](int val)->void{cout<<val<< " "; });//ladam表达式 |
|
transform 容器数据搬运 (被放入数据的容器需要自行开辟空间) |
有迭代器 |
无 |
(B,E,函数对像) 注:或者直接用Ladma表达式 或为5个参数 |
transform(v.begin(), v.end(), v1.begin(), [](int val)->int{return val+10; });
transform(vc1.begin(), vc1.end(), vc2.begin(), vc.begin(), Trans_add()); //对象重载需要俩个参数 第二个容器小于第一个容器,第三个容器大小等于第一个容器大小 |
|
查找算法 |
find |
有迭代器 |
返回迭代器it,数据没有找到,则it == v.end()) |
(B,E, Data):注:或者用bool类型的函数,满足某种条件第一个数据。如果是类,第三参数对象重载
|
vector<int>::iterator it = find(v.begin(), v.end(), 20);
bool MyPrint03(int val) {return val > 30;} it = find_if(v.begin(), v.end(), MyPrint03);
struct MyCompare :public binary_function<Person, Person, bool> {bool operator()(Person p1, Person p2)const {return p1.mName == p2.mName&&p2.mAge == p2.mAge;}}; vector<Person>::iterator it= find_if(v.begin(),v.end(),bind2nd(MyCompare(),Person("dddd",40))); |
find |
|||||
adgacent_find删除重复且相邻的数据 |
有迭代器 |
返回迭代器it,数据没有找到,则it == v.end()) |
(B,E) 注:如果为类的时候,使用bool函数在类内重载==,用俩个参数,类外重载,运用三个参数 |
vector<int>::iterator it = adjacent_find(v.begin(), v.end());
bool comareStudent(Student &s1, Student &s2) { return s1.mName == s2.mName&&s1.mAge == s2.mAge; } vector<Student>::iterator it = adjacent_find(v.begin(), v.end(),comareStudent);
|
|
binary_search 二分查找法 |
数据有序,默认升序 |
bool值 |
(B,E, Data);过数据是降序,需写入第四个参数greater<Student>() |
|
|
count count_if 统计满足条件的数据 |
迭代器 |
int类型 |
(B,E, Data);统计等于Data的个数。 如果为_if中第三数据为bool函数 |
|
|
accumulate 容器中数据相加,放入第三个容器 |
无 |
int类型 |
(B,E, 0) 注:面对类的时候,第三个参数为对象重载 |
int ret = accumulate(v.begin(), v.end(), 0);
struct MyPuls {int operator()(int val, Person &p){return val + p.mAge;}}; ret = accumulate(v.begin(), v.end(), 0, MyPuls()); |
|
fill向容器中添加元素 |
|
无 |
|
fill(v.begin(), v.end(), 100); |
|
copy拷贝算法
|
|
无 |
|
copy(v1.begin(), v1.end(),v2.begin()); |
|
替换算法 |
replace |
有序 |
无 |
(B, D, 20, 100); |
replace(v1.begin(), v1.end(), 20, 100); replace_if(v1.begin(), v1.end(), mycompare, 200); |
replace_if |
有序 |
无 |
(B, D, bool, 100);为bool函数 |
||
容器交换算法 |
|
|
|
swap(v1, v2); |
|
set_intersection交集 |
需要开辟第三个容器,第三个容器大小要初始化 |
返回迭代器,输出的时候返回的迭代器作为输出结束的条件 |
((v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin())) |
vector<int>::iterator myend = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin()); |
|
set_union 并集 |
vector<int>::iterator myend = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin()); |
||||
set_difference 差集 (返回的为前面这个容器的差集) |
vector<int>::iterator myend = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin()); |
||||
merge (有序数据的合并) |
有序 |
无 |
5个,第六个参数进行升序降序判断 |
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin(),greater<int>()); |
|
random_shuffle (容器数据随机排序算法) |
|
|
2个 |
random_shuffle(v1.begin(), v1.end()); |
|
w_x_me |
|
|
|
|
|
|
|
|
|
||
|
|
|
|
||
|
|
|
|
1、串口通讯中,将16进制的字符串转化为整数
流程:1、从PLC收到16进制的字符串,将字符串的数据段转换为整型
#include<stdio.h>
#include<cstdio>
#include<math.h>
using namespace std;
int main()
{
char vaule[] = { '0', '6', '2', '2' };
int len = 3;
int sum=0;
int temp;
for (; len >= 0; len--)
{
if (vaule[len] >= 'A')
{
temp = powl(16, (3 - len));
printf("temp:%d\n", temp);
sum += (vaule[len] - 'A')*temp;
}
if (vaule[len] >= '0'&&vaule[len] < 'A')
{
temp = powl(16, (3 - len));
printf("temp:%d\n", temp);
sum += (vaule[len] - '0')*temp;
}
}
printf("%d", sum);
system("pause");
}
2、配置文件的运用,调用Windos的API函数
流程:1、建立.ini后缀文件,文件编写方法入config.ini文件。2、注意VS的版本对函数调用造成的影响,需要自行添加MFC的一些库
config.ini文件
[Custom_Config]
m_nTest=123456789
m_nstr="COM3"
代码:
#include<afxwin.h>
#include<string>
using namespace std;
int main()
{
int m_nTest;
char m_nstr[20];
//参数说明:
//参数1:INI文件中的一个字段名(中括弧里面的字符),这个字串不区分大小写。
//参数2:下的一个键名(‘=’右边的名字),也就是里面具体的变量名,这个字串不区分大小写。
//参数3:如果没有其前两个参数值,则将此值赋给变量。指定的条目没有找到时返回的默认值。必须为整型。
//参数4:完整的INI文件路径名
m_nTest = GetPrivateProfileInt("Custom_Config", "m_nTest", 123456, "D:\\work\\C++\\cofig\\cofig\\cofig.ini"); //如果没有从配置文件中找到,则默认为12345//参数说明:
//参数1:INI文件中的一个字段名(中括弧里面的字符),这个字串不区分大小写。
//参数2:下的一个键名(‘=’右边的名字),也就是里面具体的变量名,这个字串不区分大小写。
//参数3:如果没有其前两个参数值,则将此值赋给变量。指定的条目没有找到时返回的默认值。可设为空("")。
//参数4:接收INI文件中的值的CString对象(一般用字符串数组),指定一个字串缓冲区
//参数5:指定装载到lpReturnedString缓冲区的最大字符数量
//参数6:完整的INI文件路径名
GetPrivateProfileString("Custom_Config", "m_nstr","123", m_nstr, sizeof(m_nstr), "D:\\work\\C++\\cofig\\cofig\\cofig.ini");
cout << m_nTest << endl;
cout << m_nstr << endl;
system("pause");
}
关于Visual Studio
error LNK1112: 模块计算rld机类型“x64”与目标计算机类型“X86”冲突。 解决方法:1、重新设置 解决方案配置,将Win32改为x64。2、选择“链接器”->“高级”,将目标计算机设置为MachineX64:
显示图片时,提示异常中断。 解决方法:检查图片路径情况