前言
笔者面试了一个偏硬件的岗位,准备了很多操作系统和底层驱动有关的内容,结果被面试官用C++语言特性狠狠拷打。C++开发讲究的是细分领域,越往后越没有人在意你是不是了解语言特性,但是对相关行业经验的要求就越高。作为初入行业的新人,在经验这块是比较欠缺的,相比之下,C++八股还是比较容易上手的,属于努努力就能学会的类型,作为年轻人还是再拼一把吧,少一点怨天尤人,多抓住每一个机会去尝试。
关于语言类型
C/C++是强类型还是弱类型,属于静态语言还是动态语言?
- 强类型(依据:只允许以不丢失信息为前提的自动类型转换)
- 静态(依据:数据类型在编译阶段检查)
那静态类型语言一定是类型安全的吗?
不一定。首先看类型安全的定义:编程语言不允许错误的运算或转换发生。然而,静态语言检查的只是数据类型,这只是错误的一部分,并不是全部;而且也不能保证所有错误都能被捕捉到。两者没有必然联系。
C++的类型转换有哪些?
static_cast(用于明确定义的转换)dynamic_cast(类继承结构中类型安全的对象指针向下转换)const_cast(const->non const /volatile->non volatile)reinterpret_cast(在位运算层面操作)
const 和volatile
const *p和*const p的区别是什么?
被const修饰的表示为常量,它的值不可修改。至于这两者的区别,要看const后面紧跟着的是什么:
const *p中const后面紧跟着*,这个*是取值的意思,说明const用于修饰指针变量指向的内容,即该内容不可修改,但指针变量本身的值可以修改*const p中const紧跟着指针p本身,指的是指针变量值为常量,不可修改
谈谈你对volatile关键字的理解?
volatile是指“易变的”,它告诉编译器不要对与volatile有关的运算进行编译优化,并且为了防止前后读取数据不一致,是直接从内存中读取。
指针可以是volatile的吗?能举个例子吗?
可以,因为指针和普通变量一样也有可能发生意想不到的改变。
具体例子:中断服务子程序修改一个指向buffer的指针时,该指针需要用volatile修饰。
还有哪些情况会用到volatile?
- 最常见的是多线程应用中被共享的变量
- 并行设备的硬件寄存器
内存管理
堆和栈的区别?
这个问题涉及到内存的组织结构。内存大致划分为四个部分:
- 栈(向下生长,往内存地址减小的方向)
- 堆(向上生长)
- 数据段
- 代码段
其中:
- 堆存放程序执行中动态分配的内存段,存放的对象是全局的。
- 栈存放临时创建的局部变量、函数参数、函数返回地址等,存放的对象是局部的。
以下是一些可能被追问的问题:
- 堆和栈的大小对比?栈通常远小于堆
- 资源管理与分配方式?堆中资源由程序员管理,不连续的内存区域;栈中由编译器管理,连续的内存区域
- 堆和栈的碎片问题?由于堆的内存不连续,频繁new又delete会,但栈不会。
你说说C++中的几个malloc有什么异同?
- malloc(size_t size):动态分配size字节的空间
- calloc(int num_elements, size_t size):动态分配num_elements*size字节的空间,并初始化为0
- realloc(void *ptr, size_t size):重新调整之前调用 malloc 或 calloc 所分配的 ptr 所指向的内存块的大小.
具体方式如下:
- ptr --。如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针。
- size -- 内存块的新的大小,以字节为单位。如果大小为 0 ,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针。
malloc和new的区别
- malloc是C中的标准库函数;new是C++支持的运算符。两者都是针对堆空间的管理机制
- 对于内置数据类型而言,两者等价
- 对于非内置数据类型而言,malloc是函数,不在编译器控制权限内,因此需要new的帮忙
语言关键字特性
内联函数与宏的区别?
- 宏由预处理器展开,内联函数在编译时展开
- 内联函数会检查参数类型,因此更安全
断言的作用?
强制检查。如果某个表达式的值为假,会输出错误信息,并调用abort()结束程序