啊C啊C我爱你-2
C++软件与嵌入式软件面经解析大全(蒋豆芽的秋招打怪之旅)
本章讲解点
1.1 熟悉的陌生人——main函数
1.2 If else——易错细节分辨
1.3 Switch、break——相爱相杀的故事
1.4 For、while、do-while——傻傻分不清楚
1.5 枚举
1.6 结构体与共用体
1.7 函数——原来你是这样的函数
1.8 全局变量与静态变量详解
1.9 数据类型详解
1.10 类型转换
1.11 谁先谁后——把人搞疯的优先级
1.12 震惊——位运算还可以这样用
1.13 面试技巧讲解
1.14 数组指针与指针数组
1.15 指针与字符串
1.16 指针与函数
1.17 指针与结构体
1.18 内存布局
1.19 野指针与内存泄露
1.20 野指针与内存申请
1.21 内存碎片
受众:本教程适合于C/C++已经入门的学生或人士,有一定的编程基础。
本教程适合于互联网、嵌入式软件求职的学生或人士。
故事背景
蒋 豆 芽:小名豆芽,芳龄十八,蜀中人氏。卑微小硕一枚,科研领域苟延残喘,研究的是如何炒好一盘豆芽。与大多数人一样,学习道路永无止境,间歇性踌躇满志,持续性混吃等死。会点编程,对了,是面对对象的那种。不知不觉研二到找工作的时候了,同时还在忙论文,豆芽都秃了,不过豆芽也没头发啊。
隔壁老李:大名老李,蒋豆芽的好朋友,技术高手,代码女神。给了蒋豆芽不少的人生指导意见。
导 师:蒋豆芽的老板,研究的课题是每天对豆芽嘘寒问暖。
故事引入
蒋 豆 芽:今天周五了,嘿嘿,周末要到了,趁着周末好好复习下,迎接下周的笔试面试,刚把跌!!!(豆芽脸上笑嘻嘻(#^.^#))
蒋 豆 芽:老李,马上周末了,上次你给我讲的C语言细节知识,还有吗?再给我讲讲吧。大佬,哦呐桑(姐姐),拜托。
隔壁老李:(一脸嫌弃)本来是周末陪男朋友的,看你这么诚恳,就给你讲讲吧,我让男朋友晚点来。
蒋 豆 芽:(小声嘀咕)原来如此,呵,女人,重色轻友。
隔壁老李:(目光凌厉)你说啥?
蒋 豆 芽:(一脸嬉笑)没啥啊,我说你才貌与智慧并重,狭义与柔情化身。豆芽滞销,快救救豆芽吧,求求了。
隔壁老李:(一脸无奈)行啦行啦,豆芽,我们就开始吧。
蒋 豆 芽:好好好!
隔壁老李:上次我们一直探讨了一些C语言的细节知识,如果忘了,豆芽你再回去复习复习,这次我们接着讲几个内容。
1.7 函数——原来你是这样的函数
隔壁老李:上次我们将了熟悉的陌生人——main函数。这次我们讲讲函数的细节知识。
隔壁老李:讲之前,关于函数的基础知识,我们先提一下。函数是一个独立的代码块,实现某一功能,可以传入参数,返回结果。函数定义的一般格式是:
返回值类型 函数名([形参]){ 函数体 }
函数可以没有返回值。
行,豆芽,C语言你是有基础的,所以这里点到为止。
隔壁老李:豆芽,函数的入门知识你应该是没问题的,但是有一个东西不知道你有没有注意过,那就是实参与形参。
蒋 豆 芽:这个简单,比如一个函数声明为:double cylinder(double r, double h)
,这个时候r
和h
就是形参,而当我们调用该函数时,如volume = cylinder(radius, height)
,这个时候传入的参数radius
和height
就是实参。函数调用时,实参radius
和height
的值将被依次传给形参r
和h
。
蒋 豆 芽:函数的形参必须是变量,用于接受实参传递过来的值;而实参可以是常量、变量或表达式,其作用是把常量、变量或表达式的值传递给形参。如果实参是变量,它与所对应的形参是两个不同的变量。
比如:
//函数声明,函数的形参必须是变量 double cylinder(double r, double h); //函数调用,实参可以是常量、变量或表达式 volume = cylinder(radius, height); volume = cylinder(3, 4); volume = cylinder(radius+3, height*4);
实参是主调函数的,形参是自定义函数的,这两者可以同名,也可以不同名。实参和形参一一对应,数量应相同,建议类型也保持一致。
隔壁老李:豆芽,你的基础还不错嘛。
蒋 豆 芽:嘻嘻。勉强勉强。
隔壁老李:那我问下你,以你的例子为例,当r
,h
的值改变时,radius
和height
的值会改变吗?
蒋 豆 芽:(不太确定)不会吧。
隔壁老李:你的样子看起来不太确定哈。正确答案是不会的。我们在学习语言时,都会想当然先入为主,平时习以为常,并没有去关注细节,但是有人问起细节时,就感觉不确定了,所以我们要弄懂细节,使得我们更有自信地去用好一门语言,笔试面试更不在话下。
隔壁老李:豆芽你来说说radius
和height
的值为什么不会改变。
蒋 豆 芽:我想起来了,因为在函数传参的过程中,函数会为形参申请新的内存空间,并将实参的值复制给形参。如下:
因为实参和形参是不同的变量,各自占有自己的内存,当然形参的值发生改变但不会影响实参了啊。
隔壁老李:没错,我们来验证一下。下面是我给的参考例子。
#include <stdio.h> using namespace std; double cylinder(double r, double h) { double *address_r = &r;//展示地址 double *address_h = &h; r = 1.1; h = 2.2;//改变形参值 return 1.0; } int main() { double radius = 3.2; double height = 4.2; double *address_radius = &radius;//展示地址 double *address_height = &height; double volume = cylinder(radius, height); return 0; }
我们通过断点调试,先到double volume = cylinder(radius, height);
处,我们先记录一下radius
和height
的值和地址,
然后进入cylinder
函数。
记录一下r
和h
的值和地址:
我们可以清楚看到,C语言将实参的值复制给了形参,专门为形参变量开辟了新的内存空间,实参与形参的内存地址是不一样的。然后我们运行完cylinder
函数时,我们的形参值发生了改变,最后我们退出函数,发现我们的实参值是没有改变的。
原因很简单,形参和实参拥有不同的内存空间。
隔壁老李:(眼光一闪)豆芽,我问你个问题,那如果我们想让实参随着形参的值改变应该怎么办呢?
蒋 豆 芽:(丝毫不慌)那就使用指针变量。如double cylinder(double *r, double *h)
,当我们调用该函数时传入变量地址,volume = cylinder(&radius, &height)
。
隔壁老李:没错,那我们再来验证一下。
#include <stdio.h> using namespace std; double cylinder(double *r, double *h) { *r = 1.1; *h = 2.2;//改变形参值 return 1.0; } int main() { double radius = 3.2; double height = 4.2; double *address_radius = &radius;//展示地址 double *address_height = &height; double volume = cylinder(&radius, &height); return 0; }
依然按照我们之前的思路依次查看形参实参的地址和值。
可以非常清楚地看到,这时的形参和实参内存地址是一样的,那么改变形参的值,实参的值也会被改变。豆芽你说说这是为什么?
蒋 豆 芽:根据指针的特性,是因为函数调用时,将实参地址赋值给了形参变量,使得形参指针指向了实参的地址空间,所以实参和形参指向了同一个内存空间。如图:
可以很清楚地看到,函数为形参*r
申请新的内存空间,然后将实参radius
的地址赋值给了r
,所以r=0x0001
,这样r
就指向了radius
的内存空间,通过改变*r
的值,也就是改变了radius
的值,因为它们指向了同一个内存空间。
隔壁老李:豆芽,那你看看下面的代码,最后radius
和height
的值又是多少呢?
#include <stdio.h> using namespace std; double cylinder(double *r, double *h) { r = new double(0.1); h = new double(0.2); *r = 1.1; *h = 2.2;//改变形参值 return 1.0; } int main() { double radius = 3.2; double height = 4.2; double *address_radius = &radius;//展示地址 double *address_height = &height; double volume = cylinder(&radius, &height); return 0; }
蒋 豆 芽:这不是一样的吗?指针形参嘛,最后radius=1.1
,height=2.2
隔壁老李:你确定吗?我们看看最后的结果吧
蒋 豆 芽:(一脸疑惑)咦?没变?形参不是值改变了吗?这是怎么回事?
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
<p> - 本专刊适合于C/C++已经入门的学生或人士,有一定的编程基础。 - 本专刊适合于互联网C++软件开发、嵌入式软件求职的学生或人士。 - 本专刊囊括了C语言、C++、操作系统、计算机网络、嵌入式、算法与数据结构等一系列知识点的讲解,并且最后总结出了高频面试考点(附有答案)共近400道,知识点讲解全面。不仅如此,教程还讲解了简历制作、笔试面试准备、面试技巧等内容。 </p> <p> <br /> </p>