1、用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)。
#define YEAR_SECOND (365 * 24 * 60 * 60)UL
//一年365天,一天24小时,一小时60分钟,一分钟60秒
//UL表示数长度 unsigned long
2、写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。
#define MIN(a,b) ((a > b) ? (b) : (a))
3、预处理器标识 #error 的目的是什么
停止编译,并输出错误信息,具体用法如下。
#ifndef ADC
#error "ADC未定义"
#endif
这段代码主要检查ADC这个宏定义是否有定义,如果没有定义,就停止编译,并输出ADC未定义。
4、嵌入式系统中经常要用到无限循环,你怎么样用 C 编写死循环。
while(1){
//放入死循环函数
}
for(;;){
//放入死循环函数
}
do{
//放入死循环函数
}while(1)
5、用 变量 a 给出下面的定义:
- 整型数
- 指向整型数的指针
- 指向指针的指针,它指向的指针指向整型数
- 有10个整型数的数组
- 有10个指针的数组,它的指针指向整型数
- 指向有10个整型数的数组的指针
- 指向函数的指针,该函数有一个整型参数,并返回一个整型数
- 有10个指针的数组,该指针指向一个函数,该函数有一个整型参数 并返回一个整型数
- 整型数 :
- 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);
6、static 的作用,请写出两个;
1、在函数体内定义static变量,表示该变量的作用范围在该函数体内,该变量的内容只分配一次,因此该变量的生存周期长,不会随着函数体执行结束而被销毁。
2、在函数体外、文件内定义static变量,表示该变量的作用范围在该文件内,可以被文件内的所有函数访问,但是不能被文件外的函数访问。
3、利用static修饰函数名,表示该函数只能被同文件中的函数调用,不能被文件外的函数调用。
7、关键字const的作用;
1、用const修饰变量,表示该变量是只读变量。
2、使编译器能够保护好被const修饰的变量,防止其被无意修改。
例如:
const int a;//表示a是一个整形常量
const int *a;//const修饰的是int,表示指针中的数据不可以改变,但是指针可以改变。
int * const a;//const修饰的是指针,表示指针不可以改变,但是指针中的数据可以改变。
const int *const a;//const修饰了int,const修饰了指针,表示指针和数据都不可以改变。
8、volatile的作用;
利用volatile修饰变量,防止变量被编译器优化。
1、利用中断去改变一个变量的值,这个值是系统运行参数,使用volatile修饰这个值可以防止编译器对这个变量进行优化而陷入死循环。
2、修饰并行设备的硬件寄存器,如状态寄存器(状态可能会被外部事件改变)。
3、多线程中,被几个任务共享的变量(即随时可能被修改)。
9、嵌入式系统总是要用户对变量或寄存器,进行位操作;
- 对bit3 进行置1,而不改变其他位的值。
- int a;
- a |= (0x01 << 3);
- 对bit4 进行置0,而不改变其他位的值。
- int a;
- a &= ~(0x01 << 4);
- 取出0x56的低三位。
- char a = 0x56;
- a &= 0x07;
10、嵌入式系统经常具有要求程序员去访问某特定的内存位置,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66;
int *p = (int *)(0x67a9);
*p = 0xaa66;
11、中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。具体表现是,产生了一个新的关键字 __interrupt。
下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。__interrupt double compute_area (double radius)
{
double area = PI * radius * radius;
printf("\nArea = %f", area);
return area;
}
中断:表示某个事件发生了,CPU暂停当前正在执行的程序,转去执行中断的程序,执行完中断程序后继续之前暂停的任务。
1、中断不可以返回值,返回area是不合法的。
2、中断内尽量不要做浮点数的运算。
3、中断不可以传递参数,double radius的输入是不合法的。
4、printf()不可以在中断内调用,这个函数经常有重入和性能上的问题。
12、请判断下面代码输出的结果
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a + b > 6) ? puts(" > 6 “) : puts(” <= 6 ");
}
代码输出:>6。
因为 a 是无符号整形,b是有符号整形,两者运算会将 b 自动转为无符号整形,所以 b = -20 会变成一个很大的数,所以输出 >6。
13、 评价下面的代码片断:
unsigned int zero = 0;
unsigned int comp_zero = 0xFFFF; //0 的反码(错误结果)
对于非16位单片机来说,unsigned int comp_zero = 0xFFFF;的写法是不正确的。
正确的写法如下:
unsigned int zero = 0;
unsigned int comp_zero = ~0;//对0按位取反
14、判断下面代码段输出什么?为什么?
char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
puts(“Got a null pointer”);
else
puts(“Got a valid pointer”);
输出:Got a valid pointer
因为内存申请了0字节,虽然没有申请到内存,但是其依然是合法的,依然会申请到一个合法的指针,所以输出Got a valid pointer。
申请内存的写法:
int *p = NULL;
p = (int *) malloc(sizeof(int) * 128);//申请了128个int类型的空间
free(p);//内存释放
15、判断下面代码是否合法
#define dPS struct s *
typedef struct s * tPS;
dPS p1 , p2;
tPS p3 , p4;
#define dPS struct s * 不合法
typedef struct s * tPS; 合法
因为dPS p1,p2 ,展开可以表示为 : struct s *p1,p2。
p1能够达成定义目的,而p2不可以,p2被定义为一个结构体。
因为tPS p3,p4 ,展开可以表示为 : struct s *p3; struct s *p4;符合定义目的。
16、分析代码:
int a = 5, b = 7, c;
c = a +++ b;
c = a +++ b;
可以表示为 c = a++ +b;
a++ 等于6
b 等于7
在表达式中 a++仍然等于5,只有c赋值之后,a才等于6,所以
c = 5 + 7 = 12;
2217

被折叠的 条评论
为什么被折叠?



