信盈达—您身边的嵌入式&人工智能专家
全国免费咨询热线:400-8788-909

嵌入式经典面试题30道

时间:2018-08-16 00:00:00 来源:信盈达 作者:信盈达

    学习嵌入式之后紧接着就是面试了,信盈达小编整理了三十道经典面试题可供各位参考:


1int a[10]={1,2,3,4,5,6,7,8,9,0};

   int *p=&a[1];

   p[6]等于8


2、整数数组清零:bzero(),memset()


3sizeof();测试变量所占地址的字节数


4main()

 {

  char *str[]={"ab","cd","ef","gh","ij","kl"};

  char *t;

  t=(str+4)[-1];

  printf("%s",t);

 }

则显示"gh"


5、小端:低位字节数据存储在低地址

 大端:高位字节数据存储在低地址

 例如:int a=0x12345678;(a首地址为0x2000)

 0x2000  0x2001  0x2002  0x2003

  0x12    0x34    0x56    0x78      大端格式


6、异步IO和同步IO区别

 如果是同步IO,当一个IO操作执行时,应用程序必须等待,直到此IO执行完,相反,异步IO操作在后台运行,

 IO操作和应用程序可以同时运行,提高系统性能,提高IO流量; 在同步文件IO中,线程启动一个IO操作然后就立即进入等待状态,直到IO操作完成后才醒来继续执行,而异步文件IO中,

 线程发送一个IO请求到内核,然后继续处理其他事情,内核完成IO请求后,将会通知线程IO操作完成了。


7、用变量a定义

 一个整型数   int a;

 一个指向整型数的指针  int *a;

 一个指向指针的指针,它指向的指针式指向一个整型数  int **a;

 一个有10个整型数的数组   int a[10];

 一个有10指针的数组,该指针是指向一个整型数  int *a[10];

 一个指向有10个整型数数组的指针   int (*a)[10];

 一个指向函数的指针,该函数有一个整型数参数并返回一个整型数   int (*a)(int);

 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型数参数并返回一个整型  int (*a[10])(int);


8int foo(void)

{

 int i;

 char c=0x80;

 i=c;

 if(i>0)

  return 1;

 return 2;

}

返回值为2;因为i=c=-128;如果c=0x7f,i=c=127

9a=b*2;a=b/4;a=b%8;a=b/8*8+b%4;a=b*15;效率最高的算法

 a=b*2 -> a=b<<1;

 a=b/4 -> a=b>>2;

 a=b%8 -> a=b&7;

 a=b/8*8+b%4 -> a=((b>>3)<<3)+(b&3)

 a=b*15 -> a=(b<<4)-b


