c++与c语言相关面试题

C与C++面试题解析

解释下C与C++的区别?

C++是C语言的继承与发展,兼容C的语法,但引入了面向对象编程(OOP)范式。
从面向过程到面向对象的核心转变,使得C++在代码复用性、安全性和工程化能力上显著提升。具体如下:

一、面向对象特性
1. 封装性:

C语言(无封装)

  • 结构体(struct)仅作为数据容器,成员完全公开。
  • 数据操作依赖外部函数,易导致数据被误修改。
    C++(强封装)
  • 通过classstruct将数据与操作封装为对象
  • 访问控制private隐藏内部细节,public暴露接口。
  • 构造函数/析构函数:确保对象初始化和资源释放。
    2. 继承性:代码复用与层次化设计

C语言(无原生继承):通过结构体嵌套模拟继承,但无语法支持。
C++(语法级继承)

  • 公有/私有继承:明确派生类与基类的关系。

  • 复用基类代码:减少冗余,提升可维护性。

    3. 多态性:动态绑定与接口抽象

C语言(手动模拟多态):通过函数指针实现多态,代码复杂且易出错。
C++(原生多态支持)

  • 虚函数(virtual:通过虚函数表(vtable)实现动态绑定。
  • 纯虚函数:定义接口规范(类似Java的interface)。
二、内存管理范式

new/delete vs malloc/free

  • 对象生命周期管理
    • new:分配内存 + 调用构造函数(对象初始化)。
    • delete:释放内存 + 调用析构函数(资源清理)。
  • RAII机制:通过对象作用域自动管理资源(如文件句柄、锁)。
    mallocfree 管理的是动态分配的内存,而与对象的作用域无关。当你使用 malloc 分配内存时,这块内存将在堆(heap)中分配,这意味着它的生命周期独立于任何特定作用域。
三、编译与链接机制

函数名修饰(Name Mangling)
- C:函数名保持不变(如funcfunc),不支持重载。
- C++:函数名 + 参数类型编码到符号表(如func(int)_Z4funci),支持重载。
- 影响:C++需用extern "C"禁用修饰以兼容C库。

四、变量初始化规则

静态变量初始化时机
- C:全局/静态变量在程序启动前初始化(编译期完成,仅支持基本类型)。
- C++
- 局部静态变量:首次使用时初始化(线程安全,C++11起)。
- 支持复杂对象的构造(如调用类的构造函数)。

--------------------------------------------------------------------------------

说说C++的structclass以及C的struct区别

  1. 默认访问struct成员和继承默认publicclass默认private
  2. 模板参数:模板中只能用classtypename,不能用struct
template <class T> // 合法
class Container {};
template <struct T> // 非法!
class AnotherContainer {}; 
  1. C的struct:仅数据集合,无函数、访问控制或继承。
    此外,C++11允许成员变量默认初始化,
    C不可在声明时初始化成员,需在实例化时或之后赋值。
    C声明变量需带struct关键字,或对结构体使用typedef取别名,C++可省略
	struct Point { int x, y; };
	struct Point p = {1, 2}; 
	struct Point p1;          // 合法
	typedef struct Point Point; 
	Point p2;                // 合法(需typedef)
	struct Point {
	    int x = 0; // C++11允许
	    int y = 0;
	};
	Point p; // 合法

总结对比表

特性C的structC++的structC++的class
成员函数不支持支持支持
访问控制默认公有默认公有默认私有
继承默认权限无继承默认public继承默认private继承
模板参数不适用不可用可用(与typename等价)
成员默认初始化不支持(C11前)支持(C++11起)支持(C++11起)
变量声明方式struct关键字或typedef直接使用类型名直接使用类型名

--------------------------------------------------------------------------------

说说newmalloc的区别,各自底层实现原理

特性newmalloc
语言C++操作符C标准库函数
重载支持重载(operator new不可重载
内存分配自动计算所需内存大小需手动指定字节数
类型安全返回类型安全指针(无需强转)返回void*(需强转)
错误处理默认抛出std::bad_alloc异常返回NULL
构造/析构调用构造函数和析构函数仅分配/释放内存
内存来源自由存储区(可能位于堆或静态存储区)堆(Heap)
  1. 功能new是C++操作符,分配内存并调用构造函数;
    malloc是C库函数,仅分配内存。new可以被重载,malloc不行。
  2. 类型安全new返回类型指针,malloc返回void*需强转。
  3. 错误处理new默认抛异常,malloc返回NULL
  4. 底层实现上malloc通过brk/mmap管理堆内存,使用隐式链表减少碎片;
    new通常调用malloc分配内存,再调用构造函数初始化对象。
    malloc的实现
    • 内存分配策略
      • 小块内存(<128KB):通过brk()系统调用调整堆顶指针(break),扩大堆空间。
      • 大块内存(≥128KB):通过mmap()直接在内存映射区分配匿名内存页。
    • 内存池管理
      • 隐式空闲链表:通过内存块头部信息(如块大小、是否空闲)串联所有内存块。
      • 分割与合并:分配时分割空闲块,释放时合并相邻空闲块以减少碎片。
    • 性能优化
      • 缓存机制:维护多个内存池(如fastbins)加速小块内存分配。
        new的实现
        内存分配
    • 调用operator new:底层通常调用malloc,但可重载以实现自定义分配策略。
    void* operator new(size_t size) { 
        return malloc(size); // 默认实现
    }
    
    对象构造
    • 分配内存后,编译器插入代码调用构造函数。
    MyClass* obj = new MyClass();
    // 等价于:
    void* mem = operator new(sizeof(MyClass)); // 分配内存
    MyClass* obj = static_cast<MyClass*>(mem);
    obj->MyClass();                            // 调用构造函数
    
    异常处理
    • 默认抛出std::bad_alloc异常,但可通过new (nothrow)禁用异常。
    MyClass* obj = new (nothrow) MyClass(); // 失败返回nullptr
    

--------------------------------------------------------------------------------

简述C/C++从源码到执行文件的整体流程

从源码到执行文件的整体流程上,C 和 C++ 的编译过程基本一致,都遵循 预处理 → 编译 → 汇编 → 链接 四个核心阶段,但在具体细节实现上存在差异。

1. 预处理(Preprocessing)
  • 共同点
    • 处理 #include#define#ifdef 等预编译指令。
    • 删除注释,展开宏,生成 预处理后的代码.i 或 .ii 文件)。
  • 差异
    C++ 预处理阶段可能处理更复杂的模板和命名空间等语法结构。
2. 编译(Compilation)
  • C/C++ 共同点
    • 将预处理后的代码转换为 汇编代码.s 文件)。
    • 检查语法、类型、语义错误。
  • 差异
    • C++ 编译器(如 g++)默认启用名称修饰(Name Mangling),而 C 编译器(如 gcc)不会。
3. 汇编(Assembly)
  • 完全一致
    • 将汇编代码转换为机器码,生成 目标文件.o 或 .obj 文件)。
4. 链接(Linking)
  • 共同点
    • 合并多个目标文件和库,解析符号引用,生成最终 可执行文件(如 .exe 或 .out)。
  • 差异
    • C++ 需要链接标准库(如 libstdc++ 或 libc++),而C仅需 libc
    • C++ 的名称修饰可能导致符号不兼容,混合 C/C++ 代码时需用 extern "C" 声明。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值