cin.sync(); //清除cin缓存区的所有数据,不够灵活,不建议。 cin.ignore(1, EOF); // 同cin.sync(); cin.ignore(numeric_limits::max(),’n’); //清除当前行, cin.ignore(numeric_limits::max()); //清除cin里所有内容,
numeric_limits::max()是climits头文件定义的流使用的最大值,也可自定义足够大整数代替(如1024)。例如,getline函数前或者批量输入很多值后必须cin.ignore(1024, ‘n’);当然,如果自定义按行取数的截止符非’n’,也可消除换行操作的影响。
std::cin >> n;
if (!cin.good()) {
std::cout << "输入有错!" << endl;
cin.clear();
cin.sync(); //清空流
return;
}
注:日常验证小逻辑、算法,不要采用键盘交互,最好直接写死,参见“排序问题”
2.功能的不同实现方式 3.定义枚举类型的好处比定义成int型占用的空间小。而且代码更安全。
4.表达式运算 4.1运算符优先级:1)初等运算符:(),[],->,后置自增减++/--
2)单目运算符:逻辑非!,按位反~,正负号,解引用*,取地址&,sizeof,强制类型转换(type),前置++/--;
2.5)C++中:
->*:在指针上通过指向成员的指针访问成员的操作符,ptr->*var = 24;
.* :在对象上通过指向成员的指针访问成员的操作符,obj.*var = 24;
3)算术运算符(先*,/, %后+,-)
3.5)移位操作符:<<,>>;
4)关系运算符: 先<,<=,>,>=后==,!=
4.5)位操作符:按位与&,按位异或^,按位或;
5)逻辑运算符:逻辑与&&,逻辑或||
6)三目运算符
7)赋值运算符:=,+=,*=,&=,<<=等;
8)逗号运算符
总结:"()" > "-(负号)" > "!" > "算术运算符" > "关系运算符" > "&&" > "||"
4.2拓展:
1)左值和右值
左值和右值都是针对表达式而言的,
左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时就不再存在的临时对象。
区分左值与右值的便捷方法是:看能不能对表达式取地址,如果能,则为左值,否则为右值
2)表达式运算时参数的存储类型
int*int结果仍是int型,当结果值太大容易出现异常(值为负),日常开发参与运算的参数变量最好采用long型;
同型基本类型数据相乘结果类型不变【注意:int转long可以直接转;同型相乘不能超限】;
C++中编译器对未指定类型常量的处理:根据实际值位数选择int、long(long qq = 201808 * 100000000;本例中两个常量选择了用int来存储)
5.操作符重载:用于自定义对象的比较等 6.预处理指令之条件编译#if #ifdef #ifndef #if defined #if !defined #elif #else #endif #undef
划重点:
1)#ifdef只能判断单一的宏是否定义,而#if defined()可以组成复杂的判别条件; 2)对于单一的宏AAA来说,#ifdef AAA和#if defined(AAA)是完全相同的; 3)要组成复杂的判别条件,用#if defined()灵活方便,比如:#if defined(AAA) && (BBB >= 10) 4)头文件编写时,为了防止同一头文件被多次编译,可能造成重定义错误,所以开头结尾会有"#ifndef XXX /#define XXX/#endif"7.STL
标准模板库
容器,比如 deque、list、vector、map 等; 可以高效地添加元素等操作
算法,作用于容器; 它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。
迭代器,iterator,每种标准容器定义了一种迭代器类型; 用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。
注:
1)begin()操作返回指向容器第一个元素的迭代器;end()操作返回指向容器末端元素的下一个元素的迭代器
2)通过STL和函数,可以实现许多算法和数据结构,如向量、链表、队列、栈
前者为函数,参数只能为字符串,统计时不包含字符串结束符,且返回类型为size_t(无符号整型),比较运算时方式:strlen(x)>= strlen(y);
后者是单目运算符,参数类型不限制,包含字符串结束符
指针优点:
1.快速传递数据,减少内存消耗;
2.使函数返回多个值
指针本质:
地址,一个n+1级型指针变量,只能存储n级型指针变量的地址,位数大小=min(cpu,操作系统,编译器)
指针与引用区别:
指针指向一块内存,它的内容是所指内存的地址;引用则是某块内存的别名,引用不改变指向。
指针与引用区别应用于指针传递和引用传递(普通的变量传递,形参只是实参的一份拷贝,并未改变实参指向,传递失败,采用引用传递则完美解决问题)
拓展:
指针(*)
取地址(&)
解引用(*)
引用(&)
10.续行符
普通代码行后面加不加都一样(VC是自动判断续行的),但是在宏定义里面就特别有用,因为宏定义规定必须用一行完成:
11.类的指针&类的对象|指针与对象 指针变量是间接访问,但可实现多态(通过父类指针可调用子类对象),并且没有调用构造函数。
直接声明可直接访问,但不能实现多态,声明即调用了构造函数(已分配了内存)。
至于那个效率高要看程序调用过程而定。
C++的精髓之一就是多态性,只有指针或者引用可以达到多态。对象不行
用指针:
第一,实现多态。
第二,在函数调用,传指针参数。不管你的对象或结构参数多么庞大,你用指针,传过去的就是4个字节。如果用对象,参数传递占用的资源就太大了
12.socket编程
基本套接字系统调有有如下一些:
创建套接字: socket()
#include#include
绑定本机端口: bind()
#include#include
建立连接: connect(),accept()
#include#include
侦听端口: listen()
#include
数据传输: send( )
#include
recv()
#include#include
输入/输出多路复用: select()
关闭套接只: closesocket()
#include#include
所需头文件:
https://www.cnblogs.com/cucumber/p/3922756.html
atof():将字符串转换为双精度浮点型值。 atoi():将字符串转换为整型值。 atol():将字符串转换为长整型值。 strtod():将字符串转换为双精度浮点型值,并报告不能被转换的所有剩余数字。 strtol():将字符串转换为长整值,并报告不能被转换的所有剩余数字。 strtoul():将字符串转换为无符号长整型值,并报告不能被转换的所有剩余数字。
https://www.cnblogs.com/bluestorm/p/3168719.html
14.泛型编程一个泛型模板里不能正确处理所有的类型时,
类模板需要特化处理,但C++标准中规定,嵌套类模板在类的定义中不允许被显示特化声明,只允许偏特化(增加一个无用的模板参数),或者将特化代码放在类定义之外:
https://blog.csdn.net/peterlin666/article/details/38089727
函数模板用重载实现特化:
https://bbs.csdn.net/topics/380243267
编译、调用
GNU:操作系统名,全称GNU is Not Unix
Linux系统包含Linux内核、其他自由软件项目中的GNU组件和软件。
GCC:GNU中编译器集合
gcc:GCC中c编译器
g++:GCC中c++编译器
http://blog.csdn.net/A784586/article/details/73610982
简单构造函数 与 复杂构造函数 的区别?
虚函数概念?
maollc和new的区别?
都能动态地申请内存,后者为C++操作符,需要编译器支持才行,前者为C标准库函数,添加头文件后可以调用;
char *s=(char *)malloc(100*sizeof(char)); //c分配方式 char *s=new char [100]; //c++分配方式
后者会调用构造函数,主要用于自定义类型对象的内存分配;前者不会;
前者需指定大小;后者不用,编译器会自动计算;
malloc/free——new/delete;
后者返回的是对象类型的指针,不用转换类型,前者返回void*,需要强制类型转换为我们所需的类型;
后者可以重载,前者不可以;
https://blog.csdn.net/alidada_blog/article/details/83149419
注意:free操作只告诉系统该内存块可以被回收了,并不是直接释放给操作系统,而是还给了glibc的堆管理实体
Linux共享内存函数:shmget、shmat、shmdt、shmctl四个函数
https://blog.csdn.net/guoping16/article/details/6584058
内存分配:栈、堆和静态区
https://blog.csdn.net/qq_38998213/article/details/83055718
int a=0; //全局初始化区
char *p1; //全局未初始化区
main()
{
int b;栈
char s[]="abc"; //栈
char *p2; //栈
char *p3="123456"; //123456 在常量区,p3在栈上。
static int c=0; //全局(静态)初始化区
p1 = (char*)malloc(10);
p2 = (char*)malloc(20); //分配得来得10和20字节的区域就在堆区。
strcpy(p1,"123456"); //123456 放在常量区,编译器可能会将它与p3所向"123456"优化成一个地方。
}
17.结构体
1)结构体变量和共同体变量不能用作函数的参数 2)C结构体中不能有函数,C++扩展后可有;C++中结构体和类很相似,区别在于其成员默认public 3)结构体输入/输出,既可以发送地址也可以发送内容,一般为节省内存和提高执行速度选择发送地址(只需要4B就ok了) 4)结构体是不占用内存的,只有定义结构体变量时才会占用内存。(类似类定义时不占用内存)18.API用法查看
open opendir19.C++强制类型转换
static_cast dynamic_cast const_cast reinterpret_cast
char a = 'a'; int b = static_cast20.const指针与指向const的指针区别(a); //正确,将char型数据转换成int型数据 double *c = new double; void *d = static_cast (c); //正确,将double指针转换成void指针 int e = 10; const int f = static_cast (e); //正确,将int型数据转换成const int型数据 const int g = 20; // int *h = static_cast (&g); //编译错误,static_cast不能转换掉g的const属性 delete c;
以*为基准,const在右为const指针,const在左为指向const的指针
const double PAI = 3.1415926; const double pi = PAI; const double *lptr = π // const型变量的地址,只能由指向const型的指针存放 const double *const mptr = π //指向const对象的const指针 double const *nptr = π double pi1 = PAI; double *const optr = &pi1; //const指针初始化后不可改变指向 std::cout << DBG(*lptr) << "n" << DBG(*mptr) << "n" << DBG(*nptr) << "n" << DBG(*optr) << std::endl;算法设计与实现 1.排序算法
插入排序:
直接插入排序、
希尔排序(dh=1时即为直插排序)
交换排序:
冒泡排序、
快速排序
选择排序:
简单选择排序,不稳定,相同数也会发生交换次序;
堆排序,改进,相同数不会发生交换次序;
2.广度优先遍历算法
3.深度优先遍历算法
5.排列组合
组合算法:
https:// blog.csdn.net/lwhsyit/article/details/80598827
排列算法:
1)Arrange()方法,递归实现全排列
https:// blog.csdn.net/lwhsyit/article/details/80598827
https:// blog.csdn.net/summerxiachen/article/details/60579623
栈
队列
循环队列:解决顺序队列的“假溢出”问题,将data[0]作为data[MAX_LEN-1]的下一个存储位置,
即当front或rear值为MAX_LEN-1时,即需要执行出队、入队操作。
动态存储结构:链表、链栈、链队列
线性表:
顺序表:逻辑相邻的元素存储地址也相邻(可用数组作为存储方式)
链表:
C++进阶之常用技术
QT MFC STL Boost OpenCV WebSocket++ Bcrypt Catch Neu



