嵌入式软件笔试
/************************
Chapter1语法类
***********************/
1 .volatile作用?应用场合举3例
volatile修饰的变量表示这个变量可能会被意想不到的改变,对该变量的操作将不作优化,用到该变量时都从这个
变量的原始地址读取,而不是用保存在寄存器里的备份。
Volatile常用在:
1).硬件寄存器(如:状态寄存器)。
2).中断程序中会访问到的非自动变量(Non-automatic variables)。
3).多线程应用中几个任务共享的变量
-
一个参数既可以是 const还可以是 volatile吗?解释为什么。
是的。比如只读的状态寄存器。它是 volatile因为它可能被意想不到地改变。它是 const因为程序不应该试图去修
改它。
-
一个指针可以是 volatile吗?解释为什么。
是的。 比如一个中断服务子程序修该一个指向一个 buffer的指针时。
-
用变量 a给出下面的定义 a)一个整型数 b)一个指向整型数的指针 c)一个指向指针的指针,它指向的指针是指向一个整型数 d)一个有10个整型数的数组 e)一个有10个指针的数组,该指针是指向一个整型数的 f)一个指向有10个整型数数组的指针 g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数 h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数
int a;// An integer
int *a;// A pointer to an integer
int **a;// A pointer to a pointer to an integer
int a[10];// An array of 10 integers
int *(a[10]);// An array of 10 pointers to integers
int (*a)[10];// A pointer to an array of 10 integers
int (*a)(int); //A pointer to a function a that takes an integerargument and returns an integer
int (*a[10]) (int); // An array of 10 pointersto functions that take an in teger argument and return an integer
-
什么是存储机制里的大、小端模式?试举例说明
大端模式(big-edian):MSB存放在最低端的地址上。举例,双字节数0x1234以big-endian的方式存在起始地
址0x00002000中:
| data |<-- address
| 0x12 |<--0x00002000
| 0x34 |<--0x00002001
在 Big-Endian中,对于bit 序列中的序号编排方式如下(以双字节数0x8B8A为例): bit | 0 1 2 3 4 5 6 7 | 8 9 10 11 1213 14 15
MSB----------------------------------LSB
val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |
= 0x8 B 8A小端模式(little-endian):LSB存放在最低端的地址上。举例,双字节数0x1234以little-endian 的方式存在起始地
址0x00002000中:
| data |<-- address
| 0x34 |<--0x00002000
| 0x12 |<--0x00002001
在 Little-Endian 中,对于 bit 序列中的序号编排和 Big-Endian刚好相反,其方式如下(以双字节数0x8B8A为
例):
bit | 15 14 13 12 11 10 9 8 | 7 6 5 4 3 2 1 0
MSB-----------------------------------LSBval | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |
= 0x8 B 8A
-
写一段用来判断内存存储方式是大端还是小段的代码。联合体 union 的存放顺序是所有成员都从低地址开始存放,利用该特性就可以轻松地获得了CPU对内存采用Little-endian还是 Big-endian模式读写。代码如下:
int checkCPUendian()
{ union
{ unsigned int a; unsigned char b;
}c;
c.a = 1;
return (c.b = = 1);
}
/*return 1 : little-endian, return0:big-endian*/
-
定义一个返回值是指向函数的指针且有一个指向函数的指针作参数的函数。
通用形式如下:
typedef int (*P)( ); //定义一个函数指针 P 类型
P function( int (*p)() ); // 定义一个函数返回值 P 类型,且定义一个指向函数的指针 p 作参数
8.用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)#define SECONDS_PER_YEAR (60 * 60 * 24 * 365) UL // UL 怎么个用法?你暂不要加
9.写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。
两个作用:
局部变量被声明为 static 则这一函数调用结束后该变量值保持不变。
-
外部变量被声明为 static 表明它是一个本地全局变量。该变量只能在该文件内被访问,不能被其它文件访问。
11.关键字const有什么含意?声明一个变量为只读。
-
下面的声明都是什么意思?
1)const int a; 2)int const a; 3)const int*a; 4)int * const a; 5)int const * consta ;
1,2一样a为只读整形变量;3指向一个只读整形变量的指针;4指向整形的只读指针; 5 指向只读整形的只读指针。
-
C语言实现设置一绝对地址为0x1234的整型变量的值为0xaa55。int *p; p=(int *) 0x1234; // 把整型数0x1234强制转换(typecast)为一指针
*p=0xaa55;
-
找出下面一段 ISR的问题。
__interrupt double compute_area (double radius)
{ doublearea = PI * radius * radius; printf("\nArea = %f", area); returnarea;
}
ISR 不能传递参数。
ISR 不能有返回值。
-
ISR 应该短且有效率,在ISR 中做浮点运算不明智。15.下面的代码输出是什么?为什么?
void foo(void)
{ unsigned int a = 6; int b = -20;
(a+b > 6) ? puts("> 6") : puts("<=6");
}
输出 > 6,原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。-20成了
一个非常大的正数。 // 此题的输出确实是这样,但单纯输出 a+b 时结果又是-14很怪异 迷惑~~~~~~!
16.评价下面的代码片断: unsigned int zero = 0; unsigned int compzero = 0xFFFF;
如果碰巧 int 型是16位则上述代码没有问题,否则上面的代码不正确。应写成:unsigned int compzero = ~0;
17 .下面代码执行后a,b,c的值各是多少?int a = 5, b = 7, c;
c = a+++b; // c = (a++)+ba = 6, b = 7, c = 12. // 吾已试,结果确如此
18. Typedef和#define的区别
#define 在预编译的时候处理作机械的字符替换。Typedef在编译的时候处理,并不是作简单的字符替换。而是如同定义变量一样声明一个类型。然后用它去定义这种类型的变量。比如下面的例子:
#define dPS struct s *
dPS p1,p2; tPS p3,p4;
第一句扩展为 struct s * p1, p2;这条代码定义 p1为指向结构的指针,p2为一个实际的结构体。第二句定义p3 和 p4 为指向结构体 s的指针。
/************************
Chapter2系统类
***********************/
Linux 和 Uc/os是如何实现任务调度的?
Bootloader 移植过程要注意的事项,要做哪些工作
Emacs 用过没有?
/************************
Chapter3编程类
***********************/
1.在字符串中找出所有与给定字符相同字符的位置。
#include <stdio.h> chars[6]="hello";
void search(char given)
{ int i=0,j=0;while(s[i]!='\0'){
if(s[i]==given){
printf("location=%d\n",i);j++; } i++;
} if(j==0)
printf("No %c found\n",given);
}
int main(void)
{ search('o');return 0;
}
2.将一个字符串自身逆序.
#include <stdio.h>
#define LEN 12 int main(void)
{
int m,i; char temp; char s[LEN]="hellotiger"; m=(LEN-1)/2; printf("%s\n",s); for(i=0;i<m;i++){temp=s[i]; s[i]=s[LEN-2-i]; s[LEN-2-i]=temp;
}printf("%s\n",s); return 0;
}
/*------- E ------*/
3.链表的基本操作及链表自身逆序。
/*---- chain operate from Data Structure---*/
#include <malloc.h>
#include <stdio.h> #include <stdlib.h> typedef intDataType; typedef struct Node
{
DataTypedata; struct Node *next;
}SLNode; //---- initiate voidListInitiate(SLNode **head)
{ if( (*head=(SLNode*)malloc(sizeof(SLNode)))==NULL ) exit(1); else printf("OK\n");
(*head)->next=NULL;
}
//---- length cal intListLength(SLNode *head)
{
SLNode*p=head; int size=0; while(p->next!=NULL){
p=p->next; size++;
} return size;int ListInsert(SLNode *head,int i,DataType x)
{
SLNode *p,*q;int j; p=head; j=-1; while( (p->next!=NULL) && (j<(i-1)) ) {
p=p->next;j++; } if(j!=(i-1)) {
printf("Positionerror\n"); return 0; } if((q=(SLNode *)malloc(sizeof(SLNode)))==NULL)
exit(1); q->data=x;q->next=p->next; p->next=q; return 1;
}
//----delete a node intListDelete(SLNode *head,int i,DataType *x)
{
SLNode *p,*s;int j; p=head; j=-1; while((p->next!=NULL) &&(p->next->next!=NULL) && (j<i-1) ){
p=p->next; j++;
} if(j!=i-1){printf("Position error\n"); return 0; } s=p->next; *x=s->data;p->next=p->next->next; free(s); return 1;
}
//----- data get
int ListGet(SLNode *head,int i,DataType*x)
{ SLNode *p; intj; p=head; p=p->next; j++;
} if(j!=i) { printf("Positionerror\n"); return 0;
}*x=p->data; return 1;
} //----Destroy a chain voidDestroy(SLNode **head)
{ SLNode *p,*p1;p=*head; while(p!=NULL) { p1=p; p=p->next; free(p1);
}
*head=NULL;
}
//-----converse a chain void converse(SLNode *head)
{
SLNode *p,*q; p=head->next;head->next=NULL; while(p!=NULL) { q=p; p=p->next;q->next=head->next; head->next=q;
}
}
//---- composite operation intmain(void)
{ SLNode *head;
int i,x;
ListInitiate(&head);for(i=0;i<10;i++) { if(ListInsert(head,i,i)==0){
printf("Error\n"); return1;
}
if(ListDelete(head,0,&x)==0) //chain,position,data address
{printf("Error\n"); return 1;
} if(ListInsert(head,0,100)==0){ printf("Error\n"); return 1;
} converse(head);for(i=0;i<ListLength(head);i++) {
if(ListGet(head,i,&x)==0) //chain,position,data address
{printf("Error\n");
return 1; } elseprintf("%d ",x);
}printf("\n"); Destroy(&head); return 0;
}
/*------ E -------*/
4.写一个二分查找算法。
#include <stdio.h> #definesize 10 int g[size]={0,1,2,3,4,5,6,7,8,9}; int search(int x)
{ int low=0; inthigh=size-1; int mid; while(low<=high) {
mid=(low+high)/2; if(g[mid]==x)return mid;
elseif(g[mid]<x) low=mid+1;
else if(g[mid]>x)
high=mid-1;
} return -1;
} //---int main(void)
{printf("%d\n",search(7)); return 0;
5.计算一个字节里(byte)里面有多少bit被置1.
#include <stdio.h> intcal_bit(char a)
{ int i,j=0;for(i=0;i<8;i++) {
if((a&0x01)==0x01)
j++;a=a>>1;
} return j;
} //-int main(void)
{printf("%d\n",cal_bit(255)); return 0;
}
/*---- E ----*/
6.字符串转换为整数,比如“1234”转换成1234.
#include <stdio.h> char str[6]="12345"; intstring_to_int(char s[])
{ int i; intsum=0; for(i=0;s[i]!='\0';i++)
sum=sum*10+s[i]-'0';
return sum;
} //----int main(void)
{printf("%d\n",string_to_int(str)); return 0;
}
/*------ E -----*/
7.整数转换为字符串,比如1234转换成“1234”.
#include <stdio.h>
#include <math.h> #define LEN 4 charstr[]=" "; char *int_to_string(int given)
{ int i; inttemp; given=given%((int) pow(10,LEN-1-i)); //int mustbe on both side of '%'str[i]=temp+'0';
} return str;
} //----int main(void)
{printf("%s\n",int_to_string(9876)); return 0;
}
/*------ E -----*/
8. C语言实现插入排序算法(从大到小,从小到大).
#include<stdio.h> #define LEN5 int a[LEN]={7,4,8,4,5}; void insertion_sort(void)
{ int i,j,key;for(j=1;j<LEN;j++){printf("%d,%d,%d,%d,%d\n",a[0],a[1],a[2],a[3],a[4]); key=a[j]; i=j-1;
while( (i>=0) && (a[i]>key) ){ // a[i]>key 从小到大;a[i]<key从大到小 a[i+1]=a[i]; i--;
} a[i+1]=key;
}printf("%d,%d,%d,%d,%d\n",a[0],a[1],a[2],a[3],a[4]);
} //----int main(void)
{insertion_sort();
return 0;
}
/*------ E -------*/
9. C语言实现冒泡排序算法(从大到小,从小到大)
#include<stdio.h> #define LEN5 int a[LEN]={5,4,3,2,1}; void bubble_sort(void)
{ inti,j,flag=1; int temp; for(i=1;(i<LEN)&&(flag==1);i++){ flag=0;
flag=1;temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } }printf("%d,%d,%d,%d,%d\n",a[0],a[1],a[2],a[3],a[4]);
}
}
//-------intmain(void)
{ bubble_sort();return 0;
}
/*---- E ----*/