嵌入式面试题整理(一)

自己整理了一些来自各个公司嵌入式行业的面试的题目。答案在后面(是自己写的答案,不敢保证100%正确,哈哈,能力有限)。题目都是近两年的公司面试题

 

  1. 关键字volatile有什么含义?并列举一个例子。
  2. 嵌入式系统总是要用户变量或寄存器进行位操作。给定一个整变量a,写两段代码,第一个设置a的bit 3,第二个清零a的bit3。在以上两个操作中,要保持其它位不变。
  3. 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址位0x67a9整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。
  4. 中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。 具代表事实是,产生一个新的关键字__interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。

__interrupt double compute _area(double radius)

{

double area = PI*radius *radius;

printf(” Area = %f”, area);

return area;

}

 

  1. 请问运行test函数会有什么结果?为什么?

(1)void getmemory( char *p )

{

P=(char*)malloc( 100 );

}

void test( void )

{

Char *str = null;

getmemory(str);

strcpy( str, “hello world” );

Printf( str );

}

(2)char *getmemory( void )

{

char p[] = “hello world”;

return p;

}

void test( void)

{

char *str = null;

str = getmemory();

printf( str );

}

 

6、用一句语句实现x是否是2的若干次幂的判断?

 

 

解答:

  1.  

Volatile关键字修饰变量,表示该变量是一个会意想不到改变的量(在某个特定的时刻就会改变),所以该变量是不能被编译器优化的(有时编译器为了操作方便,会把变量保存在一个寄存器中,使用的时候会直接从寄存器去取该变量的值),要去读取数据的时候要从保存变量的内存单元去取。避免读到的数据是有误的。

 

例子:在使用多线程编程时,同时访问同一个变量就可能造成数据不符的情况

 

小知识:C语言的原子性:在执行程序的过程中,如果一条语句不能被拆分,则该语句具有原子性。但在C语言中大部分语句是不具备原子性的。比如接下来的一条语句:i++; 刚刚接触的可能会想,不就是i自加1吗,这中间还会有其他的操作。答案是,会的,在汇编的时候该语句,包含了三个动作:1.读取i变量到寄存器,2.寄存器的值加1,3.把结果保存到i变量所对应的内存中。所以当多段代码同时要使用i变量的时候就会造成数据的错误读写。

 

2.

在做这道前要知道以下的知识点

1&0=0; 1&1=1; 0&0=0;

1|0=1; 1|1=1; 0|0=0;

1^0=1 1^1=0; 0^0=1;

 

了解这些这道题就比较简单了;

将a的第三位置1,其他位不变 将a的第三位清0,其他位不变

a=a|(0x1<<2); a=a&(~(0x1<<2))

 

总结:(假设m=4)

一个整数n,把它的第m个二进制位变成0,其他的二进制位不允许改变

                    n = n&11111111 11111111 11111111 11110111

                    n = n&(~(1<<(m-1)))

一个整数n,把它的第m个二进制位变成1,其他的二进制位不允许改变

                    n = n|00000000 00000000 00000000 00001000

                    n = n|(1<<(m-1))

一个整数n,把它的第m个二进制位反转(原本1--》0原本0--》1),其他的二进制位不允许改变

                    n = n^00000000 00000000 00000000 00001000

                    n = n^(1<<(m-1)

 

3.

   置一绝对地址位0x67a9整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。

 

方法一:

int *p;

p = (int *)0x67a9;

*p =(int) 0xaa55;

通过该方式可以比较明确的完成目标。

方法二:

一些大神也会这样写:

*(int * const)(0x67a9) = 0xaa55;

 

其实意思一样的。

 

注:在你用unix来测试该端代码的时候会发生当段错误,可能在开发板上才能用(来没有开始接触开发板)。

 

4.

还没有接触到底层开发。。。........

 

5.

(1)void getmemory( char *p )

{

P=(char*)malloc( 100 );

}

void test( void )

{

char *str = null;

getmemory(str);

strcpy( str, “hello world” );

Printf( str );

}

 

 

首先要明白的一点是,char *p 这是str的形参,而不是保存的str指针的地址,所以p和str是两个,p的一切行为和str没有任何关系。

所以在主函数执行完getmemory(str);后str还是一个指向NULL的一个指针。没有被分配空间。所以执行strcpy( str, “hello world” );会发生错误

 

(2)char *getmemory( void )

{

char p[] = “hello world”;

return p;

}

void test( void)

{

char *str = null;

str = getmemory();

printf( str );

}

这个问题就比较明显了,p是一个数组,是存放在是一个局部变量,存储在栈空间中,当getmemory()函数调用完后p的内存空间会被释放掉,str得到的将会是一个野指针。自然不能打印想要的字符串了。

 

6.

用一句语句实现x是否是2的若干次幂的判断?

首先要了解的是如果一个数是2的若干次幂,那么按照位来看,就是只有满足有且只有一位是1,其他全0;所以只要通过以下语句就可以实现了。

(x&(x-1))?(false):(ture)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值