1. for语句的break
for语句使用break,后续条件不会执行。
for(u8 i=0x00;i<10;i++)
{
if(i==4)
break;
}
printf("i=%d",i);
结果为i=4。continue会执行后续条件。
2. 使用结构体查表,减少if语句
查表一般会省去大部分的if判断条件语句,使用结构体数组查表会使代码看上去不那么low。
下面代码是直接if判断的:
#define PAGE_SIZE 0x4000
#define PAGE1 1
#define PAGE1_START_ADDR 0x08008000
#define PAGE1_END_ADDR PAGE1_START_ADDR+PAGE_SIZE
#define PAGE2 2
#define PAGE2_START_ADDR 0x0800C000
#define PAGE2_END_ADDR PAGE2_START_ADDR+PAGE_SIZE
if(validPage == PAGE1)
{
validPageStart = PAGE1_START_ADDR;
validPageEnd = PAGE1_END_ADDR;
}
else if(validPage == PAGE2)
{
validPageStart = PAGE2_START_ADDR;
validPageEnd = PAGE2_END_ADDR;
}
for(u32 Address = validPageStart+4;Address < PAGE2_END_ADDR;Address += 4)
{
//巴拉巴拉巴拉
}
如果很多地方都要判断这个valid的话,代码会显得很胖乎!建议查表,下面是数组查表:
#define PAGE_SIZE 0x4000
#define PAGE1 1
#define PAGE1_START_ADDR 0x08008000
#define PAGE1_END_ADDR PAGE1_START_ADDR+PAGE_SIZE
#define PAGE2 2
#define PAGE2_START_ADDR 0x0800C000
#define PAGE2_END_ADDR PAGE2_START_ADDR+PAGE_SIZE
u32 PAGE[2][2]={
{PAGE1_START_ADDR,PAGE1_END_ADDR},
{PAGE2_START_ADDR,PAGE2_END_ADDR}
};
for(u32 Address = PAGE[validPage][0]+4;Address < PAGE[validPage][1];Address += 4)
{
//阿巴阿巴阿巴
}
显然,上面的数组在for循环里PAGE[validPage][0]看的不直白,不看定义可能就不会知道他是什么意义的数据,使用结构体的话就好啦!
结构体查表:
#define PAGE_SIZE 0x4000
#define PAGE1 1
#define PAGE1_START_ADDR 0x08008000
#define PAGE1_END_ADDR PAGE1_START_ADDR+PAGE_SIZE
#define PAGE2 2
#define PAGE2_START_ADDR 0x0800C000
#define PAGE2_END_ADDR PAGE2_START_ADDR+PAGE_SIZE
typedef struct
{
u32 StartAddr;
u32 EndAddr;
}Page_struct;
Page_struct PAGE[2]={
{PAGE1_START_ADDR,PAGE1_END_ADDR},
{PAGE2_START_ADDR,PAGE2_END_ADDR}
};
for(u32 Address = PAGE[validPage].StartAddr+4;Address < PAGE[validPage].EndAddr;Address += 4)
{
//嗨 章鱼哥
}
是不是感觉最后一个有一点Fashion!如果是单个判断的话,这么写没什么意义,但是如果经常使用if判断同一个变量,我还是用查表吧,看着还高大上。
3. 共同体+结构体 解决高低字节计算问题
在单片机开发中,经常遇到高低字节计算的问题。如16位数据通过某种8位的协议发送,这时就要将数据分为高低字节发送;或者在读写FLASH时候,我就想读16位,但是FLASH只允许32位读取,这时又需要进行高低16位的计算,等等场合,这时如果使用共同体的话,会使代码省去&0xff或者>>16的计算。
typedef struct
{
u8 LSB;
u8 MSB;
}BIT16_struct;
typedef union
{
u16 Data16;
BIT16_struct Data8;
}Data_union;
Data_union Data=0xAAFF;
SPI_FIFO = Data.Data8.MSB;//发送高位
SPI_FIFO = Data.Data8.LSB;//发送低位
3. 共同体+结构体+数组
共同体+结构体+数组 会使数据处理的更加方便。
struct TEMP_STRUCT
{
uint16_t HalfWord_0;
uint16_t HalfWord_1;
uint16_t HalfWord_2;
uint16_t HalfWord_3;
uint16_t HalfWord_4;
}temp_Struct;
union TEMP_UNION
{
struct TEMP_STRUCT temp_Struct;
uint16_t Array[5];
}temp_Union;
上述例子将结构体中的地址与数组的地址一一对应。连续处理用数组,单独处理用结构体。
但是遇到结构体变量类型不一致的情况下,就可能会有问题了。
比如:
struct TEMP_STRUCT
{
uint16_t HalfWord_0;//对应数组 Array[0]
uint16_t HalfWord_1;//Array[1]
uint16_t HalfWord_2;//Array[2]
uint32_t HalfWord_3_4;//这里插入了一个32位数据//Array[4/5]
uint16_t HalfWord_5;//无数组
}temp_Struct;
union TEMP_UNION
{
struct TEMP_STRUCT temp_Struct;
uint16_t Array[6];
}temp_Union;
上述代码在运行中就会发现有问题,发现有的数组和结构体对应不上,
temp_Union.temp_Struct.HalfWord_2 和 temp_Union.Array[2]
地址是对应的,但是
temp_Union.temp_Struct.HalfWord_3_4 和 temp_Union.Array[4]、[5]
地址是对应的,中间的 temp_Union.Array[3] 没人用
这时就应该知道,当使用 共同体+结构体+数组的情况下,应该32位对齐,所以上述结构体声明应该:
struct TEMP_STRUCT
{
uint16_t HalfWord_0;//Array[0]
uint16_t HalfWord_1;//Array[1]
uint16_t HalfWord_2;//Array[2]
uint16_t HalfWord_5;//Array[3]
uint32_t HalfWord_3_4;//这里插入了一个32位数据//Array[4]
}temp_Struct;
调过来就好了!
5. 结构体位定义
通过结构体的位定义可以实现对数据的位操作。
union Data16_union
{
u16 Data16;
struct Data8_struct
{
u8 LSB;
u8 MSB;
}Data8;
struct Bit_struct
{
u16 bit0:1;
u16 bit1:1;
u16 bit2:1;
u16 bit3:1;
u16 bit4:1;
u16 bit5:1;
u16 bit6:1;
u16 bit7:1;
u16 bit8:1;
u16 bit9:1;
u16 bit10:1;
u16 bit11:1;
u16 bit12:1;
u16 bit13:1;
u16 bit14:1;
u16 bit15:1;
}Bit;
}temp16;
temp16.Bit.bit0 = 1;
最后temp16 = 1;
5. #pragma once
代替
#ifndef __XX_H
#define __XX_H
//
#endif
有些编译器不支持。