C++说爱你不容易-2
C++软件与嵌入式软件面经解析大全(蒋豆芽的秋招打怪之旅)
本章讲解点
- 1.1 C++与C的区别——看看你的理解是否深刻
- 1.2 从代码到可执行文件的过程
- 1.3 extern "C"
- 1.4 宏——到底是什么
- 1.5 内联函数
- 1.6 条件编译
- 1.7 字节对齐详解
- 1.8 Const——今天必须把它搞懂
- 1.9 Static作用
- 1.10 volatile和mutable
- 1.11 volatile在嵌入式里的应用
- 1.12 原子操作
- 1.13 指针与引用的区别
- 1.14 右值引用
- 1.15 面向对象的编程思想
- 1.16 类
- 1.17 类的成员
- 1.18 友元函数
- 1.19 初始化列表
- 1.20 this指针
- 1.21 继承
- 1.22 多态
- 1.23 虚函数与重写
- 1.24 虚构造函数与虚析构函数
- 1.25 函数重载
- 1.26 操作符重载
- 1.27 迭代器与指针
- 1.28 模板
- 1.29 C++智能指针
- 1.30 四种cast转换
- 1.31 Lambda
- 1.32 function和bind
受众:本教程适合于C/C++已经入门的学生或人士,有一定的编程基础。
本教程适合于互联网、嵌入式软件求职的学生或人士。
故事背景
蒋 豆 芽:小名豆芽,芳龄十八,蜀中人氏。卑微小硕一枚,科研领域苟延残喘,研究的是如何炒好一盘豆芽。与大多数人一样,学习道路永无止境,间歇性踌躇满志,持续性混吃等死。会点编程,对了,是面对对象的那种。不知不觉研二到找工作的时候了,同时还在忙论文,豆芽都秃了,不过豆芽也没头发啊。
隔壁老李:大名老李,蒋豆芽的好朋友,技术高手,代码女神。给了蒋豆芽不少的人生指导意见。
导 师:蒋豆芽的老板,研究的课题是每天对豆芽嘘寒问暖。
故事引入
“中国土豆科技大学一研三学生因论文压力太大,跳楼轻生,家长指责导师故意延毕。”豆芽将这条新闻推送到了微信朋友圈,并配文:默哀。我也压力好大啊。
导 师:(试探)豆芽,你这实验尽力做就行了,你也别压力大,慢慢来嘛。
蒋 豆 芽:老师,我压力好大啊,也想把实验做出来,不然辜负了您的一片谆谆教导。
导 师:不用压力大,周末好好休息下,实验慢慢做就行了。
蒋 豆 芽:好的!(豆芽脸上笑嘻嘻,心里小感动,老师蛮好的。实验要继续加油!)
蒋 豆 芽:(吹着口哨)我得儿意的笑,我得儿意的笑。。。。。。
隔壁老李:哟,豆芽,什么事啊这么开心,不用搞实验了?
蒋 豆 芽:别介,老李。我回顾你上次跟我讲的宏,在C++中,尽量使用const去替代非参数宏命令,这样大大增强我们程序的健壮性。我今天在思考,const是什么样的机制呢,为什么可以做到不变?还有,const有哪些应用场景呢?
隔壁老李:(啧啧啧)哟,芽别三日,当刮目相待啊,开始学会思考知识点了,没错,找工作中,面试只是一个过程,这不仅仅是应试,学知识不是应付找工作,而是真正提升自己的技术能力,学会思考知识点背后的原理,掌握知识点的核心,才是找工作给予我们的最大的启示。(语重心长)凭这一点,豆芽,你成熟了,不枉为父谆谆教导。
蒋 豆 芽:老李,说话就说话,别占我便宜好吗?
隔壁老李:(嘿)哈哈。哦?不想听啊,不想听算了呗。
蒋 豆 芽:爸爸!
隔壁老李:哈哈,好啦,跟你开玩笑的。今天我们先来聊聊const,说const之前,我们要先说说常量,什么是常量呢?
常量是一种标识符,它的值在运行期间恒定不变。C语言和C++中都可以用#define来定义常量(称宏常量)。除此之外,C++语言还可以用const来定义常量(称const常量),就是我们今天要说到的主角了。那么豆芽我问问你,我们为什么需要常量?
蒋 豆 芽:这个我还真没想过,我只知道有这个东西,但为什么要用就不知道了。
隔壁老李:(语重心长)所以我们的学习不能仅仅停留在这个地步,不仅要知其然,还要知其所以然,凡事多问几个为什么,就会引申出很多的知识。
蒋 豆 芽:老李,我发现你越来越像我高中班主任了。
隔壁老李:(好奇)哦?是讲解细致入微?
蒋 豆 芽:不,是啰里啰嗦了。
隔壁老李:(敲脑袋)呸,死豆芽懂什么啊,那都是为你好!等你以后就知道班主任的好了。我不仅在教你编程知识,还在教你怎样正确编程。
蒋 豆 芽:(捂脑袋)好,老李,你继续吧。
隔壁老李:豆芽,你想想你平时编写程序时,直接填充数字会遇到什么问题?
蒋 豆 芽:(恍然大悟)哦,修改的时候特别麻烦,过几天再来看,就忘了这个数字什么意思了。
隔壁老李:所以啊,如果我们在程序中直接填充数字或字符串,
(1)程序的可读性(可理解性)变差。我们总会忘记这些数字或字符串代表什么意义。
(2)一旦数字很多,改动麻烦。
为了避免这些问题,我们就要用常量来替代。豆芽,之前我已经跟你说过了,在C语言中,可以使用宏替代常量,而C++尽量使用const常量替代宏常量,豆芽你来回顾一下。
1.8 Const——今天必须把它搞懂
蒋 豆 芽:简单!const 是 constant 的缩写,本意是不变的,不易改变的意思。在 C++ 中是用来修饰内置类型变量,自定义对象,成员函数,返回值,函数参数。
C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助。
在C++中为了安全性,我们就要少用甚至不要再用宏了,不带参数的宏命令我们可以用常量const来替代,比如const double PI = 3.1415
,可以起到同样的效果,而且还比宏安全,因为这条语句会在编译阶段进行语法检查。而宏常量在预编译阶段被替换,不会进行语法检查。
蒋 豆 芽:(疑惑)那老李,C语言里也有const,为什么C语言里的常量用的是宏而不是const?
隔壁老李:诶?这个问题问的非常得好啊,豆芽。看样子你有在认真听哈。
蒋 豆 芽:必须的!
隔壁老李:这是因为C语言里的const和C++里的const,两者作用机制是不一样的。这也是个比较重要的知识点,老李记得曾经被面试官这样问过,当时老李没有回答出来(羞涩)
蒋 豆 芽:嘿嘿。
隔壁老李:在C语言中,const修饰的变量依然被当做变量,那么其在内存中依然有存储它的空间。并且可以通过指针间接的改变该内存空间的值。如下面例子所示:
#include <stdio.h> int main(){ const int i = 10; int *p = (int *)(&i); *p = 20; printf("i=%d *p=%d \n", i, *p); return 0; }
结果如下:
i=20 *p=20
这里可以清楚地看到,i
的值被改变了。
蒋 豆 芽:啊?那这样就违背了我们定义const的初衷了。
隔壁老李:没错,所以这就是为什么在C语言中表示常量,使用的是宏常量而非const。宏是直接替换。
蒋 豆 芽:(好奇)那C++的const机制又是怎样的呢?
隔壁老李:在C++中,C++把const看做常量,编译器会使用常数直接替换掉上面例子中对i
的引用,最后的结果是i = 10,*p = 20
。
#include<iostream> using namespace std; int main(){ const int i = 10; int *p = (int *)(&i); *p = 20; cout << "i=%d" << i << "*p=%d" << *p; //这里编译器会直接将i替换为10 return 0; }
这里需要说明的是,其实变量i
的内存空间里的数值依然已经被改变了,为20。
所以千万不要轻易对 const 变量设法赋值,这会产生意想不到的行为。
蒋 豆 芽:明白了!所以C++中的const机制类似C语言中的宏,都是替换,不过C++的const是在编译阶段替换,C语言的宏是在预编译阶段替换。
隔壁老李:没错!豆芽,赶紧把小笔记记起来啊,这就是标准答案啊,面试官最喜欢问了。然后我们要把const讲透,const还有其他的用法,const可以修饰指针。
隔壁老李:在定义指针的时候我们可以用const来修饰
根据const出现的位置和出现的次数分为三种
指向常量的指针
常指针
指向常量的常指针
1.指向常量的指针
指针指向一个常量对象,目的是防止使用该指针来修改指向的值。
如:
const int *a; //a指针所指向的内存里的值不变,即(*a)不变,但a可以变 int const *a; //同const int *a;
给出实例:
int a = 10; int b = 20; const int *p = &a; //该声明的意思是p指向一个const int(这里为10),因此不能使用p来修改这个值, //换句话来说,*p的值为const,不能被修改。 *p = 20; //错误,编译报错 p = &b; //正确,const只能防止修改p指向的值,但不能防止修改p的值,也就是说,可以将一个新地址赋给p
2.常指针
将指针本身声明为常量,这样可以防止改变指针指向的位置。
如:
int *const a; //a指针所指向的内存地址不变,即a不变,但(*a)可以变
给出实例:
int a = 10; int b = 20; int *const p = &a; //意思是p只能指向a,p不能变,但允许p来修改a的值。 *p = 20; //正确,a的值可以被修改 p = &b; //错误,编译报错,p不能被修改
3.指向常量的常指针
一个常量指针指向一个常量对象。
如:
const int *const a; //都不变,即(*a)不变,a也不变
隔壁老李:const可以修饰参数传递。
对于 const 修饰函数参数可以分为三种情况。
A:值传递的 const 修饰传递,一般这种情况不需要 const 修饰,因为函数会自动产生临时变量复制实参值,实参反正不会变。但是我们也可以加const,这是一种良好的风格。
#include<iostream> using namespace std; void douya(const int a){ cout<<a; // ++a; 是错误的,a 不能被改变 } int main(void) { douya(8); system("pause"); return 0; }
B:当 const 参数为指针时,可以防止指针被意外篡改。
#include<iostream> using namespace std; void douya(int *const a){
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
<p> - 本专刊适合于C/C++已经入门的学生或人士,有一定的编程基础。 - 本专刊适合于互联网C++软件开发、嵌入式软件求职的学生或人士。 - 本专刊囊括了C语言、C++、操作系统、计算机网络、嵌入式、算法与数据结构等一系列知识点的讲解,并且最后总结出了高频面试考点(附有答案)共近400道,知识点讲解全面。不仅如此,教程还讲解了简历制作、笔试面试准备、面试技巧等内容。 </p> <p> <br /> </p>