C和C++的区别
C和C++都是广泛使用的编程语言,但它们有显著的区别:
语言范式:
- C:是一种过程化编程语言,强调过程和函数的使用。
- C++:是一种多范式编程语言,支持面向对象编程、泛型编程和过程化编程。
类和对象:
- C:没有类和对象的概念。
- C++:引入了类和对象的概念,支持封装、继承和多态。
标准库:
- C:标准库比较小,主要包含一些基础的函数库。
- C++:标准库更大,包含STL(标准模板库),提供了丰富的数据结构和算法。
内存管理:
- C:主要使用
malloc
和free
进行动态内存分配和释放。 - C++:除了
malloc
和free
,还提供了new
和delete
操作符,更适合对象的动态内存管理。
- C:主要使用
类型检查:
- C:类型检查相对宽松,支持隐式类型转换。
- C++:类型检查更严格,支持重载、模板等特性。
C++中指针和引用的区别
定义:
- 指针:保存变量地址的变量,可以重新赋值,指向不同的变量。
- 引用:是一个变量的别名,一旦绑定到一个变量,不能重新绑定。
语法:
- 指针:使用
*
和&
操作符。 - 引用:使用
&
符号,但在使用时像普通变量一样。
- 指针:使用
内存分配:
- 指针:需要存储地址的空间。
- 引用:不需要额外的存储空间。
初始化:
- 指针:可以不初始化。
- 引用:必须在声明时初始化。
结构体struct和共同体union(联合)的区别
内存分配:
- struct:每个成员有自己的内存空间,总大小是所有成员大小的总和。
- union:所有成员共享同一块内存,大小是最大成员的大小。
访问:
- struct:所有成员可以同时访问。
- union:同一时刻只能访问一个成员,修改一个成员会影响其他成员。
用途:
- struct:用于需要同时访问多个数据的情况。
- union:用于节省内存,需要在不同时间存储不同数据的情况。
#define和const的区别
类型检查:
- #define:是预处理指令,不进行类型检查。
- const:是编译时常量,有类型检查。
作用范围:
- #define:在预处理阶段进行替换,不局限于某个作用域。
- const:遵循作用域规则,只在声明的作用域内有效。
调试:
- #define:替换后无调试信息,难以调试。
- const:有类型和作用域信息,易于调试。
重载overload,覆盖(重写)override,隐藏(重定义)overwrite的区别
重载(overload):
- 定义:同一个作用域内,同名函数的参数列表不同。
- 用途:增加函数的多态性,提高代码灵活性。
覆盖(重写)(override):
- 定义:子类重新定义父类中的虚函数。
- 用途:实现多态,允许子类提供特定实现。
隐藏(重定义)(overwrite):
- 定义:子类定义了一个与父类同名的新函数,但参数列表不同或不是虚函数。
- 用途:在子类中隐藏父类同名函数,防止误用父类函数。
new、delete、malloc、free之间的关系
new/delete:
- new:分配对象内存并调用构造函数。
- delete:释放对象内存并调用析构函数。
malloc/free:
- malloc:分配指定字节的内存,不调用构造函数。
- free:释放内存,不调用析构函数。
delete和delete[]的区别
- delete:用于释放单个对象。
- delete[]:用于释放数组对象。
虚函数、纯虚函数
虚函数:
- 定义:在基类中使用
virtual
关键字声明,允许子类重写。 - 用途:实现运行时多态。
- 定义:在基类中使用
纯虚函数:
- 定义:在基类中声明,但不提供实现,用
=0
表示。 - 用途:定义抽象类,要求子类必须实现。
- 定义:在基类中声明,但不提供实现,用
STL库用过吗?常见的STL容器有哪些?算法用过几个?
常见STL容器:
- 序列式容器:
vector
,list
,deque
,array
- 关联式容器:
set
,map
,multiset
,multimap
- 序列式容器:
常见STL算法:
- 排序:
sort
- 查找:
find
- 变换:
transform
- 复制:
copy
- 排序:
const的作用
- 常量声明:
const int x = 5;
- 常量指针:
const int* p;
- 常量成员函数:
int getValue() const;
虚函数的实现
通过虚函数表(vtable)实现,编译器为每个类创建一个vtable,存储虚函数指针。
堆和栈的区别
分配方式:
- 堆:动态分配,需要手动管理(
new
/delete
)。 - 栈:自动分配,函数调用结束自动释放。
- 堆:动态分配,需要手动管理(
存储内容:
- 堆:动态分配的对象。
- 栈:局部变量和函数调用信息。
关键字static的作用
- 局部变量:静态局部变量,生存期延长到程序结束。
- 类成员:静态成员变量/函数,属于类而非对象。
- 文件作用域:静态全局变量/函数,限制在文件内可见。
STL中map和set的原理(关联式容器)
- map:基于红黑树,键值对存储,支持快速查找。
- set:基于红黑树,唯一元素存储,支持快速查找。
include和#include"file.h"的区别
- 尖括号:从标准库路径查找。
- 双引号:从当前目录查找,然后是标准库路径。
什么是内存泄漏?面对内存泄漏和指针越界的方法
内存泄漏:动态分配的内存未释放。
- 方法:使用智能指针,定期检查和释放。
指针越界:指针访问非法内存。
- 方法:使用调试工具(如Valgrind),严格检查边界。
定义和声明的区别
- 定义:分配内存,如
int x;
- 声明:说明存在,不分配内存,如
extern int x;
C++文件编译与执行的四个阶段
- 预处理:处理
#include
、#define
等预处理指令。 - 编译:将源码翻译为目标代码。
- 汇编:将目标代码转换为机器指令。
- 链接:将目标文件和库文件合并生成可执行文件。
STL中的vector的实现,是怎么扩容的?
vector
通过动态数组实现,当容量不足时,分配更大的内存(通常是原来的两倍),复制旧数据到新内存,并释放旧内存。