前言:
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()结束程序