C++新经典

  • 第1章 C/C++
    • 1.1 C和C++语言的起源、特点、关系与讲解范畴
    • 1.2 C/C++语言市场需求与就业需求分析
    • 1.3 再谈C/C++就业
    • 1.4 搭建开发语言环境
  • 第2章 数据类型、运算符与表达式
    • 2.1 常量、变量、整形、实型和字符型
      • 2.1.1 创建最基本的C程序
      • 2.1.2 C语言的数据类型
      • 2.1.3常量和变量
      • 2.1.4 整型数据
      • 2.1.5 实型数据
      • 2.1.6 字符型数据
      • 2.1.7 字符串常量
      • 2.1.8 变量赋初值
      • 2.1.9 数值型数据之间的混合运算
    • 2.2 算数运算符和表达式
      • 2.2.1 C语言的运算符
      • 2.2.2 算术运算符和算数表达式
      • 2.2.3 运算符优先级问题
      • 2.2.4 强制类型转换运算符
      • 2.25 自增和自减运算符
    • 2.3 复制运算符和逗号运算符
      • 2.3.1 赋值运算符和赋值表达式
  • 第3章 程序的基本结构和语句
  • 第4章 程序的基本结构和语句
  • 第5章 循环控制
  • 第6章 数组
  • 第7章 函数
  • 第8章 编译预处理
  • 第9章 指针
  • 第10章 结构体与公用体
  • 第11章 位运算
  • 第12章 文件
  • 第13章 C++基本语言
    • 13.6函数新特性、inline内联函数与const详解
      • 13.6.1 函数回顾与后置返回类型
      • 13.6.2 inline内联函数
      • 13.6.3 函数特殊写法总结
      • 13.6.4 关于const char * 、char const *、char * const
      • 13.6.5 函数形参中带const和&
    • 13.7 string 类型
    • 13.8 vector类型
    • 13.9 迭代器精彩演绎、失效分析及弥补、实战
    • 13.10 类型转换:static_cast 、reinterpret_cast
      • 13.10.1 隐式类型转换
      • 13.10.2 显式类型转换(强制类型转换)
  • 第14章 类
  • 第15章 模板与泛型
  • 第16章 智能指针
  • 第17章 并发与多线程
    • 17.1 基本概念和实现
      • 17.1.1 并发、进程、线程的基本概念
      • 17.1.2 并发的实现方法
      • 17.1.3 C++11新标准线程库
    • 17.2 线程启动、结束与创建线程的方法
      • 17.2.1 范例演示线程运行的开始和结束
      • 17.2.2 其他创建线程的写法
    • 17.3 线程传参详解、detach坑与成员函数作为线程函数
      • 17.3.1 传递临时参数对象作为参数
      • 17.3.2 临时对象作为线程参数继续讲
  • 第18章 内存高级话题
  • 第19章 STL标准模板库大局观
  • 第20章 高级话题与新标准
  • 后记 IT职业发展的未来之路

第1章 C/C++

1.1 C和C++语言的起源、特点、关系与讲解范畴

1.2 C/C++语言市场需求与就业需求分析

1.3 再谈C/C++就业

1.4 搭建开发语言环境

第2章 数据类型、运算符与表达式

2.1 常量、变量、整形、实型和字符型

2.1.1 创建最基本的C程序


2.1.2 C语言的数据类型


1.每种数据类型所占内存大小

2.每种数据的取值范围

2.1.3常量和变量

常量:字面值。
变量:值可以改变的量。
变量定义:类型名 变量名 [ = 变量初始值 ];
标识符:变量等等的取名。
保留字:系统保留的特殊用途的字。

2.1.4 整型数据

整数,包含所有进制。

2.1.5 实型数据

小数。

2.1.6 字符型数据

1.字符常量
‘a’ , ‘b’ ,‘1’
2.转义字符
‘\n’ ‘\’ ‘’’ …
3.字符变量
char c = ‘a’ ;