10c关键字

 

 c的关键字共32

 *数据类型关键字(12

 char,short,int,long,float,double,unsigned,signed,union,enum,void,struct

 *控制语句关键字(12

 if,else,switch,case,default,for,do,while,break,continue,goto,return

 *存储类关键字(5

 auto,extern,register,static,const

 *其他关键字(3

 sizeof,typedef,volatile


11int main(void)

 {

  unsigned int a = 6;

  int b = -20;

  char c;

  (a+b>6)?(c=1):(c=0);

 }c=1,但a+b=-14;如果aint类型则c=0

 原来有符号数和无符号数进行比较运算时(==<,>,<=,>=,有符号数隐式转换成了无符号数(即底层的补码不变,但是此数从有符号数变成了无符号数),

 比如上面 (a+b)>6这个比较运算,a+b=-14-14的补码为1111111111110010。此数进行比较运算时,

 被当成了无符号数,它远远大于6,所以得到上述结果。


12、给定一个整型变量a,写两段代码,第一个设置abit3,第二个清除abit,在以上两个操作中,

 要保持其它位不变。

 

#define BIT3 (0x1<<3)

  static int a;

  void set_bit3(void)

  {

   a |= BIT3;

  }

  void clear_bit3(void)

  {

   a &= ~BIT3;

  }


13、要求设置一绝对地址为0x67a9的整型变量的值为0xaa66

 int *ptr;

    ptr = (int *)0x67a9;

   *ptr = 0xaa66;(建议用这种)

  

    一个较晦涩的方法是:

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


14、中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。

 具代表性的是,产生了一个新的关键字__interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。

 __interrupt void compute_area (void)

 {

   double area = PI * radius * radius;

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

   return area;

 }

 ISR不可能有参数和返回值的!

 ISR尽量不要使用浮点数处理程序,浮点数的处理程序一般来说是不可重入的,而且是消耗大量CPU时间的!!

 printf函数一般也是不可重入的,UART属于低速设备,printf函数同样面临大量消耗CPU时间的问题!


15、评价下面的代码片断:

  

  unsigned int zero = 0;

  unsigned int compzero = 0xFFFF;

  /*1's complement of zero */

  对于一个int型不是16位的处理器为说,上面的代码是不正确的。应编写如下:

  unsigned int compzero = ~0;


16main()

 {

  char *ptr;

   if ((ptr = (char *)malloc(0)) == NULL)

   puts("Got a null pointer");

   else

   puts("Got a valid pointer");

 }

 该代码的输出是Got a valid pointer”。还可以*ptr='a';不出现段错误


17Typedef C语言中频繁用以声明一个已经存在的数据类型的同义字。也可以用预处理器做类似的事。

    例如,思考一下下面的例子:

  #define dPS struct s *

  typedef struct s * tPS;

  

  以上两种情况的意图都是要定义dPS tPS 作为一个指向结构s指针。哪种方法更好呢?(如果有的话)为什么?

  这是一个非常微妙的问题,任何人答对这个问题(正当的原因)是应当被恭喜的。答案是:typedef更好。思考下面的例子:

  dPS p1,p2;

  tPS p3,p4;

  

  第一个扩展为

  struct s * p1, p2;

  

  上面的代码定义p1为一个指向结构的指,p2为一个实际的结构,这也许不是你想要的。第二个例子正确地定义了p3 p4 两个指针。


18int a = 5, b = 7, c;

  c = a+++b;

 c=12


19int main()

 {

  int j=2;

  int i=1;

  if(i = 1) j=3;

  if(i = 2) j=5;

  printf("%d",j);

 }

 输出为5;如果再加上if(i=3)j=6;则输出6


20、宏定义是在预编译阶段被处理的。


21NorflashNandflash的区别

 (1)NAND闪存的容量比较大

 (2)、由于NandFlash没有挂接在地址总线上,所以如果想用NandFlash作为系统的启动盘,就需要CPU具备特殊的功能,

 s3c2410在被选择为NandFlash启动方式时会在上电时自动读取NandFlash4k数据到地址0SRAM中。

 (3)NAND Flash一般地址线和数据线共用,对读写速度有一定影响。NOR Flash闪存数据线和地址线分开,

    所以相对而言读写速度快一些。


22、反码:对原码除符号位外的其余各位逐位取反就是反码

 补码:负数的补码就是对反码加1

 正数的原码、反码、补码都一样


23pthread_t tid;

 pthread_create(&tid,NULL,pthread_func,NULL);//创建线程

 pthread_join(tid,NULL);//等待子线程结束,并回收资源

 pthread_detach(tid);//与当前进程分离

 pthread_exit(NULL);//退出调用线程

 pthread_cancel(tid);//取消线程

 pthread_mutex mutex=PTHREAD_MUTEX_INITIALIZER;

 pthread_mutex_init(&mutex,NULL);//初始化一个互斥锁

 pthread_mutex_lock(&mutex);//对互斥锁上锁

 pthread_mutex_unlock(&mutex);//对互斥锁解锁

 sem_t sem;

 sem_init(&sem,0,1);//创建信号量并初始化它的值

 sem_wait(&sem);//信号量的值减1

 sem_post(&sem);//信号量的值加1


24、内存管理MMU的作用

  *内存分配和回收

  *内存保护

  *内存扩充

  *地址映射


25ROM是只读存储器,掉电不丢失

 RAM是读写存储器,掉电丢失


26SRAMCPU的缓存就是SRAM,静态的随机存取存储器,加电情况下,不需要刷新,数据不会丢失

 DRAM,动态随机存取存储器最为常见的系统内存,需要不断刷新,才能保存数据

 SDRAM:同步动态随机存储器,即数据的读取需要时钟来同步。


27signed char 的取值范围-128~127.


28、编译和链接有什么不同?(如外部符号的处理)

 编译生成的是目标文件(object  *.o);

 编译过程中对于外部符号不做任何解释和处理。外部符号对应的就是“符号”

 

 链接生成的是可执行程序

 链接将会解释和处理外部符号。外部符号对应的是地址


29、已知strcpy函数的函数原型是:

 char *strcpy(char *strDest, const char *strSrc)。其中,strDest是目的字符串,strSrc是源字符串。

 不调用C++/C的字符串库函数,请编写函数strcpy

 char *strcpy(char *strDest, const char *strSrc)

 {

  int i=0;

  if(!(strDest && strSrc))

   return;

  while(strDest[i++] = *strSrc++);

  return strDest;

 }


30strcpy能把strSrc的内容复制到strDest,为什么还要char *类型的返回值?

 为了实现链式表达式

 int len = strlen(strcpy(strDest, strSrc));


信盈达2008年在深圳特区南山高新科技园成立。自成立至今近九年来专注为企业和个人提供高端方案设计、高端嵌入式/Android培训等服务。公司下设信盈达实训学院、信盈达研发中心、信盈达教学仪器三大业务板块。九年来公司坚持"技术领先、服务领先",以雄厚的实力和专业的品质成为国内唯一有实力从产品最底层研发到系统层开发的嵌入式实训、产品解决方案提供商。为中国IT行业提供最具价值的职业教育服务。专业嵌入式、物联网、人工智能Java、单片机等课程,想了解更多信息点击立马咨询