以下是阅读开源程序,从中总结出的一些技巧:
1、关于一年天数的宏定义(闰年366天):
#define IsLeapYear(yr) (!((yr) % 400) || (((yr) % 100) && !((yr) % 4)))
#define YearLength(yr) (IsLeapYear(yr) ? 366 : 365)
2、将秒换算成时间函数:
typedef struct
{
uint16_t year; // 2000+
uint8_t month; // 0-11
uint8_t day; // 0-30
uint8_t seconds; // 0-59
uint8_t minutes; // 0-59
uint8_t hour; // 0-23
}
UTCTimeStruct;
uint8_t monthLength( uint8_t lpyr, uint8_t mon )
{
uint8_t days = 31;
if ( mon == 1 ) // feb
{
days = ( 28 + lpyr ); //2月天数为28 + (是否闰年)
} else {
if ( mon > 6 ) // aug-dec 大于6月的30天的月份为9、11月,此时对应的mon为8、10,--之后变为7、9
{
mon--;
}
if ( mon & 1 ) { //判断是否为4 6 9 11
days = 30;
}
}
return ( days );
}
void ConvertToUTCTime( UTCTimeStruct *tm, UTCTime secTime )
{
// calculate the time less than a day - hours, minutes, seconds
{
uint32_t day = secTime % DAY;
tm->seconds = day % 60UL;
tm->minutes = (day % 3600UL) / 60UL;
tm->hour = day / 3600UL;
}
// Fill in the calendar - day, month, year
{
uint16_t numDays = secTime / DAY;
tm->year = BEGYEAR;
while ( numDays >= YearLength( tm->year ) )
{
numDays -= YearLength( tm->year );
tm->year++;
}
tm->month = 0;
while ( numDays >= monthLength( IsLeapYear( tm->year ), tm->month ))
{
numDays -= monthLength( IsLeapYear( tm->year ), tm->month );
tm->month++;
}
tm->day = numDays;
}
}
3、do{ }while(0) 用法
看nordic源码的时候,看到了宏定义中全是用do{ }while(0) 来实现的,开始有点不理解,于是马上查了一下,才发现这么好的技巧,居然自己这么多年不知道,也不会用,马上记录一下:
首先是宏定义的时候将多余一条语句的定义放到do{ }while(0) 的{}中,这样在遇到if()宏 else的时候,就不会出现错误。
其次,避免程序中代码重复,避免使用goto语句的解决方法,例如,函数开头申请了一块内存,后边执行过程检测到错误就释放内存,可以将除了申请和释放的代码放到{}中,遇到错误break即可;
最后,空宏定义可以直接使用do{ }while(0) ,避免编译器警告。
4、赋最大值
int end = (unsigned int)-1;