嵌入式开发中的一些细节(dlmu2001)

从事开发一年多,发现到一些小细节,会影响到自己开发的效率,特总结如下,以免犯错

1.标准C中str系列的函数中,'/0'有特殊的含义(字符串结束),所以如果要操作具有0x00(有实际意义)的字符串,不应该用该系列的函数。

例:有字符串"/0nocookie/0nocache/0",本义是想用'/0'来表示分隔符,分隔出nocookie和nocache,拷贝的时候用strcpy(Buf,"/0nocookie/0nocache/0"),结果Buf里面什么也没有,因为strcpy碰到0x00就自动结束了。要实现这一个功能,应该改用memcpy,memcpy(Buf,"/0nocookie/0nocache/0",strlen("0nocookie0nocache0"));注意到strlen里面我没有再使用'/0'

2.在开发中,对内存的操作经常采用基址+偏移的方式,这时候相当于一块大的内存多用,每次用只记录相对于基址的偏移以及使用到的内存块的长度,比如开一块Buf,200k,用Buf+Start来存放某一个变量,Len表示该变量占用的内存块长度,这种用法的时候,两个相邻的变量之间可能没有间隔,所以尽量不要再用str系列的函数。当然,保险的方法是人为的加入一些间隔

3.宏和常量

在开发中,为了利于以后的维护,经常对一些字符串,常数,以宏或者常量的形式定义,这二者是有区别的,宏是在预编译的时候替代的,而常量是在运行时赋值的。所以如果对宏赋值,编译器大部分能报错,但是对常量赋值,编译器不一定会报错,但是运行时肯定有问题,应该避免编码的时候对常量赋值。

4.全局变量的问题

有的系统支持声明时赋值,但是为了提高可移植性,最好不要对全局变量进行声明时赋值的操作,否则在有些系统上会产生意想不到的破坏效果。比较保险的做法是有个初始化函数处理所有的全局变量的赋初值工作。

顺便插一句,在函数里头,最好养成先在开头声明所有变量,然后初始化,然后再操作的习惯,有些系统是不支持在函数的中间声明变量的

5.动态内存的申请和释放

这是嵌入式系统中一个比较头疼的问题,有几个问题需要注意1)系统是否支持动态内存,可支持多大的动态内存。为了提高移植性,建议将内存操作的函数封装一下,实现内核代码的与平台无关2)对动态内存,一般在分配后要检查是否成功,以避免对空地址操作。一般是采用声明时赋初值null,分配后检查是否为NULL。3)内存释放后最好对指针赋0,由于有的系统内存空间释放以后,指针的值并没有变,这时候如果指针不小心再拿来使用,会有很大的问题,所以在free以后强烈建议一定对指针赋空4)内存泄漏,在内存分配以后,必须保证以任何出口(途径)退出,都要释放申请的内存,很多系统在查找内存的释放上都比较费力,所以在编码的时候一定要检查仔细。另外,如果可以用数组代替的地方,尽量用数组代替,而不使用动态内存。对内存泄漏的查找要有步骤的进行,首先是重现泄漏,然后总结规律,根据规律打断点,看相应的代码。如果没有任何规律,只好一步步排查,就是运行到某个节点,然后退出,没有泄漏,即可以判断泄漏出现在该节点之后。

6.关于sizeof

在C语言中,sizeof是个单目操作符,它以字节的形式给出了操作数的存储大小,可以用于数据结构类型或者变量1)int,long,double,float这些类型的大小不同的编译器是不一样的2)对指针使用sizeof操作符,每个指针都是一样大小的,视编译器不同而定,比如micorsoft的C,C++编译器,指针总是4个字节的,例:

char TestBuf[100];

int Len1,Len2,Len3;

char *p;

memset(TestBuf,0,100);

Len1=Len2=Len3 = 0;

strcpy(TestBuf,"testbuf");

Len1 = sizeof(TestBuf);

Len2 = strlen(TestBuf);

p = TestBuf;

Len3 = sizeof(p);

则Len1 = 100,Len2 = 7,Len3 = 4(在Microsoft c编译器中)

在这一点中还要注意一个问题,就是数组名作为函数参数传递的时候,其实传递的是数组首地址,就是相当于指针,因此在函数中对该数组名sizeof,得到总是指针的长度。比如上例中,有个函数

void Test(char *p)

{

    int Len4 = sizeof(p);

}如果实参是数组名TestBuf,Len4也总等于4

3)联合类型操作数的sizeof是其最大字节成员的字节数。结构类型操作数的sizeof是这种类型对象的总字节数,包括任何垫补在内。

让我们看如下结构: 

  struct {char b; double x;} a; 

  在某些机器上sizeof(a)=12,而一般sizeof(char)+ sizeof(double)=9。 

  这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。如double类型的结构成员x要放在被4整除的地址。

4)枚举类型一般当作int型处理,如Microsoft上,对枚举变量用sizeof得4 

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