前言
(1)如果你在读大学,不管你本科毕业是读研还是就业,你都可以早点准备嵌入式面试题,本系列教程的面试题均基于C语言。
(2)像嵌入式学得好,且学历不错的本科生和研究生,都有机会进入华为、小米、大疆、智元等公司,薪资待遇也是不错的。
(3)早点接触面试题,心里有底,大家一起学起来吧。
(4)希望各位大佬多多指点经验,大家一起交流,共同进步!本人邮箱:3201935299@qq.com
第一题(考查对volatile关键字的认识——华为)
#include<setjmp.h>
static jmp_buf buf;
main()
{
volatile int b;
b =3;
if(setjmp(buf)!=0)
{
printf("%d ", b);
exit(0);
}
b=5;
longjmp(buf , 1);
}
请问,这段程序的输出是
(a) 3
(b) 5
© 0
(d) 以上均不是
第一题答案(b)5
详细解析
(1)volatile是C语言中的一个关键字,用于声明一个变量为"易变"(volatile)。当一个变量被声明为volatile时,编译器将对该变量的访问和操作做出特殊处理,以确保对该变量的读写操作不会被优化、重排序或省略,从而提供对变量的准确和可预测的访问。
(2)这是因为这个变量可能在一个寄存器,直接与外部设备相连,你写入之后,该寄存器也有可能被外部设备的写操作所改变;或者,该变量被一个中断程序,或被另一个进程改变了。
(3)volatile 不会被编译器优化影响,在longjump 后,它的值是后面假定的变量值,b最后的值是5,所以5被打印出来.(4)setjmp : 设置非局部跳转 /* setjmp.h*/
Lonjjmp: 执行一个非局部跳转 /* setjmp.h*/
反思
(1)请先允许见识狭窄的我先说一句,我用了两年C语言都没见过<setjmp.h>这个头文件,以至于我开始都以为这题考的不是C语言哈哈,直到我把题目代码在VS里编译后,才相信,还是学的东西太少了,一下子暴露了自己的知识上限(doge),其次题目代码少包含了一个头文件#include <stdio.h>。
我提出问题,头文件<setjmp.h>有什么作用?函数setjmp()、longjmp()是什么作用?该程序的逻辑功能是什么?
(2)头文件<setjmp.h>有什么作用?
头文件<setjmp.h>是C标准库中的一个头文件,它提供了用于非局部跳转的函数setjmp()和longjmp()的声明和定义。
setjmp()和longjmp()函数允许在程序的不同位置进行跳转,而不是按照正常的顺序执行代码。这种非局部跳转的能力对于处理异常、错误处理、状态回滚等情况非常有用。
具体来说,<setjmp.h>头文件中提供的函数有以下作用:
setjmp()函数:用于设置一个跳转点,并将当前程序状态保存到jmp_buf类型的变量中。它在设置跳转点时返回0,但当通过longjmp()函数跳转回来时,setjmp()函数会返回非零值,用于判断是否发生了跳转。
longjmp()函数:用于进行非局部跳转,返回到之前通过setjmp()函数设置的跳转点。它的第一个参数是之前保存的jmp_buf变量,第二个参数是用于标识跳转原因的值。
通过结合使用setjmp()和longjmp()函数,可以实现一种跳转回之前的程序状态的机制,从而实现异常处理、错误处理、状态回滚等操作。
需要注意的是,由于非局部跳转可能会导致代码流程的混乱和难以维护,应该谨慎使用setjmp()和longjmp()函数,并确保在使用时遵循相关的规范和最佳实践。
(3)函数setjmp()、longjmp()是什么作用?
函数
setjmp()
和longjmp()
是C标准库中提供的用于非局部跳转的函数。
setjmp()
函数:setjmp()
函数用于设置一个跳转点,并将当前程序状态保存到一个jmp_buf
类型的变量中。它的原型如下:int setjmp(jmp_buf env); ``` ``setjmp()`函数在设置跳转点时返回0,并将程序状态保存在`env`变量中。这样,通过调用`longjmp()`函数可以跳回到`setjmp()`函数所在的位置,并恢复保存的程序状态。
longjmp()
函数:longjmp()
函数用于进行非局部跳转,返回到之前通过setjmp()
函数设置的跳转点。它的原型如下:void longjmp(jmp_buf env, int value); ``` ``longjmp()`函数接受一个`jmp_buf`类型的变量`env`作为参数,以及一个用于标识跳转原因的整数值`value`。调用`longjmp()`函数会使程序跳转回`setjmp()`所在的位置,并且`setjmp()`函数的返回值被设置为`value`。
这种非局部跳转的机制可以用于异常处理、错误处理以及特定的控制流程需求。例如,当发生某个异常情况时,可以使用
setjmp()
函数设置一个跳转点,然后在需要的地方调用longjmp()
函数跳转回来,从而实现异常处理。这种机制在一些C语言框架和库中被广泛使用,例如错误处理和资源回收的实现。需要注意的是,非局部跳转是一种强大但也容易导致代码复杂性和难以维护性的特性,因此在使用时应慎重考虑,并确保遵循相关的规范和最佳实践。
(4)程序逻辑分析
这段代码展示了使用C标准库中的setjmp()和longjmp()函数来实现非局部跳转的示例。
首先,jmp_buf是一个用于存储跳转位置信息的数据类型。在代码中,我们声明了一个名为buf的jmp_buf类型变量。
接下来,main()函数中声明了一个volatile修饰符的整型变量b,并将其初始化为3。
然后,通过使用setjmp(buf)函数,在此处设置了一个跳转点。setjmp()函数会将当前程序状态保存到buf中,并返回0作为返回值。这是第一次调用setjmp()函数,因此返回值为0。
之后,代码中的条件判断语句if(setjmp(buf)!=0)检测到setjmp()函数的返回值不为0,表示发生了跳转。在这种情况下,程序会执行跳转后的代码块。
在跳转后的代码块中,通过调用printf()函数输出变量b的值,并调用exit(0)函数来终止程序运行。
然而,在跳转之前,我们将变量b的值修改为5。
最后,通过调用longjmp(buf, 1)函数,程序将跳转回之前设置的跳转点,并且setjmp()函数的返回值被设置为1。这会导致条件判断语句为真,从而执行跳转后的代码块。
综上所述,这段代码的输出结果将是"5"。