printf("c1=%c, c2=%c\n",c1,c2);
printf("c1=%d, c2=%d\n",c1,c2);printf("%f",num);

知识点: ASCII

2.1.7 字符串常量

printf("hello world!");/*
*   区分'a'   "a"
*   字符串结尾多出来一个转义字符'\0',作为结束符
*
*/

注:Ctrl+F5 调试
Ctrl+F9 断点
Ctrl+F10下一断点
Shift +F9 添加监视
Ctrl Alt M +1 调用内存1(调试-窗口-内存-内存1)

2.1.8 变量赋初值

定义变量之后才能使用,一般是要赋初值的,否则会出错。

2.1.9 数值型数据之间的混合运算

不同数值类型的数据一起运算的的时候,系统尝试将变量类型统一。
类型转换从:
char , short ---->int ----> unsigned ----> long ----> double <-----double <----float
范围:由小变大。(隐式转换)

2.2 算数运算符和表达式

2.2.1 C语言的运算符

算数运算符 + - * 、 %(取余)
关系运算 <, <=, ==,>, >=,!=
逻辑运算符 !, &&, ||
位运算符 <<, >>, ~, |, ^, &
赋值运算符 =
条件运算符 ? :
逗号运算符 ,
指针运算符 * , &
求占字节运算符 sizeof()
强制类型转换符 (类型名)
成员变量运算符 . , ->
下标运算符 []
其他 …

2.2.2 算术运算符和算数表达式

2.2.3 运算符优先级问题


2.2.4 强制类型转换运算符

一般形式: (类型名)(表达式)

int a=1;
double b=(int) a;

总结:两种数据类型转换

  • 自动类型转换,类型范围由小到大。
  • 强制类型转换

都有精度损失或者溢出的风险。

2.25 自增和自减运算符

前++
后++
只适用于整型变量。

2.3 复制运算符和逗号运算符

2.3.1 赋值运算符和赋值表达式

第3章 程序的基本结构和语句

第4章 程序的基本结构和语句

第5章 循环控制

第6章 数组

第7章 函数

第8章 编译预处理

第9章 指针

第10章 结构体与公用体

第11章 位运算

第12章 文件

第13章 C++基本语言

13.6函数新特性、inline内联函数与const详解

13.6.1 函数回顾与后置返回类型

前置返回类型

int func( int a , int b);
int func( int a , int b)
{return a+b;
}

后置返回类型

auto func( int a, int b)->int ;
auto func( int a, int b)->int
{return a+b;
}

提示:一般一个函数写个几十到几百行就行,别太多,难以阅读。

13.6.2 inline内联函数

将简短且常用的函数定义为内联函数,代码在编译时被编译器会自动替换函数为函数体。

  • 循环、分支、递归调用就不要使用内联修饰符。
  • 内联函数类似 宏展开 #define 和 constexpr
inline int myfunc()
{return 1;
}

13.6.3 函数特殊写法总结

  • 返回空
void func(int a, int b){a+b;
}
  • 返回 值
