C++一些知识点总结

全局变量的缺点

缺点:
全局变量在main函数执行前初始化,会影响程序启动速度
全局变量会长期占用内存
全局变量会破坏代码的封装性,增加了程序的耦合性
全局变量被误操作修改的可能性更大
基于这些原因,最终也就可能导致代码可读性差、难以调试

static、final、volatile、const、extern关键字

static:

1.static作用于局部变量,改变了局部变量的生存周期,使该变量在定义后直到程序运行结束的这段时间始终保存在数据段。但其作用域还是局部的。

2…static作用于全局变量和函数,使全局变量和函数只能在定义它的文件中使用,其它文件中可以定义相同名字的变量和函数,不会发生冲突

3.static修饰的类成员是该类的所有对象所共有的。静态成员变量只分配一次内存,供所有对象共用。static修饰的变量先于对象存在,所以static修饰的变量要在类外初始化。静态成员函数没有this指针,只能访问类的静态成员,不能定义成虚函数。

static变量初始化时机:

全局静态变量、类的静态成员变量在main函数执行之前初始化

局部静态变量在第一次使用时初始化
final:
修饰类,该类不可被继承,修饰虚函数,该虚函数不能被重写

extern :
修饰全局变量:表明该变量定义在其他源文件。
修饰全局常量:全局常量默认链接属性是内部链接,其他源文件不可见。extern修饰后改变链接属性为外连接
C++在函数前加extern “C”,意思是告诉编译器将函数按照C的风格来编译

volatile:
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从内存中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值

const:

  1. const 修饰普通变量,将变量定义成常量,相较于宏常量可进行类型检查,节省内存空间。const修饰的成员变量,在某个对象的生命周期内是常量,只能在类内声明定义,在构造函数初始化列表初始化。
  2. const修饰函数参数,不允许函数参数被修改。const修饰成员函数,实际上修饰的是this指针,目的是不允许函数修改成员变量,所以也不能访问非const成员函数。

sizeof 和 strlen 的区别

  1. strlen是函数,在程序运行时候进行计算。sizeof是C++运算符,在编译期间计算。
  2. strlen 计算的是以 \0 结束的字符串的长度,参数必须是char* 类型。
    而 sizeof 可以用于类型和变量,传入数组名的时候,计算的是数组占的字节数。strlen可以传入字符数组数组名,计算的还是\0 结束的字符串的长度。

引用

引用不是新定义一个变量,而是给已存在变量取了一个别名,它和它引用的变量共用同一块内存空间。

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体
  4. 如果函数返回时,出了函数作用域,如果返回对象生命周期未结束,则可以使用引用返回,否则须使用传值返回。
  5. 在语法概念上引用就是一个别名,没有独立空间,在底层实现上实际是有空间的,因为引用是按照指针方式来实现的

指针和引用的不同:

  1. 引用在定义时必须初始化,指针没有要求
  2. 引用在引用一个实体后,就不能再引用其他实体,而指针可改变指向
  3. 没有NULL引用,但有NULL指针,因为这几点,所以 引用比指针使用起来相对更安全
  4. 在sizeof中含义不同:引用结果为引用类型的大小,指针始终是地址空间所占字节个数
  5. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  6. 有多级指针,但是没有多级引用
  7. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理

函数重载的原理

C++编译器用参数个数和参数类型对每一个函数标识符进行专门编码,编译后链接时,通过这个编码可以找到对应函数的地址链接起来

C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同(返回值不影响是否构成重载),修饰出来的名字就不一样,就支持了重载

NULL和nullptr

NULL实际是一个宏,被定义为字面常量0,或者被定义为无类型指针的常量 ((void *)0)
由于C++支持重载,传参传入NULL时候可以匹配到整型和指针类型,有歧义,所以为了提高代码的健壮性C++建议使用nullptr
nullptr是C++11关键字,所以nullptr表示指针空值时,不需要包含头文件

//define定义标识符常量
#define MAX 1000
//define定义宏
#define ADD(x, y) ((x)+(y))

优缺点:
优点:

1.增强代码的复用性。
2.提高性能。

缺点:

  1. 可读性差
  2. 程序在预处理阶段进行宏替换,预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,所以宏不做语法检查,没有类型安全检查。
  3. 宏不方便调试(因为预编译阶段进行了替换)

替代宏的语法:

  1. 常量定义 换用const

  2. 函数定义 换用内联函数
    以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。

  3. enum
    枚举有类型检查,更加严谨,方便调试

define定义宏和const的区别

  1. define 是在预处理阶段进行替换,const 是在编译阶段确定其值。
  2. define 定义的宏常量没有数据类型,只是进行简单的代码替换,不会进行类型安全的检查
  3. 宏定义本身不占用内存空间,某个宏常量在程序中使用多少次就会进行多少次替换,内存中有多个备份。const 定义的常量内存中只有一份。
  4. define 定义的宏常量不能调试,因为在预编译阶段就已经进行替换了;const 定义的常量可以进行调试。
  5. define 可以接受参数复杂的表达式。

类和对象

面向对象和面向过程

C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。

C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

面向对象的三大特性:

封装

将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

继承

多态

链表经典程序

栈和队列

牢牢把握性质,会解决相关题目

二叉树、堆

排序

各个排序的复杂度,快排、堆排、归并排序都要会写

AVL树

红黑树

map和unordered_map的区别

🔗

STL容器

什么是迭代器,作用是什么

1.体现了容器的封装性,不暴露容器实现细节的情况,提供了一种类似的方式去访问修改容器
2.方便算法去对容器的数据进行处理

顺序表和链表的区别

1.空间是否连续,内存碎片问题、空间利用率、缓存利用率
2.是否支持随机访问
3.插入删除效率
4.增容问题

vector 和 list 的区别

1.vector底层是顺序表,list底层是带头双向循环链表,顺序表和链表的区别
所以,vector适用于支持随机访问,不关心插入删除效率的场景
list适用于大量插入删除,不关心随机访问的场景
2.迭代器是否是原生态指针
3.迭代器失效问题,vector插入删除迭代器都会失效,list插入元素不会导致迭代器失效,删除元素时,只会导致当前迭代器失效

map 和 set

malloc和free的区别

malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地方是:

  1. malloc和free是函数,new和delete是操作符
  2. malloc申请的空间不会初始化,new可以初始化
  3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可
  4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
  5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常
  6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用自定义类型的构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神奇dyl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值