1.嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环?
第一种 | 第二种 | 第三种 |
---|---|---|
while(1) { } |
for(;;) { } |
goto Loop: … goto Loop; |
2.位操作(Bit manipulaton)
答:嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a,写两端代码,第一个设置 a 和bit 3,第二个清除 a 和 bit 3。在以上两个操作中,要保持其他位不变。
用 #defines 和 bit masks 操作。这是一个有极高可移植性的方法,是应该被用到的方法。最佳的解决方案如下:
#define BIT3(0x1 << 3)
static int a;
void set_bit3(void)
{
a |= BIT3;
}
void claer_bit3(void)
{
a &= ~BIT3;
}
3.访问固定的内存位置(Accessing fixed memory locations)
答:嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一堆绝对地址为0x67a9的整型变量值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。
//为了访问一绝对地址把一个整型数强制转换(typecast)为一指针
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa66;
4.中断(Interrupt)
答:中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展——让标准C支持中断。具代表事实,产生一个新的关键字_interrupt。下面的代码就使用了_interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码。
_interrupt double compute_area(double radius) //ISR不能返回一个值,不能传递参数
{
double area = PI * radius * radius;
printf("\nArea = %f",area);
return area;
}
/*
在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的
寄存器入栈,有些处理器/编译器就是不允许在 ISR 中做浮点运算。此外,ISR 应该是短而
有效率的,在 ISR 中做浮点运算是不明智的。
*/
5.Typedef
答: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 两个指针。
6.给变量a给出下面的定义
int a; //一个整形数
int *a; //一个指向整型数的指针
int **a; //一个指向指针的指针,它指向的指针是指向一个整型数
int a[10]; //一个有10个整型数的数组
int *a[10]; //一个有10个指针的数组,该指针是指向一个整型数的
int (*a)[10]; //一个指向有10个整型数数组的指针
int (*a)(int); //一个指向函数的指针,该函数有一个整型参数并返回一个整型数
int (*a[10])(int); //一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数。
7.写一个“标准”宏
//交换两个参数值的宏定义:
#define SWAP P(a,b) a = a + b; b = a - b; a = a-b;
//输入两个参数,输出较小的一个:
#define MIN(A,B) (A < B)?A:B
//已知一个数组 table,用一个宏定义,求出数据的元素个数
#define NTBL
#define NTBL(sizeof(table) / sizeof(table[0]))
8.A.c 和 B.c 两个 c 文件中使用了两个相同名字的 static 变量,编译的时候会不会有问题?这两个 static 变量会保存到哪里(栈还是堆或者其他的)?
答:static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。他们都放在数据区,但是编译器对他们的命名是不同的。如果要使变量在其他模块也有意义的话,需要使用extern关键字。
9.一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指
向的节点?
答:将这个指针指向的 next 节点值 copy 到本节点,将 next 指向 next->next,并随后删除原 next
指向的节点。
代码例子:
//假设 p是已知指针
Node *temp=p->next;
DataStyle d=temp->data;
p->data=temp->data;//交换两节点的值
p->next=temp->next;//链接单链表