1、当你需要对每一个错误或者每一帧都要进行独立解析或者处理的时候,在面对很多很多函数的选择的时候,你可以加入一个转移表来将所有的函数集合起来,优雅的处理这个问题。
那转移表是什么呢?这就是创建一个函数指针数组,将那些函数全部包含起来,像调用数组中的元素一样调用函数去处理当前的问题。
2、在编写bootloader的时候需要跳转到App程序,你可以采用 JMP 指令直接跳转到目标地址,也可以采用函数指针的方式跳转到目标地址,例如要跳转到0x0080
第一种办法 插入汇编指令跳转过去
JMP 0x0080
第二种办法 利用函数指针跳转过去
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
Jump_To_Application = (pFunction) 0x0080;
Jump_To_Application();
3、一些有意思的语句如
node[i>>3] += -(0x01<<(i&0x70));
node[i++] += -(0x01<<(i&0x70));
这两个语句很有意思,明明 ’++‘ 的优先级比‘>>’高,但是是最后才执行的,而右移则在赋值之前执行。
void (*signal(int sig, void (*func)(int)))(int);
typedef void(*ptr_to_func)(int);
ptr_to_func signal(int, ptr_to_func);
第一句和第二句表达的意思是一样的,后一种很简洁,但是在工作中遇到有人用typedef包上三四层就离谱!
#define weather int
static unsigned weather i;
#typedef int weather
static unsigned weather i;//error!
#define char_ptr char*
char_ptr a, b;
#typedef char* char_ptr
char_ptr a, b;
typedef 和 define之间的区别,typedef更强调的是封装性,你不能再往里面加东西了,就相当于已经做好蛋糕摸具你不能改,但是define不讲武德用,可以灵活修改的摸具你可以往里面夹带私货,但是在后面两句里体现了,a是char型数据的指针但是b只是char型的数据,而后面那句中都是char型指针!
4、结构体作为函数参数传递中,会复制一份结构体数据再传入函数,这样很浪费空间,故可以直接采用结构体指针去作为函数参数去传递,节约空间。结构体成员的字节对齐问题,如果不强制对齐那么有效对齐位数是结构体成员中最长的成员,例如
struct{
char a;
int b;
char c;
}test;
struct{
char a;
char b;
int c;
}test;
在32位和64位的机器中int通常为4个字节(16位的为2个字节,具体看编译器),char为1个字节, 第一个结构体的内存大小为,12个字节而第二个则是8个字节。
5、数据类型的表示范围问题:例如你在编辑器里写下char 但是由于编译器的不同它有可能是single char 也就是带符号位,也可能是unsigned char不带符号位的,如果采用直接写char去定义数据类型的话会造成,程序的可移植性下降。
6、字符串常量实际上,是一个字符指针。指针和数组是有区别的,数组的名称实际上是代表该数据类型的存储的首地址,利用数组下标进行地址偏移取值,而用指针存储也使用数组下标的方式调用,则是先取指针中存储的字符数组的地址再进行地址偏移后取值。