程序员0x10

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的输入是不合法的。
4printf()不可以在中断内调用,这个函数经常有重入和性能上的问题。

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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值