9.十万个问题
9.1.定义局部变量而不初始化,其值为什么是随机的?
因为定义时相当于在栈上移动指针找到一块没人在用的空间给变量,但是栈是会被人反复使用的(脏的),所以这块空间上遗留着上次使用的内容。
9.2.结构体为什么要对齐访问?
主要是为了配合硬件,提高访问效率。
9.3.为什么需要条件编译?
有时候我们希望程序有多种配置,我们在编写源代码时写好了各种配置的代码,然后给个配置开关,在源代码级别区修改配置开关来让程序编译出不同的效果。
9.4.为什么会有函数?
这是人的需要不是机器的需要。可以分化问题,易于分工,有利于程序的组织。
9.5.为什么需要回调函数
实现方:提供回调的地方
执行方:调用回调的地方
1、降低模块耦合性(降低依赖性、关联性),提高模块独立性,避免模块之间你中有我我中有你。
2、异步回调,可以将耗时的操作隐藏在执行方,不影响实现方其它操作。SetTimer
3、多态效果,可以让实现方,根据自己的需要定制执行方的不同形态;
例如功能模块和业务模块之间
9.6.Localhost、127.0.0.1、0.0.0.0有什么区别
在IP协议中,0.0.0.0表示“本网络中的本机”,而127.0.0.1则表示环回地址。如果用于Hosts文件,可以用localhost替代。
当需要多IP地址服务监听的时候,使用0.0.0.0;而需要做回环测试的时候则使用127.0.0.1。
9.7.32位为什么叫x86
x86指的是一种cpu的架构。基于32位cpu开发的操作系统就叫32位操作系统,因为目前x86架构在32位cpu的知名度,32位操作系统也通常被称为x86系统。
9.8.什么是嵌入式
嵌入式即嵌入式系统,是用于控制、监视或者辅助操作机器。
9.9.mcu、cpu、dsp有什么区别?
MCU:单片机;将计算机的CPU、RAM、ROM、定时数器和多种I/O接口集成在一片芯片上,形成芯片级的计算机。
CPU:中央处理单元(Central Processing Unit)的缩写,它可以被简称做微处理器(Microprocessor),用于计算。
DSP(digital signal processor)是一种独特的微处理器,是以数字信号来处理大量信息的器件。
9.10.0、NULL强转有什么用
比如linux kernel下有链表定义LINK_NODE
typedef struct _LINK_NODE
{
struct _LINK_NODE* prev;
struct _LINK_NODE* next;
}LINK_NODE;
然后我们自定义的结构体如下,在只知道LINK_NODE的情况下,如何使用DATA_TYPE访问value呢?
方法是head的地址减去head相当于结构体的偏移,就可以得到结构体的首地址,再强转后就是DATA_TYPE了。
typedef struct _DATA_TYPE
{
LINK_NODE head;
int value;
}DATA_TYPE;
#define GET_DATA_ADDRESS(pNode, DATA, head) \
(DATA*)((char*)(pNode) - (&((DATA*)(0))->head))
9.11.结构体最后定义char[0]有什么用
typedef struct _DATA
{
int len;
char flage;
int value;
char a[0];
}DATA;
这个a可以用来实现可变长的结构体,用的时候malloc出来就可以了。其本身不占内存空间,但是可以访问。如果用其他方式比如char a[1]那就还得占空间。
9.12.(void) (&min1 == &min2)的作用
在linux 内核中,这个起到警告的作用。如果两个变量不是相同类型,进行==就会告警。
9.13 宏定义加括号的作用
例如:
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
如果不加(),那这个宏定义只能作为一条语句的方式使用:形如
单独一行的min(1,2)[;]
在其他情况下都会编译报错:形如作为参数、条件语句
if(min(1,2)){}
num = 1?min(2,3):4;
printf("%d\n", min(1,2));