函数设计规则与例子
函数是C++/C程序的基本功能单元,其重要性不言而喻。函数设计的细微缺点很容易导致该函数被错用,所以光使函数的功能正确是不够的。本章重点论述函数的接口设计和内部实现的一些规则。
函数接口的两个要素是参数和返回值。C语言中,函数的参数和返回值的传递方式有两种:值传递(pass by value)和指针传递(pass by pointer)。C++ 语言中多了引用传递(pass by reference)。由于引用传递的性质象指针传递,而使用方式却象值传递,常常迷惑不解,容易引起混乱,请先阅读林锐博士的《高质量C++/C编程指南》一书的第六章--函数设计,链接如下:
而我要说的就是在编程的过程中,不用在函数的声明和定义中混用新旧两种风格。旧风格就是K&R C风格,新风格是ANSI C原型风格。
如果函数在头文件里的声明是K&R C风格的,那么该函数的定义也应该使用K&R C风格的语法。
文件一:int foo();
文件二:int foo()
int a;
int b;
{
/*......*/
}
如果函数具有ANSI C原型,那么在它的定义中也使用ANSI C风格的语法。
文件一:int foo(int a ,int b);
文件二:int foo(int a ,int b)
{
/*.....*/
}
以下是我实际工作中的例子,在文件flash.h中的定义如下。
#ifndef _FLASH_H_
#define _FLASH_H_
#include "_define.h"
#define _FLASH_ID_SV7C3208UTA_701 0x7ff6 // for silicon 7C top
#define _FLASH_ID_SV7C3208UBA_701 0x7ff9 // for silicon 7C bottom
#define __FADR_OFFSET 0xC00000//for silicon flash
_WORD Bios_GetFlashIdCode(_VOID);
_BOOL ToggleWait(_DWORD addr);
_BOOL Bios_EraseFlashSector(_DWORD addr);
//_BOOL Bios_FlashChipErase(_VOID);
_BOOL Bios_WriteFlash(_DWORD addr, _LPBYTE str,_DWORD size);
_DWORD Bios_ReadFlash(_DWORD addr,_LPBYTE str,_DWORD size);
_BYTE Bios_ReadFlashByte(_DWORD addr);
_WORD Bios_ReadFlashWord(_DWORD addr);
_DWORD Bios_ReadFlashDWord(_DWORD addr);
_BOOL Bios_EraseFlash(_DWORD addrStart,_DWORD size);
_VOID Bios_ReWriteSector(_DWORD addr, _PBYTE str,_DWORD size);
_BOOL Bios_UpdateBootCode(_DWORD addr, _PBYTE str,_DWORD size);
#endif // _FLASH_H_
而在其函数定义中,也应该按照头文件中函数的声明的格式来编写。
文件flash.c
………………
/*
------------------------------------------------------------------------
FUNCTION: Bios_ReadFlash
PURPOSE: read flash to buffer
ENTRY: address ,buffer ,size
RETURN: size
FLOWCHART
NOTE
------------------------------------------------------------------------
*/
_DWORD Bios_ReadFlash(_DWORD addr,_LPBYTE str,_DWORD size)
{
_DWORD i, len;
_WORD x;
len = (size+1)/2;
addr |=__FADR_OFFSET;
for(i=0;i<len;i++)
{
x = __F_ADDR_(addr);
*str++ = (_BYTE)x;
if ( ((i+1)*2) <= size )
*str++ = (_BYTE)(x>>8);
addr += 2;
}
return i;
}
/*
------------------------------------------------------------------------
FUNCTION: Bios_ReadFlashByte
PURPOSE: read a byte from flash
ENTRY: address
RETURN: byte
FLOWCHART
NOTE
------------------------------------------------------------------------
*/
_BYTE Bios_ReadFlashByte(_DWORD addr)
{
_WORD data;
_BYTE byte;
data = __F_ADDR_(addr|__FADR_OFFSET);
if ( (addr % 2) == 0 )
byte = (_BYTE)data;
else
byte = (_BYTE)(data >> 8);
return byte;
}
/*
------------------------------------------------------------------------
FUNCTION: Bios_ReadFlashWord
PURPOSE: read a word from flash
ENTRY: address
RETURN: word
FLOWCHART
NOTE
------------------------------------------------------------------------
*/
_WORD Bios_ReadFlashWord(_DWORD addr)
{
return (__F_ADDR_(addr|__FADR_OFFSET));
}
/*
------------------------------------------------------------------------
FUNCTION: Bios_ReadFlashDWord
PURPOSE: read a double word from flash
ENTRY: address
RETURN: double word
FLOWCHART
NOTE
------------------------------------------------------------------------
*/
_DWORD Bios_ReadFlashDWord(_DWORD addr)
{
return (__F_ADDRDWD_(addr|__FADR_OFFSET));
}
_BOOL Bios_EraseFlash(_DWORD addrStart,_DWORD size)
{
_DWORD addr;
_DWORD sectorSize;
addrStart|=__FADR_OFFSET; //add for compatible flash address!
for(addr=addrStart;addr < (addrStart+size);addr +=sectorSize)
{
if(!Bios_EraseFlashSector(addr))
return FALSE;
//add for silicon flash 05/07/2005
#if defined(_FLASH_ID_SV7C3208UBA_701)\
||defined(_FLASH_ID_SV7C3208UTA_701)
switch(g_flashID)
{
case _FLASH_ID_SV7C3208UTA_701: //Top boot
if(addr<0xff0000)
sectorSize=0x10000;
else
sectorSize=0x2000;
break;
case _FLASH_ID_SV7C3208UBA_701: //Bottom boot
if(addr < 0xC10000)
sectorSize= 0x2000;
else
sectorSize= 0x10000;
break;
default:
break;
}
#endif
}
return TRUE;
}
………………
这里不再一一列举每个函数。
这一点一定要记住,不然会有很多的麻烦。一致性格外重要。
发表于 @ 2006年11月30日 14:16:00|评论(loading...)|编辑