嵌入式开发高频面试题——第二章 C/C++高频面试题(上)

嵌入式开发高频面试题——第一章 进程与线程 点此进入

2.1 C 和 C++ 的区别、概念相关面试题

2.1.1 new 和 malloc 的区别 ⭐⭐⭐⭐⭐
  • new 是 C++ 的运算符,malloc 是 C 语言的库函数。
  • new
    • 会调用构造函数来初始化对象,并返回具体的对象指针。
    • 返回对象的实际类型,不需要进行强制类型转换。
    • 内存分配失败时会抛出异常 std::bad_alloc
  • malloc
    • 仅仅分配内存,不调用构造函数进行初始化。
    • 需要强制转换返回的 void* 类型指针。
    • 内存分配失败时返回 NULL
    • malloc 只分配内存,free 用于释放。
    • new 配合 delete 使用,自动调用析构函数。
2.1.2 malloc 的底层实现 ⭐⭐⭐⭐

malloc 的底层实现主要依赖于操作系统提供的 brk()mmap() 系统调用。它们可以向内核申请动态内存。内存通常来自堆区,通过链表或分块的方式进行管理。具体实现通常会使用 glibc 中的 ptmalloc 或其他类似算法。它们通过分配内存块和合并空闲内存来提高效率。

2.1.3 在 1G 内存的计算机中能否 malloc(1.2G)?为什么? ⭐⭐

不一定能成功。因为 malloc 分配的是虚拟内存,并不要求物理内存立即足够,但这也依赖于操作系统的虚拟内存管理和交换空间(swap)。操作系统可以使用虚拟内存技术分配超过物理内存大小的空间,但如果超过了系统可用虚拟内存的范围,malloc 就会失败,返回 NULL

2.1.4 指针与引用的相同和区别;如何相互转换? ⭐⭐⭐⭐⭐
  • 相同点

    • 都可以用于操作其他变量或对象。
  • 区别

    • 指针
      • 可以改变所指向的对象。
      • 可以是 NULL,不一定指向有效对象。
      • 使用 * 访问指向的对象,使用 & 获取变量地址。
    • 引用
      • 必须在声明时初始化,不可以改变所引用的对象。
      • 不能是 NULL
      • 更像是别名,不需要使用特殊符号直接访问。
  • 转换

    • 可以通过 & 运算符将引用的地址转为指针。
    • 可以通过 * 运算符将指针转换为引用指向的对象。
2.1.5 C 语言检索内存情况,内存分配的方式 ⭐⭐⭐

C 语言中的内存分配可以通过以下方式:

  • 静态分配:在编译时分配固定大小的内存,如全局变量、静态局部变量。
  • 动态分配:在运行时分配内存,如 malloccallocrealloc
2.1.6 extern "C" 的作用 ⭐⭐⭐

extern "C" 是用来告知编译器该块代码或函数遵循 C 语言的链接规范,而不是 C++ 的。C++ 使用的是名字修饰(name mangling),而 C 语言不使用。通过 extern "C" 可以让 C++ 和 C 函数互相调用。

2.1.7 头文件声明时加 extern 定义时不要加 因为 extern 可以多次声明,但只有一个定义 ⭐⭐⭐⭐

extern 关键字通常用于声明变量或函数,而不是定义。它告诉编译器该变量或函数的定义在其他地方,因此同一个变量或函数可以在多个文件中声明但只需要定义一次。

2.1.8 函数参数压栈顺序,即关于 __stdcall__cdecl 调用方式的理解 ⭐⭐⭐
  • __cdecl:函数的参数由调用者清理,参数从右到左入栈,这是 C/C++ 的默认调用约定。
  • __stdcall:函数的参数由被调用者清理,参数也是从右到左入栈。
2.1.9 重写 memcpy() 函数需要注意哪些问题 ⭐⭐
  • 避免内存重叠,应该考虑内存区域的重叠问题,可以通过检查源地址和目标地址来解决。
  • 考虑指针的对齐问题,避免未对齐访问导致性能问题或崩溃。
  • 需要正确处理不同数据类型的内存拷贝,如字节、整数、浮点数等。
2.1.10 数组到底存放在哪里 ⭐⭐⭐

数组在内存中的存放位置取决于数组的类型:

  • 局部数组:存放在栈中。
  • 全局数组或静态数组:存放在数据段(静态内存区)。
  • 动态分配的数组:存放在堆中。
2.1.11 structclass 的区别 ⭐⭐⭐⭐⭐
  • 区别

    • struct:默认成员的访问权限是公有(public)。
    • class:默认成员的访问权限是私有(private)。
  • 相同点

    • 两者都可以包含数据和函数成员。
2.1.12 charint 之间的转换 ⭐⭐⭐

在 C/C++ 中,charint 之间的转换通常是隐式的。char 占 1 个字节,而 int 占多个字节。当将 char 转换为 int 时,字符的 ASCII 值被提升为 int,反之亦然。

2.1.13 static 的用法(定义和用途) ⭐⭐⭐⭐⭐
  • static 变量

    • 在函数内声明时,函数调用结束后变量的值不会丢失。
    • 在全局作用域内,static 变量的作用域只限于当前文件。
  • static 函数

    • 限定函数的作用范围,使其只能在声明它的文件中可见。
2.1.14 const 常量和 #define 的区别(编译阶段、安全性、内存占用等) ⭐⭐⭐⭐
  • const:有类型检查,属于编译时常量,存储在内存中。
  • #define:没有类型检查,属于预处理指令,不占用内存,只是简单的文本替换。
2.1.16 volatile 的作用和用法 ⭐⭐⭐⭐⭐

volatile 告诉编译器不要对该变量进行优化,强制每次访问都从内存中读取值,避免因为编译器优化导致的错误。常用于硬件寄存器或多线程程序中被其他线程修改的变量。

2.1.17 有常量指针、指针常量、常量引用,没有引用常量 ⭐⭐⭐
  • 常量指针:指针指向的内容不能更改。
  • 指针常量:指针本身不能修改,但指向的内容可以修改。
  • 常量引用:引用的值不能被修改。
  • 没有引用常量的概念,引用是别名,指向对象的常量属性。
2.1.18 没有指向引用的指针,因为引用是没有地址的,但有指针的引用 ⭐⭐⭐

引用在底层实现上是指向对象的指针,但 C++ 语法上不允许存在指向引用的指针。不过,可以有“指针的引用”,即引用指向一个指针。

2.1.19 C/C++ 中变量的作用域 ⭐⭐⭐⭐⭐
  • 局部变量:在函数或代码块中声明,作用范围是函数或块的内部。
  • 全局变量:在函数外部声明,作用范围是整个文件和其他引用的文件。
  • 静态局部变量:在函数中声明的静态变量,生命周期贯穿整个程序执行过程,但作用域依然是该函数。
  • 静态全局变量:只能在声明的文件中访问。
2.1.20 C++ 中类型转换机制?各适用什么环境?dynamic_cast 转换失败时会出现什么情况? ⭐⭐⭐

C++ 提供了四种类型转换方式:

  • static_cast:用于

基础数据类型之间的转换和父类子类之间的指针/引用转换。

  • dynamic_cast:用于多态类型之间的安全转换。如果转换失败,返回 NULL 指针(对于指针)或抛出 bad_cast 异常(对于引用)。
  • const_cast:用于添加或移除对象的 const 限定符。
  • reinterpret_cast:用于不同类型指针之间的转换,不安全的强制转换。

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Fruit_Caller

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

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

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

打赏作者

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

抵扣说明:

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

余额充值