- 如何又快又好的学好C++
- 1 入门
- 关于指针
- 关于内存
- 普通变量
- 数组
- 智能指针
- 2 学习过程中的坑
- 2.1 iostream
- 2.2 未完待续
作为未来可望见时间范围内的工业软件开发的不二语言——C++,有着强大的开发效率和运行效率,也有的让很多人摸不着头脑的巨量知识,博主今天结合自身经验谈一谈如何学好C++,以及C++中的一些明显的坑。 1 入门
和C语言一样,C++其实也是一个面向机器硬件的语言,不然哪来那么高的性能呢? 面向机器的特点,就是——什么你都得自己干。
但凡你要干点有动态特性的事情, 内存你得自己分配和释放, 取地址,解引用也得显示写明, 要是你用了c-string,连复制个字符串你都得留神,不能忘了末尾的‘ ’
但是也和C语言一样,C++几乎没有违反直觉的语法,这是与python、fortran、visual basic等“高级”动态语言形成鲜明的对比。你只需要学会C语言,弄清楚内存和指针,那么学C++的时候,这是补充一下相关知识而已。
关于指针说两句关于指针的吧。
汇编时期,无所谓指针不指针, 都是直接操作地址,先把地址装入寄存器,然后从这个地址中取数,最后把运算结果存到某个地址中。
到了C语言中,有普通变量了, 比如int a =5, 那意思就是把label a对应的地址赋值为5. 这时候a只是一个助记符而已.
但不是每个地址都有助记符的, 数组, 也就是一片连续的内存,就不可能每个地址都有助记符了,而只是数组首地址有个助记符, 那就是数组名. 比如下面的arr
int arr[5] = {0, 0, 0, 0, 0}
arr后面的4个元素都没有助记符。没有助记符怎么访问这些元素呢, 那就是直接用地址喽!
比如arr+1, 就是arr的内容(地址值)加上1个int元素的偏移字节数,如果arr = 56, 那么一个int偏移是4字节,arr+1就等于 60 了。
要为地址为60的内存(或者arr数组的第一个元素)赋int值,c语言中至少三种等价写法
*((int*)60) = 5; //二逼青年写法,或者极黑的黑客写法 *(arr+1) = 5; //文艺青年写法 arr[1] = 5; // 普通青年写法
第一种写法没人用,第二种写法有一部分人用,第三种写法是常用的: arr[1]是c语言的语法糖, 让你快速操作数组。
指针的出现,原本是为了操作内存,就是这么简单。
关于内存未完待续
物理内存就是你装机的时候插进去的那一个或者两根内存条提供的内存容量.
虚拟内存空间就是你操作系统的位数之下,能访问到的最大虚拟内存地址。32bit OS是4GB的内存地址,64bit OS理论上是2^64 字节的内存空间。
但CPU制造商采取了一条捷径。它们使用允许完整的64位地址空间的指令集,但当前的CPU仅使用较低的48位,所以目前64bit OS的虚拟内存地址空间只有2^48字节。
虚拟内存和物理内存什么关系呢? 这是个复杂的话题,只要知道程序分配内存都是在虚拟内存上分配的,所以我们关注虚拟内存就可以了。
普通变量有空再写
数组 智能指针 2 学习过程中的坑 2.1 iostream流式处理是C++诞生初期,利用算子重载(operator overloding)特性搞出来概念,用<<和>>来方便的完成输入和输出。流式处理是个好东西,只要你能抽象出一个sink对象,就能利用流式操作,往这个sink里边不停追加数据,这就是ostream的设计思路; 或者你只要能抽象出一个数据源, 你就能通过流式操作不停的取出数据直到“取”操作失败。
但是C++的istream和ostream模块,设计的却相当糟糕。尤其是stringstream, 居然是取不出数据来的, 也就是你写了半天,只能通过str()方法, 来得到一个值拷贝,这无疑是非常低效的。相比之下,Qt的OIODevice那就设计的逻辑清晰而且高效了,借用物理中的“源”和“汇”来说,你可以指定接受数据的“汇”, 还能把这个“汇”数据拿走,而OIODevice只不过提供一个读写的统一接口而已,这才是工程中最常用的场景。
而iostream则是糟糕叠加糟糕, 它本来负责向stdout输出和输入字符串, 实际工程中,我们碰到的输入输出全是要进行格式化的。要是不格式化,屏幕上写的乱糟糟谁也看不明白,就失去了输出的意义。
输出确实可以抽象成流,但是格式化却跟流没关系。iostream强行把两个凹在一起,成就了一个四不像,既不好看,也不好用。比如输出用10个字符宽度,6个有效数字,输出浮点数, iostream得这么写
#includecout< 用 printf的话
printf("%8.6f", 3.5)我想正常人都知道该选哪种方法,如果还不懂的,尝试输出5个浮点数,前两个用科学计数法,后三个用普通输出,有效数字要各不一样,这时候用cout就知道多麻烦了。
所以给初学C++的朋友们一个建议, 不要在iostream上花费太多功夫,printf虽然年岁很高,但依然“宝刀不老”,好多书上来就教iostream,纯属误人子弟
但是printf无法打印std::string之类的对象,所以后来诞生了fmt库,这个库的格式化语法和printf思路、python format思路一致,写起来方便。因为好多格式化过程在编译期完成,所以性能也十分高,是c++格式化输出的不二选择。fmtlib已经进了c++ 20 的标准,也是std::format那一套东西,都可以选用。
2.2 未完待续



