按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
intmy_strlen(constchar*strDest) 
{ 
assert(NULL!= 
strDest); 
if 
('0' 
 
*strDest) 
{ 
return0; 
} 
else 
{ 
return(1+my_strlen(++strDest)); 
} 
}
第一步:用 
assert宏做入口校验。
第二步:确定参数传递过来的地址上的内存存储的是否为 
'0'。如果是,表明这是一个
空字符串,或者是字符串的结束标志。
第三步:如果参数传递过来的地址上的内存不为 
'0',则说明这个地址上的内存上存储
的是一个字符。既然这个地址上存储了一个字符,那就计数为 
1,然后将地址加 
1个 
char
类型元素的大小,然后再调用函数本身。如此循环,当地址加到字符串的结束标志符 
'0'时,
递归停止。
当然,同样是利用递归,还有人写出了更加简洁的代码: 
intmy_strlen(constchar*strDest) 
{ 
return*strDest?1+strlen(strDest+1):0; 
}
这里很巧妙的利用了问号表达式,但是没有做参数入口校验,同时用 
*strDest来代替('0' 
 
*strDest)也不是很好。所以,这种写法虽然很简洁,但不符合我们前面所讲的编码规范。
可以改写一下: 
intmy_strlen(constchar*strDest) 
{ 
assert(NULL!= 
strDest); 
return('0' 
!= 
*strDest)?(1+my_strlen(strDest+1)):0; 
}
上面的问题利用函数递归的特性就轻易的搞定了,也就是说每调用一遍 
my_strlen函数,
其实只判断了一个字节上的内容。但是,如果传入的字符串很长的话,就需要连续多次函数
调用,而函数调用的开销比循环来说要大得多,所以,递归的效率很低,递归的深度太大甚
至可能出现错误(比如栈溢出)。所以,平时写代码,不到万不得已,尽量不要用递归。即
便是要用递归,也要注意递归的层次不要太深,防止出现栈溢出的错误;同时递归的停止条
件一定要正确,否则,递归可能没完没了。
第七章文件结构
一个工程是往往由多个文件组成。这些文件怎么管理、怎么命名都是非常重要的。下面
给出一些基本的方法,比较好的管理这些文件,避免错误的发生。
7。1,文件内容的一般规则
【规则 
7…1】每个头文件和源文件的头部必须包含文件头部说明和修改记录。
源文件和头文件的头部说明必须包含的内容和次序如下: 
/************************************************************************ 
* 
FileName 
: 
FN_FileName。c/FN_FileName。h 
* 
Copyright 
: 
2003…2008XXXXCorporation;AllRightsReserved。 
* 
ModuleName 
: 
DrawEngine/Display 
* 
* 
CPU 
: 
ARM7 
* 
RTOS 
: 
Tron 
* 
* 
CreateDate 
: 
2008/10/01 
* 
Author/Corporation 
: 
WhoAmI/yourpanyname 
* 
* 
AbstractDescription 
: 
Placesomedescriptionhere。 
* 
*…RevisionHistory… 
No 
Version 
Date 
RevisedBy 
Item 
Description 
* 
1 
V0。95 
08。05。18 
WhoAmI 
abcdefghijklm 
WhatUDo 
* 
************************************************************************/
【规则7…2】各个源文件必须有一个头文件说明,头文件各部分的书写顺序下:
No。 
Item 
1 
Header 
File 
Header 
Section 
2 
Multi…Include…Prevent 
Section 
3 
Debug 
Switch 
Section 
4 
Include 
File 
Section 
5 
Macro 
Define 
Section 
6 
Structure 
Define 
Section 
7 
PrototypeDeclareSection 
其中 
Multi…Include…PreventSection是用来防止头文件被重复包含的。
如下例: 
#ifndef 
__FN_FILENAME_H 
#define__FN_FILENAME_H 
#endif
其中“FN_FILENAME”一般为本头文件名大写,这样可以有效避免重复,因为同一工程
中不可能存在两个同名的头文件。 
/************************************************************************ 
* 
FileName 
: 
FN_FileName。h 
* 
Copyright 
: 
2003…2008XXXXCorporation;AllRightsReserved。 
* 
ModuleName 
: 
DrawEngine/Display 
* 
* 
CPU 
: 
ARM7 
* 
RTOS 
: 
Tron 
* 
* 
CreateDate 
: 
2008/10/01 
* 
Author/Corporation 
: 
WhoAmI/yourpanyname 
* 
* 
AbstractDescription 
: 
Placesomedescriptionhere。 
* 
*RevisionHistory… 
No 
Version 
Date 
RevisedBy 
Item 
Description 
* 
1 
V0。95 
08。05。18 
WhoAmI 
abcdefghijklm 
WhatUDo 
* 
************************************************************************/ 
/************************************************************************ 
* 
Multi…Include…PreventSection 
************************************************************************/ 
#ifndef 
__FN_FILENAME_H 
#define 
__FN_FILENAME_H 
/************************************************************************ 
* 
DebugswitchSection 
************************************************************************/ 
#define 
D_DISP_BASE 
/************************************************************************ 
* 
IncludeFileSection 
************************************************************************/ 
#include 
〃IncFile。h〃 
/************************************************************************ 
* 
MacroDefineSection 
************************************************************************/ 
#define 
MAX_TIMER_OUT 
(4) 
/************************************************************************ 
* 
Struct 
DefineSection 
************************************************************************/ 
typedef 
structCM_RadiationDose 
{ 
unsignedcharucCtgID; 
charcPatId_a'MAX_PATI_LEN'; 
}CM_RadiationDose_st;*CM_RadiationDose_pst; 
/************************************************************************ 
* 
PrototypeDeclareSection 
************************************************************************/ 
unsignedintMD_guiGetScanTimes(void); 
… 
… 
#endif 
【规则7…3】源文件各部分的书写顺序如下: 
No。 
Item 
1 
Source 
File 
Header 
Section 
2 
Debug 
Switch 
Section 
3 
Include 
File 
Section 
4 
Macro 
Define 
Section 
5 
Structure 
Define 
Section 
6 
Prototype 
Declare 
Section 
7 
Global 
Variable 
Declare 
Section 
8 
File 
Static 
Variable 
Define 
Section 
9 
Function 
Define 
Section 
/************************************************************************* 
* 
File 
Name 
: 
FN_FileName。c 
* 
Copyright 
: 
2003…2008XXXXCorporation;AllRightsReserved。 
* 
ModuleName 
: 
DrawEngine/Display 
* 
* 
CPU 
: 
ARM7 
* 
RTOS 
: 
Tron 
* 
* 
CreateDate 
: 
2003/10/01 
* 
Author/Corporation 
: 
WhoAmI/yourpanyname 
* 
* 
Abstract 
Description 
: 
Place 
some 
description 
here。 
* 
*…RevisionHistory… 
No 
Version 
Date 
Revised 
By 
Item 
Description 
* 
1 
V0。95 
00。05。18 
WhoAmI 
abcdefghijklm 
WhatUDo 
* 
************************************************************************/ 
/************************************************************************ 
* 
DebugswitchSection 
************************************************************************/ 
#define 
D_DISP_BASE 
/************************************************************************ 
* 
Include 
File 
Section 
************************************************************************/ 
#include 
〃IncFile。h〃 
/************************************************************************ 
* 
MacroDefineSection 
************************************************************************/ 
#define 
MAX_TIMER_OUT 
(4) 
/************************************************************************ 
* 
Struct 
Define 
Section 
************************************************************************/ 
typedef 
structCM_RadiationDose 
{ 
unsignedchar 
ucCtgID; 
char 
cPatId_a'MAX_PATI_LEN'; 
}CM_RadiationDose_st; 
*pCM_RadiationDose_st; 
/***************