int func(int a, int b){return a+b;

-返回指针

int * func(int b)
{int a=b;return &a;//函数一结束a就被释放,巨大隐患。
}
  • 返回引用
int & func()
{int a=0;return a;//函数一结束a就被释放,巨大隐患。
}
  1. 采用形参返回
void func(int &a ,int &b)
{int temp=a;a=b;b=temp;
}

13.6.4 关于const char * 、char const *、char * const

关于修饰符:修饰符是从变量的旁边从右向左阅读
因此:

  1. const char * p ,* 先声明 p是指针,char 声明 指针指向的数据类型, const声明 不能通过指针p去修改p指的内容。
  2. char const * p,* 先声明 p是指针,const 声明不能通过指针p修改p指向的内容,声明 指针指向的数据类型。
  3. char * const p,const p p是一个常量, *声明这个常量是一个指向常量的指针,char常量指针指向的数据类型。

太难解释了,总之就是

  1. 指针常量,不能用指针求修改,指向的可以是常量,也可以是变量。(1,2)
    -常量指针, 指针指向的是一个常量,不能指向非常量。(3)

13.6.5 函数形参中带const和&

先导:
形参的三种传值方式:

  1. 值传递
int add(int a, int b)
{cout<<"a的地址:"<<&a<<std::endl;cout<<"b的地址:"<<&b<<std::endl;}
int main()
{int c=1,d=2;cout<<"c的地址:"<<&c<<std::endl;cout<<"d的地址:"<<&d<<std::endl;add(c,d);
}
  1. 指针传递
int add(int *a, int *b)
{cout<<"a指向的地址:"<<a<<std::endl;cout<<"a的地址:"<<&a<<std::endl;cout<<"b指向的地址:"<<b<<std::endl;cout<<"b的地址:"<<&b<<std::endl;}
int main()
{int e=1,f=2;int *c=&e,*d=&f;cout<<"c的地址:"<<&c<<std::endl;cout<<"d的地址:"<<&d<<std::endl;add(c,d);
}
  1. 引用传递
int add(int &a, int &b)
{cout<<"a的地址:"<<&a<<std::endl;cout<<"b的地址:"<<&b<<std::endl;}
int main()
{int c=1,d=2;cout<<"c的地址:"<<&c<<std::endl;cout<<"d的地址:"<<&d<<std::endl;add(c,d);
}

综上,值传递需要消耗时间去复制实参到形参。
指针传递和引用传递是直接调用实参,效率更高。

函数参数带const

  • 防止无意中修改形参值导致实参被修改
  • 实参类型可以更加灵活
void func(const int & a)
{a=1;//不能通过a修改实参的值,报错。//引用传递,速度更快。
}

13.7 string 类型

13.8 vector类型

13.9 迭代器精彩演绎、失效分析及弥补、实战

迭代器仅仅是用来遍历容器的,若在遍历容器时,对容器进行修改,例如删除、添加的操作,会导致迭代器失效。
禁止迭代器使用时修改容器容量!

13.10 类型转换:static_cast 、reinterpret_cast

13.10.1 隐式类型转换

13.10.2 显式类型转换(强制类型转换)

C语言风格:

double b=10.1;
int  a =(int) b;

C++四种强制类型转换
通用形式:

//强制类型转换名<type> (express);
  1. static_cast :静态转换,即编译时检查。
  • 相关类型转换,如整型和浮点型之间的转换。
double f=10.2;
int a= static_cast<int> (f);
//类似
int b=(int ) f;
  • 子类到父类的转换
class A{};
class B :public A{};
B b;
A a= static_cast<A> (b);
  • void * 与其他类型指针之间的转换
    void * 的指针可以指向任何指针类型。我感觉这个功能很鸡肋,懒得记载了。
    不过,指针类型不可以进行强制类型转换,否则会出错。
  1. dynamic_cast :运行时类型识别和检查

  2. const_cast :用于去除指针或者引用的const属性,编译时检查。

在这里插入代码片
  1. reinterpret_cast

第14章 类

第15章 模板与泛型

第16章 智能指针

第17章 并发与多线程

17.1 基本概念和实现

17.1.1 并发、进程、线程的基本概念

1.并发
多个任务同时进行。(边听音乐边写作业,听音乐和写作是两不同的活动,但是同事进行。)
早期计算机只有一个CPU,为了同时间执行多个任务,我们规定在一定的时间间隔内执行程序,这样就可以在宏观上达到并行执行程序,但实际微观上是隔很短的时间不停的切换执行程序,这样看起来就像很多程序同时执行一样。
2.可执行程序
盘上的一个文件,window上是 .exe 结尾的文佳 ,Linux上面是 文件权限为 -rwxrw-r–的文件。
3.进程
可执行程序运行起来就是一个进程,总之就是一个运行的程序的过程就是进程。
4.线程
请先记住两件事:

  • 每个进程都有一个主线程,这个主线程是唯一的。
  • 当运行一个可执行程序,产生一个进程后,这个主线程也随之默默启动起来了。

总结:

  • 线程是用来执行代码的
  • 把线程理解成一条代码执行的通路,一个新的线程就代表一条新的道路。
  • 一个进程自动办好了一个主线程,主线程随着进程的默默启动并运行,并可以包括多个其他线程(非主线程,是需要用代码来创建其他线程),但创建线程的数量最大一般不建议超过200~300个,具体还要针对实际程序。
  • 因为主线程是自动启动的,所以一个进程中最少也是有一个线程的。
  • 多线程可以同时做多件事情,所以运行效率更高,但是并不容易评估和量化,仍旧需要在实际编程和实际项目中体会和调整。

5.学习心得
戒骄戒躁,慢慢来。

17.1.2 并发的实现方法

1.多进程并发
多个程序同时运行。进程通讯三种方式:管道通讯、消息通讯和共享内存。
2.多线程并发
单个进程创建多个线程。线程通信代价更小,同一个进程的线程是共享地址空间,因此多线程并发开销更小。但是由于共享地址空间,数据一致性问题凸显。
3.总结
多线程并发的优缺点:
优点:线程启动速度更快,更轻量级,系统资源开销更少,执行速度更快。
缺点:使用起来有难度,要小心处理数据一致性问题。

17.1.3 C++11新标准线程库

C++11的线程库可以跨平台,使用起来更加方便。

17.2 线程启动、结束与创建线程的方法

17.2.1 范例演示线程运行的开始和结束

#include <iostream>
#include <thread>
using std::cout;
using std::endl;
void myprint()
{cout << "我的线程开始执行了!" << endl;//.......cout << "我的线程执行结束了。" << endl;return;}
int main()
{std::thread mytobj(myprint);//myprint作为构造函数参数mytobj.join();//main主线程等待子线执行//mytobj.detach();//主线程不会等待子线程cout << "main主函数执行结束了!" << endl;return 1;
}

(1)thread
一个类。构造函数的参数是一个可调用对象(此处可调用对象就是函数myprint)作为thread构造函数的实参来构造这个thread对象。
(2)join
阻塞函数,让main主线程等待子线程执行。(主线程结束,子线程会被强制结束)
(3)detach
分离函数,让main主线程不等待子线程执行。
(4)joinable
bool res=mytobj.joinable();//true为调用过。
判断某个线程是否调用过join或者detach函数。

17.2.2 其他创建线程的写法

1.用类来创建线程

#include <iostream>
#include <thread>
using std::cout;
using std::endl;class TA {public://重载“()”运算符void operator ()() {cout << "TA::operator()开始执行了" << endl;//...cout << "TA::operator()执行结束了" << endl;}
};int main()
{TA ta;std::thread myTObj(ta);myTObj.join();cout << "main主函数执行结束了!" << endl;return 1;
}

一些危险的操作:


/*
*使用detach后,当main函数执行结束后,
*很可能子线程还在访问主线程里面的*my_i,
*这个时候my_i早已被释放,子线程仍
*旧使用被销毁的ny_i,产生不可预料的
*后果。
*/
#include <iostream>
#include <thread>
using std::cout;
using std::endl;class TA {public:int& m_i;TA(int& i):m_i(i){}void operator ()() {cout << "mi1的值为:" << m_i << endl;cout << "mi2的值为:" << m_i << endl;cout << "mi3的值为:" << m_i << endl;cout << "mi4的值为:" << m_i << endl;cout << "mi5的值为:" << m_i << endl;cout << "mi6的值为:" << m_i << endl;cout << "mi7的值为:" << m_i << endl;cout << "mi8的值为:" << m_i << endl;cout << "mi9的值为:" << m_i << endl;}
};int main()
{int my_i = 6;TA ta(my_i);std::thread myTObj(ta);myTObj.detach();//main函数执行太快,延缓main,让线程函数执行for (int i = 0; i < 1000000; ++i) {int q;q = 1;}cout << "main主函数执行结束了!" << endl;return 1;
}

2.用lambda表达式来创建线程

#include <iostream>
#include <thread>
using std::cout;
using std::endl;auto myLamThread = [] {cout << "我的线程开始执行了" << endl;//...cout << "我的线程执行结束了" << endl;
};int main()
{std::thread myTObj(myLamThread);myTObj.join();cout << "main主函数执行结束了!" << endl;return 1;
}

17.3 线程传参详解、detach坑与成员函数作为线程函数

17.3.1 传递临时参数对象作为参数

1.要避免的陷阱1
主线程已经运行结束,资源已经释放,但是子线程仍然在调用主线程资源。

#include <iostream>
#include <thread>
using std::cout;
using std::endl;
using std::thread;
void myPrint(const int& i, char* pmyBuf)
{cout << i << endl;cout << pmyBuf << endl;return;
}int main()
{cout << "main主线程开始执行" << endl;int mvar = 1;int& mvary = mvar;char myBuf[] = "this is a test!";thread myTObj(myPrint, mvar,myBuf);myTObj.detach();cout << "main主函数执行结束了!" << endl;return 1;
}

2.要避免的陷阱2
传递的参数隐式转换时,还未来的及转换转换,资源就被释放。

#include <iostream>
#include <thread>
#include <string>
using std::cout;
using std::endl;
using std::thread;
using std::string;
void myPrint(const int& i, const &string pmyBuf)
{cout << i << endl;cout << pmyBuf << endl;return;
}int main()
{cout << "main主线程开始执行" << endl;int mvar = 1;int& mvary = mvar;char myBuf[] = "this is a test!";thread myTObj(myPrint, mvar,myBuf);myTObj.detach();cout << "main主函数执行结束了!" << endl;return 1;
}

总结:

  • 若传递int这种简单类型参数,建议都使用值传递,不用用引用类型,避免节外生枝。
  • 若传递类对象作为参数,则避免隐式转换(例如把一个char * 转换成string,一个int转成类A对象),全部都在创建线程这一行就构造出临时对象来,然后仙城入口函数的形参位置使用引用来作为形参(如果不使用引用可能在某种情况下导致多构造一次临时对象,不单浪费,且会造成新的潜在问题)。
  • 总计结论:使用join就没有这个问题了。

17.3.2 临时对象作为线程参数继续讲

1.线程id概念
每个线程对应这不同的id。
使用:std::this _thread::get_id()、
2.临时对象构造时机抓捕

第18章 内存高级话题

第19章 STL标准模板库大局观

第20章 高级话题与新标准

后记 IT职业发展的未来之路

C++笔记(《C++新经典》)相关推荐

  1. C++新经典——C++从入门到精通

    目录 专栏目的 章节目录: 开发环境: 专栏目的 博主开这一个专栏博客的目的是复习巩固博主之前学的C++知识点, 也就是 王健伟老师的C++书籍 <C++新经典>读书笔记 后续会将所有的部 ...

  2. 本站视频相关的C++新经典系列书籍出版

    ​C++新经典系列书籍出版 各位学友,<C++新经典>.<C++新经典:对象模型>两本书已经出版! 其中<C++新经典>书中的内容包含了老师在本站所发布的视频教程& ...

  3. 本站视频相关C++新经典系列书籍再出一本

    各位学友,<C++新经典:Linux通信架构实战>书籍已经出版! 这本书的内容包含了老师在本站所发布的视频教程<Linux C++网络编程>,建议大家在本站购买视频学习时也顺便 ...

  4. 《C++新经典》第1章 C/C++语言

    <C++新经典>第1章 C/C++语言 C语言最突出特点: 效率高. 灵活性.可以直接访问物理地址(操作硬件),进行位运算. C++语言特性:封装性.继承性.多态性. Visual Stu ...

  5. 《C++新经典Linux C++通信架构实战》第2章 进入Nginx之门

    <C++新经典Linux C++通信架构实战>第2章 进入Nginx之门 2.1 Nginx简介.选择理由.安装和使用 2.1.1 Nginx简介 2.1.2 为什么选择Nginx 2.1 ...

  6. 好教程推荐系列:《C++新经典》和《Visual C++ 2017从入门到精通》

    C++新经典 C++新经典:Linux C++通信架构实战 C++新经典:对象模型 C++新经典:模板与泛型编程 C++新经典:设计模式 作者:王建伟,网名:KuangXiang c++11并发与多线 ...

  7. 《C++新经典Linux C++通信架构实战》第1章 课程介绍

    <C++新经典Linux C++通信架构实战>第1章 课程介绍 1.1 本书内容详细介绍 1.1.1 内容总述 1.1.2 为什么选择Linux操作系统平台 1.1.3 讲解规划和学习建议 ...

  8. 咸鱼CAD笔记—2018切换经典模式

    咸鱼CAD笔记-2018切换经典模式 1.打开CAD2018在界面右下角,点击辅助状态栏里倒三角,点击自定义. 2.打开自定义的界面,在折叠图标中打开"工作空间",选择" ...

  9. 《泰晤士报》百本新经典童书推荐-0-3岁宝宝阅读

    <泰晤士报>近期推出的<百本新经典分级阅读童书推荐>选取了最近10年出版的100本最值得推荐的童书.该书单由牛津大学毕业的英国作家和童书评论家.多项童书大奖的评委妮可莱特.琼斯 ...

  10. iOS最新面试题4【经典】_技术成长笔记_新浪博客

    游戏题:   1.项目介绍: 你所在的团队要开始一项为期4个月的iPhone游戏项目.在团队开始工作之前,游戏引擎要支持一些功能. 任务一: 添加触屏支持(创建一个iPhone应用程序,让玩家能用3根 ...

最新文章

  1. c++中的vector的常见使用
  2. Windows 下使用Git管理Github项目
  3. 查看mysql日志文件大小和数据库大小
  4. sqoop导入数据到hive中元数据问题
  5. NYOJ 597 完数?
  6. Vue+ElementUI: 手把手教你做一个audio组件
  7. stm32编程入门_电子设计与单片机编程书籍资料推荐
  8. python中continue只结束本次循环_循环(while,break,continue),转义字符
  9. IntelliJ IDEA导入Maven之后强制刷新项目解决无法识别为Maven项目的问题
  10. 把核心代码全开源,还能做出卡别人脖子的产品吗?
  11. 有关ACM学习的博客链接
  12. android图片拖动放大_Android拖放
  13. iOS cocoapods的使用规范说明及示例(.podspec配置文件)
  14. jquery遍历的radio的取值问题
  15. [工程经验] 电气与控制系统设计方案(框架)- 机器人
  16. java oracle数据备份_Java实现Oracle数据库备份
  17. ORA-12514 错误的处理
  18. 如何手动创建NVivo主题节点?
  19. 回溯法解决01背包-非递归算法-效率低
  20. SCP 从Linux下载文件到Windows本地

热门文章

  1. 使用Excel条件格式-重复值
  2. 秒变“女装大佬”!Snapchat推出性别转换滤镜,离线实时渲染(附测评)
  3. 【Hadoop的初级理解】
  4. 身份证真伪辨别python版
  5. win10html网页运行空白,win10系统Ie浏览器无法打开HTML格式的网页文件的处理秒方...
  6. 关于二重积分,三重积分的理解
  7. 计算机主机配置科普,电脑装机配置 篇八:电脑内存如何选购?内存科普--小白篇...
  8. ESP8266+1.3“ or 0.96“ OLED两个太空人动画(胖子和瘦子)
  9. 1.(python)阿拉伯数字转中文大写
  10. 北斗短报文的工作原理及作用