admin 管理员组文章数量: 1184232
2024年3月13日发(作者:怎么把乐谱转换成代码)
2021年光电信息科学与工程专业毕业生
《C语言单片机》求职考试题及面试题试卷
(附:答案)
院
(
系
)
班
级
姓
名
学
号
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
装
…
…
…
…
…
…
…
…
…
…
订
…
…
…
…
…
…
…
…
…
线
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
题 号 一 二 三
得 分
四
总 分
一、关键字Volatile。
关键字volatile有什么含意并给出三个不同的例子。
一个定义为volatile的变量是说这变量可能会被意想不到地改
变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优
化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而
不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1). 并行设备的硬件寄存器;如:状态寄存器。
2). 一个中断服务子程序中会访问到的非自动变量:
Non-automatic variables;
3). 多线程应用中被几个任务共享的变量:
回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序
员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬
件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂
1 / 8
得volatile内容将会带来灾难。假设被面试者正确地回答了这是问
题(嗯,怀疑这否会是这样),将稍微深究一下,看一下这家伙是不
是直正懂得volatile完全的重要性。
1). 一个参数既可以是const还可以是volatile吗?解释为什
么。
2). 一个指针可以是volatile 吗?解释为什么。
3). 下面的函数有什么错误:
int square(volatile int *ptr) ;{ return *ptr * *ptr; } ;
下面是答案:
1). 是的。一个例子是只读的状态寄存器。它是volatile因为
它可能被意想不到地改变。它是const因为程序不应该试图去修改
它。
2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序
修该一个指向一个buffer的指针时。
3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr
指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器
将产生类似下面的代码:
int square(volatile int *ptr) ;{ int a,b; a = *ptr; b =
*ptr; return a * b; } ;
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同
的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr) ;{ int a; a = *ptr; return
2 / 8
a * a; };
二、位操作(Bit manipulation)。
嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整
型变量a,写两段代码,第一个设置a的bit 3,第二个清除a 的bit
3。在以上两个操作中,要保持其它位不变。
对这个问题有三种基本的反应:
1). 不知道如何下手。该被面者从没做过任何嵌入式系统的工
作。
2). 用bit fields。Bit fields是被扔到C语言死角的东西,
它保证你的代码在不同编译器之间是不可移植的,同时也保证了的你
的代码是不可重用的。我最近不幸看到Infineon为其较复杂的通信
芯片写的驱动程序,它用到了bit fields因此完全对我无用,因为
我的编译器用其它的方式来实现bit fields的。从道德讲:永远不
要让一个非嵌入式的家伙粘实际硬件的边。
3). 用 #defines 和 bit masks 操作。这是一个有极高可移植
性的方法,是应该被用到的方法。最佳的解决方案如下:
#define BIT3 (0x1<<3);static int a; void set_bit3(void);
{ a |= BIT3; } ;void clear_bit3(void);{ a &= ~BIT3; };
一些人喜欢为设置和清除值而定义一个掩码同时定义一些说明
常数,这也是可以接受的。我希望看到几个要点:说明常数、|=和&=~
操作。
三、访问固定的内存位置(Accessing fixed memory locations)。
3 / 8
嵌入式系统经常具有要求程序员去访问某特定的内存位置的特
点。在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为
0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。
这一问题测试你是否知道为了访问一绝对地址把一个整型数强
制转换(typecast)为一指针是合法的。这一问题的实现方式随着个
人风格不同而不同。典型的类似代码如下:
int *ptr; ptr = (int *)0x67a9; *ptr = 0xaa55;一个较晦涩
的方法是:*(int * const)(0x67a9) = 0xaa55;
即使你的品味更接近第二种方案,但我建议你在面试时使用第一
种方案。
四、中断(Interrupts)。
1、中断是嵌入式系统中重要的组成部分,这导致了很多编译开
发商提供一种扩展—让标准C支持中断。具代表事实是,产生了一个
新的关键字__interrupt。下面的代码就使用了__interrupt关键字
去定义了一个中断服务子程序(ISR),请评论一下这段代码的。
__interrupt double compute_area (double radius);{ double
area = PI * radius * radius; printf(" Area = %f", area); return
area; };
这个函数有太多的错误了,以至让人不知从何说起了:
1). ISR 不能返回一个值。如果你不懂这个,那么你不会被雇用
的。
2). ISR 不能传递参数。如果你没有看到这一点,你被雇用的机
4 / 8
版权声明:本文标题:2021年光电信息科学与工程专业毕业生《C语言单片机》求职考试题及面试题 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1710277417a565749.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论