今天开始学C++,计划开始更新每天的学习笔记,希望在接下来的一个月中能坚持下去。
C++的发展历史
诞生
C++是C语言的继承,由贝尔实验室的Bjarne Stroustrup博士于1982年在C语言的基础上发明,至今已有近40年的历史。C++可以看作是C语言的超集,C代码几乎不经修改就可以在C++环境下运行。由于C++既支持面向过程编程,也支持面对对象编程,泛型编程和模板元编程等范式,功能及其强大,但随之而来的问题就是该语言极其复杂,学习难度也相对较高。
发展过程
C++的发展可大致分为以下三个阶段:
第一阶段:从上世纪80年代到90年代中期,凭借面向对象特性和接近C语言的高效率,C++在工业界占到了相当大的份额;
第二阶段:1995-2000年,由于Java等语言的出现,C++受到了一定冲击;
第三阶段:2000年至今,由于C++引入了更新的概念及技术,如模板元编程,使得C++成为最复杂的编程语言,但同时也迎来了C++发展史上的又一高峰。
版本迭代https://isocpp.org/STD/STATUS
与其他语言的对比
语言 | 性能 | 开发效率 | 学习难度 |
---|---|---|---|
汇编 | 极高 | 极低 | ⭐⭐⭐⭐⭐⭐ |
C | 高 | 较低 | ⭐⭐⭐⭐ |
C++ | 高 | 较低 | ⭐⭐⭐⭐⭐ |
Java | 中 | 较高 | ⭐⭐⭐ |
Python | 低 | 高 | ⭐ |
市场占有率排名(2019.07)https://www.tiobe.com/tiobe-index/
C++头文件
C++头文件没有后缀.h,因为大部分头文件都是用模板实现,头文件的放置顺序为:自定义头文件,C头文件,C++头文件
命名空间
命名空间可以嵌套,访问全局变量用::,这是匿名的命名空间,为了兼容C语言(C语言没有命名空间)
const修饰的常量与#define有何区别?
const是在编译阶段展开且有类型检查,在声明的时候必须初始化,可以节省空间,避免不必要的内存分配;而#define是在预处理阶段展开,只进行简单的文本替换,无类型检测,有一定几率发生意想不到的错误。在C++中建议使用const代替#define。
malloc/free与new/delete的区别?
malloc与new的区别
- malloc/free是库函数,而new/delete是关键字;
- 使用malloc分配内存空间需要指定大小,而new不需指定;
- malloc返回void*,需要强制类型转换;而new返回类型与对象指针相同,无需强制转换;
- 但分配内存失败时,malloc返回NULL,而new抛出bac_alloc异常;
- malloc开辟内存空间不会进行初始化,而new开辟空间时会进行初始化。
free与delete的区别
- free释放malloc分配的空间,delete释放new分配的内存空间,二者不能混用;
- delete[]释放new[]分配的空间;
- delete会调用相应的析构函数,free不会;
- 在调用free之前要判断指针是否为空,调用delete则不需要;
引用和指针的区别
- 引用必须初始化,引用到一个有效对象,而指针不必初始化,可以随时重新赋值;
- 指针可以为NULL,引用不可;
- 引用可以看作是某一变量的别名,一旦修改,则原变量的值也会随之改变;
- 引用一旦初始化,就不能在引用其他变量,而指针可以改变指向。
malloc的底层实现是怎么样的,free如何回收内存
这个问题比较复杂,暂时不太明白,百度了一下,简单说说:
- malloc的基本实现原理是维护一个空闲内存链表,当申请内存时,系统利用内存搜索算法寻找合适的内存空闲区块,然后将该区块分成两部分:分配块和新的空闲块。常见的内存搜索算法有:首次匹配,下一次匹配和最佳匹配。
- free其实并不会回收内存,它只是告诉操作系统要释放某块内存,然后由操作系统进行回收,free并不会将该指针置为NULL,需要手工置NULL,以免其成为野指针,操作系统收回该内存块后,会将相邻的空闲内存块进行合并,然后更新空闲内存表,以供下次申请内存使用。由于malloc在申请内存时就已经将大小写入内存,所以free在释放的时候无需传入大小。
inline函数与带参数的宏定义的区别
- 内联函数在编译时展开,而宏在预处理阶段展开;
- 内联函数直接嵌入到目标代码中,而宏只是做简单的文本替换;
- 内联函数有类型检测,语法判断,而宏没有;
- 内联函数属于函数,不会产生歧义,而宏可以会产生歧义。