面试题

1、int a[10]={1,2,3,4,5,6,7,8,9,0};
int *p=&a[1];
则p[6]等于8
2、整数数组清零:bzero(),memset()。
3、sizeof();测试变量所占地址的字节数
4、 main()
{
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);
8、int 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。
9、a=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
10、c关键字

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
11、int main(void)
{
unsigned int a = 6;
int b = -20;
char c;
(a+b>6)?(c=1):(c=0);
}则c=1,但a+b=-14;如果a为int类型则c=0。
原来有符号数和无符号数进行比较运算时(==,<,>,<=,>=),有符号数隐式转换成了无符号数(即底层的补码不变,但是此数从有符号数变成了无符号数),
比如上面 (a+b)>6这个比较运算,a+b=-14,-14的补码为1111111111110010。此数进行比较运算时,
被当成了无符号数,它远远大于6,所以得到上述结果。
12、给定一个整型变量a,写两段代码,第一个设置a的bit3,第二个清除a的bit,在以上两个操作中,
要保持其它位不变。
#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;
16、main()
{
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’;不出现段错误
17、Typedef 在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 两个指针。
18、int a = 5, b = 7, c;
  c = a+++b;
则c=12。
19、int 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、宏定义是在预编译阶段被处理的。
21、Norflash与Nandflash的区别
(1)、NAND闪存的容量比较大
(2)、由于NandFlash没有挂接在地址总线上,所以如果想用NandFlash作为系统的启动盘,就需要CPU具备特殊的功能,
如s3c2410在被选择为NandFlash启动方式时会在上电时自动读取NandFlash的4k数据到地址0的SRAM中。
(3)、NAND Flash一般地址线和数据线共用,对读写速度有一定影响。NOR Flash闪存数据线和地址线分开,
所以相对而言读写速度快一些。
22、反码:对原码除符号位外的其余各位逐位取反就是反码
补码:负数的补码就是对反码加1
正数的原码、反码、补码都一样
23、pthread_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的作用
*内存分配和回收
*内存保护
*内存扩充
*地址映射
25、ROM是只读存储器,掉电不丢失
RAM是读写存储器,掉电丢失
26、SRAM:CPU的缓存就是SRAM,静态的随机存取存储器,加电情况下,不需要刷新,数据不会丢失
DRAM,动态随机存取存储器最为常见的系统内存,需要不断刷新,才能保存数据
SDRAM:同步动态随机存储器,即数据的读取需要时钟来同步。
27、signed 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;
}
30、strcpy能把strSrc的内容复制到strDest,为什么还要char *类型的返回值?
为了实现链式表达式
int len = strlen(strcpy(strDest, strSrc));
31、写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个
#define MIN(a, b) (a) <= (b) ? (a) : (b)
32、关键字static的作用是什么
static用来修饰一个局部的变量的时候,
生命域是全局的
作用域是局部的

static用来修饰一个模块内的(某一个C的源程序文件)全局变量的时候
生命域不变
作用域减小,只在本模块内有效

static用来修饰一个函数的时候
作用域减小,只在本模块内有效

33、说明下面的声明的含义:
  A.
  const int a; // a是一个常数
  int const a; // a是一个常数
  B.
  const int *a; // a是一个指向整型常数的指针
  int * const a; // a是一个指向整型变量的常指针
  int const * a const; // a是一个指向整型常数的常指针
C.
char *strcpy(char *strDest, const char *strSrc);
// 参数在函数内部不会被修改
const int strcmp(char *source, char *dest);
// 函数的返回值不能被修改
const int a = strcmp(xx, yy);
if(strcmp(xx,yy) != 0)
34、说明关键字volatile有什么含意,并给出例子。
volatile表示被修饰的符号是易变的。告诉编译器不要随便优化我的代码!!
*一个硬件寄存器
*中断中用到的变量
*线程之间共享变量
volatile int a = 10;
while((a & 0x01) == 0);
#define P_UART_STATUS ((const volatile unsigned int *)0x88000000);
// volatile表示硬件会修改这个寄存器的内容
// const表示该寄存器只读,写无意义
35、printf可以接受多个参数,为什么,请写出printf的原型。
int printf(const char *fmt, …);
36、什么是堆栈,简述为什么需要堆栈?
堆栈是计算机中最常用的一种数据结构,保存数据的一块连续内存;比如函数的调用是用堆栈实现的。
37、请列举常用的串行通信方式(两种以上),并简述串行通信和并行通信不同之处、优缺点。
异步通信和同步通信;并行速度快,串行口线间干扰小
38、列举一下你熟悉7层OSI协议中的几层。说说你最熟悉的一层协议的功能。
应用层,表示层,会话层,传输层,网络层,数据链路层,物理层。
39、路由协议:网关-网关协议,外部网关协议,内部网关协议(RIP-1、RIP-IGRP、EIGRP、IS-IS和OSPF)
40、位转换
位 8 7 6 5 4 3 2 1
数 v8 v7 v6 v5 v4 v3 v2 v1

转换后:
位 8 7 6 5 4 3 2 1
数 v1 v2 v3 v4 v5 v6 v7 v8
unsigned char bit_reverse(unsigned char c)
{
  unsigned char buf = 0;
  int bit = 8;
  while(bit)
  {
  bit–;
  buf |= ((c & 1) << bit);
  c >>=1;
  }
  return buf;
}
41、字符串倒序
1)、inverted_order(char *p)
{
char *s1,*s2,tem;
s1=p;
s2=s1+strlen(p)-1;
while(s1

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值