嵌入式C代码简洁性优化指南
目录
技巧1: 布尔表达式简化
1.1 利用C语言隐式类型转换
冗余写法(你的原代码)
void Led_Proc()
{
// LED0:温度超过上限
if(Temperature_Data > TMAX)
{
Led_Level = 3;
ucLed[0] = 1;
}
else
{
ucLed[0] = 0;
}
// LED1:温度在范围内
if((Temperature_Data >= TMIN) && (Temperature_Data <= TMAX))
{
Led_Level = 6;
ucLed[1] = 1;
}
else
{
ucLed[1] = 0;
}
// LED2:温度低于下限
if(Temperature_Data < TMIN)
{
Led_Level = 9;
ucLed[2] = 1;
}
else
{
ucLed[2] = 0;
}
// LED3:数据错误标志
if(Data_Error == 1)
{
ucLed[3] = 1;
}
else
{
ucLed[3] = 0;
}
}
行数:34行
简洁写法(范例程序风格)
void Led_Proc()
{
// 直接将布尔表达式结果赋值给变量
ucLed[0] = (Temperature_Data > TMAX);
ucLed[1] = (Temperature_Data >= TMIN) && (Temperature_Data <= TMAX);
ucLed[2] = (Temperature_Data < TMIN);
ucLed[3] = Data_Error;
// PWM等级判断
if(Temperature_Data > TMAX)
Led_Level = 3;
else if(Temperature_Data >= TMIN)
Led_Level = 6;
else
Led_Level = 9;
}
行数:14行(减少59%)
原理解析
// C语言中:
// 真值表达式 = 1
// 假值表达式 = 0
unsigned char result;
result = (5 > 3); // result = 1
result = (5 < 3); // result = 0
// 因此可以直接赋值
ucLed[0] = (Temperature_Data > TMAX);
// 等价于
if(Temperature_Data > TMAX)
ucLed[0] = 1;
else
ucLed[0] = 0;
1.2 极致优化:利用整数除法
范例程序的技巧
// 利用整数除法判断大小关系
ucLed[0] = (int)Temperature / Parameter_Ctrol[0];
// 原理:
// 若 Temperature >= Parameter_Ctrol[0],商≥1(真)
// 若 Temperature < Parameter_Ctrol[0],商=0(假)
真值表
Temperature=35, Parameter_Ctrol[0]=30
35 / 30 = 1(整数除法) → ucLed[0] = 1
Temperature=25, Parameter_Ctrol[0]=30
25 / 30 = 0(整数除法) → ucLed[0] = 0
复杂条件组合
// 范例程序:判断温度在范围内
ucLed[1] = (!((int)Temperature / Parameter_Ctrol[0])) &
((int)Temperature / Parameter_Ctrol[1]);
// 拆解:
// Part1: !((int)Temperature / Parameter_Ctrol[0])
// → Temperature < Parameter_Ctrol[0] (上限)
// Part2: ((int)Temperature / Parameter_Ctrol[1])
// → Temperature >= Parameter_Ctrol[1] (下限)
// 结果: (Temperature < 上限) && (Temperature >= 下限)
1.3 实战改进建议
推荐写法(平衡简洁与可读性)
void Led_Proc()
{
// 方案1:布尔表达式(推荐)
ucLed[0] = (Temperature_Data > TMAX);
ucLed[1] = (Temperature_Data >= TMIN) && (Temperature_Data <= TMAX);
ucLed[2] = (Temperature_Data < TMIN);
ucLed[3] = Data_Error;
// 方案2:整数除法(仅当性能关键时使用)
// ucLed[0] = Temperature_Data / (TMAX + 1); // 需要TMAX+1避免除0
// PWM等级
Led_Level = (Temperature_Data > TMAX) ? 3 :
(Temperature_Data >= TMIN) ? 6 : 9;
}
技巧2: 位运算与逻辑运算
2.1 位运算符优化
普通写法
// 参数切换
if(Parameter_Index == 0)
Parameter_Index = 1;
else
Parameter_Index = 0;
简洁写法
// 异或运算翻转
Parameter_Index ^= 1; // 0↔1切换
// 原理:
// 0 ^ 1 = 1
// 1 ^ 1 = 0
2.2 位操作集合
// 1. 置位(设置某位为1)
ucLed[i] |= (1 << n); // 将第n位置1
// 2. 清位(设置某位为0)
ucLed[i] &= ~(1 << n); // 将第n位清0
// 3. 翻转
ucLed[i] ^= (1 << n); // 将第n位翻转
// 4. 测试位
if(ucLed[i] & (1 << n)) // 测试第n位是否为1
// 5. 取反
P1 = ~temp; // 所有位取反(LED驱动常用)
2.3 实战案例:LED驱动优化
你的原代码
void Led_Disp(unsigned char addr, enable)
{
static unsigned char temp = 0x00;
static unsigned char temp_old = 0xff;
if(enable)
temp |= 0x01 << addr; // 置位
else
temp &= ~(0x01 << addr); // 清位
if(temp != temp_old)
{
P1 = ~temp;
temp_old = temp;
}
}
分析:这个已经很简洁了!保持即可。
2.4 位域(Bit Field)技巧
使用位域减少内存
// 原代码:使用多个字节
bit Num_Input; // 1 bit
bit Point_Input; // 1 bit
bit Flag_0; // 1 bit
bit Flag_2; // 1 bit
bit Data_Error; // 1 bit
// 优化:使用位域结构(如果编译器不支持bit类型)
struct {
unsigned char Num_Input : 1;
unsigned char Point_Input : 1;
unsigned char Flag_0 : 1;
unsigned char Flag_2 : 1;
unsigned char Data_Error : 1;
unsigned char reserved : 3; // 预留3位
} Flags;
// 使用
Flags.Num_Input = 1;
if(Flags.Data_Error) { ... }
技巧3: 三元运算符
3.1 基本用法
冗长写法
if(Seg_Disp_Mode == 1)
Seg_Disp_Mode = 2;
else
Seg_Disp_Mode = 1;
简洁写法
Seg_Disp_Mode = (Seg_Disp_Mode == 1) ? 2 : 1;
3.2 范例程序中的应用
// 范例:界面切换
Seg_Disp_Mode = (Seg_Disp_Mode == 1) ? 2 : 1;
// 你的代码可以改为
if(Seg_Disp_Mode != 0)
Seg_Disp_Mode = (Seg_Disp_Mode == 1) ? 2 : 1;
3.3 嵌套三元运算符(适度使用)
PWM等级判断优化
// 原代码
if(Temperature_Data > TMAX)
Led_Level = 3;
else if(Temperature_Data >= TMIN)
Led_Level = 6;
else
Led_Level = 9;
// 简洁写法
Led_Level = (Temperature_Data > TMAX) ? 3 :
(Temperature_Data >= TMIN) ? 6 : 9;
3.4 三元运算符在数组选择中的应用
// 闪烁效果
Seg_Buf[3 + Seg_Input_Index] = Seg_Star_Flag ? Seg_Input[Seg_Input_Index] : 10;
// 等价于
if(Seg_Star_Flag)
Seg_Buf[3 + Seg_Input_Index] = Seg_Input[Seg_Input_Index];
else
Seg_Buf[3 + Seg_Input_Index] = 10;
技巧4: 数组索引计算技巧
4.1 范例程序的巧妙设计
参数闪烁的索引计算
// 范例程序
bit Parameter_Index; // 0或1
// 显示参数
Seg_Buf[2] = Parameter[0] / 10; // 上限十位
Seg_Buf[3] = Parameter[0] % 10; // 上限个位
Seg_Buf[4] = Parameter[1] / 10; // 下限十位
Seg_Buf[5] = Parameter[1] % 10; // 下限个位
// 闪烁效果:通过Parameter_Index计算偏移
Seg_Buf[2 + 2*Parameter_Index] = Seg_Star_Flag ? Parameter[Parameter_Index]/10 : 10;
Seg_Buf[3 + 2*Parameter_Index] = Seg_Star_Flag ? Parameter[Parameter_Index]%10 : 10;
索引计算解析
Parameter_Index = 0 (修改上限)
→ Seg_Buf[2 + 2*0] = Seg_Buf[2] (上限十位)
→ Seg_Buf[3 + 2*0] = Seg_Buf[3] (上限个位)
Parameter_Index = 1 (修改下限)
→ Seg_Buf[2 + 2*1] = Seg_Buf[4] (下限十位)
→ Seg_Buf[3 + 2*1] = Seg_Buf[5] (下限个位)
你的原代码(展开写法)
unsigned char Temperature_Setting_Index; // 0或2
if(Temperature_Setting_Index == 0) // 修改上限
{
Seg_Buf[2] = 10;
Seg_Buf[3] = 10;
}
if(Temperature_Setting_Index == 2) // 修改下限
{
Seg_Buf[4] = 10;
Seg_Buf[5] = 10;
}
优化建议(改用索引计算)
// 方案1:改用0/1索引
unsigned char Parameter_Index; // 0或1
// 闪烁逻辑
if(Flag_2)
{
Seg_Buf[2 + 2*Parameter_Index] = 10;
Seg_Buf[3 + 2*Parameter_Index] = 10;
}
// 方案2:保持你的0/2索引,用除法
if(Flag_2)
{
Seg_Buf[2 + Temperature_Setting_Index] = 10;
Seg_Buf[3 + Temperature_Setting_Index] = 10;
}
4.2 数组遍历优化
展开写法
Seg_Point[3] = 0;
Seg_Point[4] = 0;
Seg_Point[5] = 0;
循环写法
for(i = 3; i < 6; i++)
Seg_Point[i] = 0;
// 或使用memset(需要string.h)
memset(&Seg_Point[3], 0, 3);
技巧5: 循环简化
5.1 For循环优化
你的原代码
for(j = 0; j < 3; j++)
{
Temperature_Real[j] = 0;
}
for(i = 0; i < 3; i++)
{
Temperature_Input_Point[i] = 0;
Temperature_Input[i] = 13;
}
简洁写法
// 合并循环
for(i = 0; i < 3; i++)
{
Temperature_Real[i] = 0;
Temperature_Input_Point[i] = 0;
Temperature_Input[i] = 13;
}
// 或使用memset
memset(Temperature_Real, 0, 3);
memset(Temperature_Input_Point, 0, 3);
memset(Temperature_Input, 13, 3);
5.2 While循环的巧妙应用
范例程序:四舍五入处理
// 根据小数点位置动态除法
Temperature = Seg_Input[0]*100 + Seg_Input[1]*10 + Seg_Input[2] + 5;
while(3 - Point_Wela)
{
Temperature /= 10.0;
Point_Wela++;
}
// 示例:Point_Wela=1(小数点在第2位)
// 循环次数:3-1=2次
// 373.0 → 37.3 → 3.73(实际只除2次)
5.3 展开小循环
// 当循环次数固定且少时,展开可能更快
// ❌ 循环写法(3次迭代)
for(i = 0; i < 3; i++)
Seg_Buf[3 + i] = Seg_Input[i];
// ✅ 展开写法(消除循环开销)
Seg_Buf[3] = Seg_Input[0];
Seg_Buf[4] = Seg_Input[1];
Seg_Buf[5] = Seg_Input[2];
// 注意:51单片机上展开通常更快
技巧6: 条件判断简化
6.1 提前返回(Early Return)
深层嵌套
void Key_Proc()
{
if(Key_Slow_Down == 0)
{
Key_Slow_Down = 1;
Key_Val = Key_Read();
// ... 大量代码
}
}
提前返回
void Key_Proc()
{
if(Key_Slow_Down) return; // 提前退出
Key_Slow_Down = 1;
Key_Val = Key_Read();
// ... 代码不需要缩进
}
优点:减少缩进层级,提高可读性
6.2 合并条件
分散判断
if(Key_Down >= 1)
{
if(Key_Down <= 10)
{
if(Seg_Input_Index <= 2)
{
// 处理
}
}
}
合并条件
if(Key_Down >= 1 && Key_Down <= 10 && Seg_Input_Index <= 2)
{
// 处理
}
6.3 使用查找表替代if-else
大量if-else
if(key == 1) return 0x01;
else if(key == 2) return 0x02;
else if(key == 3) return 0x04;
else if(key == 4) return 0x08;
// ...
查找表
const unsigned char KeyMap[] = {0x01, 0x02, 0x04, 0x08, ...};
return KeyMap[key - 1];
技巧7: 数据结构优化
7.1 数组vs分散变量
你的原代码
unsigned char Temperature_Setting[4] = {3,0,2,0};
unsigned char TMAX, TMIN;
// 使用时需要转换
TMAX = Temperature_Setting[0]*10 + Temperature_Setting[1];
TMIN = Temperature_Setting[2]*10 + Temperature_Setting[3];
范例程序(紧凑)
unsigned char Parameter[2] = {30, 20}; // 直接存储值
// 显示时才分解
Seg_Buf[2] = Parameter[0] / 10;
Seg_Buf[3] = Parameter[0] % 10;
对比:
- 你的:4字节数组 + 2字节变量 = 6字节
- 范例:2字节数组 = 2字节(节省67%内存)
7.2 结构体封装
使用结构体组织相关数据
// 温度相关数据封装
typedef struct {
unsigned char input[3]; // 输入缓冲
unsigned char input_point[3]; // 小数点标记
unsigned char real[3]; // 实际温度
unsigned char data; // 当前温度值
unsigned char index; // 输入索引
bit num_flag; // 数字输入标志
bit point_flag; // 小数点标志
} Temperature_t;
Temperature_t Temp;
// 使用
Temp.input[Temp.index] = Key_Down - 1;
Temp.index++;
优点:
- 数据组织清晰
- 便于参数传递
- 避免全局变量污染
7.3 枚举定义常量
魔法数字
if(Key_Down == 11) { ... } // 11是什么?
if(Key_Down == 12) { ... } // 12是什么?
枚举定义
enum {
KEY_NUM_0 = 1,
KEY_NUM_1,
// ...
KEY_NUM_9 = 10,
KEY_POINT = 11,
KEY_MODE = 12,
KEY_PARAM = 13,
KEY_ADD = 14,
KEY_SUB = 15,
KEY_CONFIRM = 16
};
if(Key_Down == KEY_POINT) { ... }
if(Key_Down == KEY_MODE) { ... }
技巧8: 宏定义与常量
8.1 宏定义常量
// 硬件引脚定义
#define LED_PORT P1
#define SEG_PORT P0
#define SEG_LATCH P2_6
#define SEG_WELA P2_7
// 系统参数
#define TEMP_MAX 85
#define TEMP_MIN 0
#define PARAM_MAX 70
#define PARAM_MIN 10
// 时间常量
#define KEY_SCAN_PERIOD 10 // ms
#define SEG_REFRESH_PERIOD 50 // ms
#define BLINK_PERIOD 250 // ms
#define LONG_PRESS_TIME 500 // ms
8.2 函数宏
// 数值限制宏
#define LIMIT(val, min, max) \
((val) < (min) ? (min) : ((val) > (max) ? (max) : (val)))
// 使用
Temperature = LIMIT(Temperature, 0, 85);
// 数组元素个数
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
// 位操作宏
#define SET_BIT(reg, bit) ((reg) |= (1 << (bit)))
#define CLR_BIT(reg, bit) ((reg) &= ~(1 << (bit)))
#define TOG_BIT(reg, bit) ((reg) ^= (1 << (bit)))
#define GET_BIT(reg, bit) (((reg) >> (bit)) & 1)
8.3 条件编译
// 调试开关
#define DEBUG_MODE 1
#if DEBUG_MODE
#define DEBUG_PRINT(x) printf(x)
#else
#define DEBUG_PRINT(x)
#endif
// 使用
DEBUG_PRINT("Temperature: %d\n"); // Release版本自动删除
技巧9: 函数封装与内联
9.1 提取重复代码
重复的清除逻辑
// 你的代码中多处出现
Temperature_Input_Index = 0;
Num_Input = 0;
Point_Input = 0;
for(j = 0; j < 3; j++)
{
Temperature_Real[j] = 0;
}
for(i = 0; i < 3; i++)
{
Temperature_Input_Point[i] = 0;
Temperature_Input[i] = 13;
}
封装为函数
void Clear_Input_Data(void)
{
unsigned char i;
Temperature_Input_Index = 0;
Num_Input = 0;
Point_Input = 0;
for(i = 0; i < 3; i++)
{
Temperature_Real[i] = 0;
Temperature_Input_Point[i] = 0;
Temperature_Input[i] = 13;
}
}
// 使用
if(invalid_data)
{
Clear_Input_Data();
}
9.2 内联小函数
// 将频繁调用的小函数声明为内联
#define INLINE static inline
INLINE unsigned char Is_Temp_Valid(unsigned char temp)
{
return (temp >= TEMP_MIN && temp <= TEMP_MAX);
}
INLINE void Set_LED(unsigned char index, unsigned char state)
{
ucLed[index] = state;
}
// 使用
if(Is_Temp_Valid(Temperature_Data))
{
Set_LED(0, 1);
}
技巧10: 状态机优化
10.1 使用switch-case优化if-else
你的原代码(部分)
if(Key_Down == 11) { ... }
if(Key_Down == 16) { ... }
if(Key_Down == 12) { ... }
if(Key_Down == 13) { ... }
if(Key_Down == 14) { ... }
if(Key_Down == 15) { ... }
使用switch-case
switch(Key_Down)
{
case KEY_POINT: // 11
// 处理小数点
break;
case KEY_MODE: // 12
// 模式切换
break;
case KEY_PARAM: // 13
// 参数切换
break;
case KEY_ADD: // 14
// 参数加1
break;
case KEY_SUB: // 15
// 参数减1
break;
case KEY_CONFIRM: // 16
// 确认输入
break;
default:
if(Key_Down >= 1 && Key_Down <= 10)
{
// 数字输入
}
break;
}
10.2 函数指针表(高级)
// 定义函数指针类型
typedef void (*KeyHandler)(void);
// 按键处理函数
void Handle_Point(void) { /* ... */ }
void Handle_Mode(void) { /* ... */ }
void Handle_Param(void) { /* ... */ }
void Handle_Add(void) { /* ... */ }
void Handle_Sub(void) { /* ... */ }
void Handle_Confirm(void) { /* ... */ }
// 函数指针表
const KeyHandler KeyHandlers[] =
{
NULL, // 0
NULL, // 1-10 (数字输入)
// ...
NULL, // 10
Handle_Point, // 11
Handle_Mode, // 12
Handle_Param, // 13
Handle_Add, // 14
Handle_Sub, // 15
Handle_Confirm // 16
};
// 使用
if(Key_Down >= 1 && Key_Down <= 16 && KeyHandlers[Key_Down])
{
KeyHandlers[Key_Down]();
}
实战重构:优化你的main.c
重构目标
将你的451行代码优化到约300行,同时保持可读性。
重构1: Led_Proc函数
原代码(34行)
void Led_Proc()
{
if(Temperature_Data > TMAX)
{
Led_Level = 3;
ucLed[0] = 1;
}
else
{
ucLed[0] = 0;
}
if((Temperature_Data >= TMIN) && (Temperature_Data <= TMAX))
{
Led_Level = 6;
ucLed[1] = 1;
}
else
{
ucLed[1] = 0;
}
if(Temperature_Data < TMIN)
{
Led_Level = 9;
ucLed[2] = 1;
}
else
{
ucLed[2] = 0;
}
if(Data_Error == 1)
{
ucLed[3] = 1;
}
else
{
ucLed[3] = 0;
}
}
优化后(8行,减少76%)
void Led_Proc()
{
// 直接赋值布尔表达式
ucLed[0] = (Temperature_Data > TMAX);
ucLed[1] = (Temperature_Data >= TMIN) && (Temperature_Data <= TMAX);
ucLed[2] = (Temperature_Data < TMIN);
ucLed[3] = Data_Error;
// PWM等级(三元运算符)
Led_Level = (Temperature_Data > TMAX) ? 3 :
(Temperature_Data >= TMIN) ? 6 : 9;
}
重构2: 输入数据清除
原代码(重复3次,每次14行)
Temperature_Input_Index = 0;
Num_Input = 0;
Point_Input = 0;
for(j = 0; j < 3; j++)
{
Temperature_Real[j] = 0;
}
for(i = 0; i < 3; i++)
{
Temperature_Input_Point[i] = 0;
Temperature_Input[i] = 13;
}
优化后(封装为函数)
void Clear_Input(void)
{
unsigned char i;
Temperature_Input_Index = 0;
Num_Input = 0;
Point_Input = 0;
memset(Temperature_Real, 0, 3);
memset(Temperature_Input_Point, 0, 3);
memset(Temperature_Input, 13, 3);
}
// 使用(替换3次重复代码)
Clear_Input();
节省:42行 → 13行(减少69%)
重构3: 参数调整逻辑
原代码(按键14,35行)
if(Key_Down == 14)
{
if(Seg_Dis_Mode == 2)
{
Temperature_Setting[Temperature_Setting_Index + 1]++;
if(Temperature_Setting[Temperature_Setting_Index + 1] == 10)
{
Temperature_Setting[Temperature_Setting_Index + 1] = 0;
Temperature_Setting[Temperature_Setting_Index]++;
}
if((Temperature_Setting[Temperature_Setting_Index] == 7) &&
(Temperature_Setting[Temperature_Setting_Index + 1] == 1))
{
Temperature_Setting[Temperature_Setting_Index] = 7;
Temperature_Setting[Temperature_Setting_Index + 1] = 0;
}
}
}
if(Key_Old == 14)
{
if(Seg_Dis_Mode == 2)
{
if(Key_Long0 >= 500)
{
// 重复上面的逻辑...
}
}
}
优化后(提取公共函数)
void Adjust_Parameter(unsigned char delta)
{
unsigned char* param = &Temperature_Setting[Temperature_Setting_Index];
unsigned char val = param[0] * 10 + param[1];
val += delta;
val = LIMIT(val, PARAM_MIN, PARAM_MAX); // 限制10-70
param[0] = val / 10;
param[1] = val % 10;
}
// 按键处理
if(Key_Down == 14 || (Key_Old == 14 && Key_Long0 >= 500))
{
if(Seg_Dis_Mode == 2)
Adjust_Parameter(1); // +1
}
if(Key_Down == 15 || (Key_Old == 15 && Key_Long1 >= 500))
{
if(Seg_Dis_Mode == 2)
Adjust_Parameter(-1); // -1
}
节省:70行 → 25行(减少64%)
重构4: 闪烁逻辑优化
原代码
if(Flag_2)
{
if(Temperature_Setting_Index == 0)
{
Seg_Buf[2] = 10;
Seg_Buf[3] = 10;
}
if(Temperature_Setting_Index == 2)
{
Seg_Buf[4] = 10;
Seg_Buf[5] = 10;
}
}
优化后(数组索引计算)
// 改用0/1索引
unsigned char Parameter_Index; // 0或1,不再是0/2
// 按键13切换
Parameter_Index ^= 1; // 0↔1切换
// 闪烁逻辑
if(Flag_2)
{
Seg_Buf[2 + 2*Parameter_Index] = 10;
Seg_Buf[3 + 2*Parameter_Index] = 10;
}
节省:12行 → 4行(减少67%)
优化效果总结
| 函数/模块 | 原代码行数 | 优化后行数 | 减少比例 |
|---|---|---|---|
| Led_Proc | 34行 | 8行 | 76% ↓ |
| Clear_Input | 42行(重复3次) | 13行 | 69% ↓ |
| 参数调整 | 70行 | 25行 | 64% ↓ |
| 闪烁逻辑 | 12行 | 4行 | 67% ↓ |
| 总计 | 158行 | 50行 | 68% ↓ |
预计总优化:451行 → 约300行(减少33%)
注意事项
1. 可读性优先原则
// ❌ 过度优化,难以理解
x = (a & b) | (~a & c);
// ✅ 清晰表达
if(a)
x = b;
else
x = c;
2. 避免过度使用宏
// ❌ 危险的宏
#define SQUARE(x) x * x
SQUARE(a + b); // 展开为 a + b * a + b(错误!)
// ✅ 安全的宏
#define SQUARE(x) ((x) * (x))
SQUARE(a + b); // 展开为 ((a + b) * (a + b))
// ✅ 更好:使用内联函数
INLINE unsigned int Square(unsigned int x)
{
return x * x;
}
3. 性能vs可读性权衡
// 高可读性(推荐)
ucLed[0] = (Temperature_Data > TMAX);
// 高性能但晦涩(仅在关键路径使用)
ucLed[0] = Temperature_Data / (TMAX + 1);
4. 团队协作考虑
- 简洁代码需要团队统一风格
- 注释说明复杂技巧
- 代码审查时验证可读性
学习路径
初级(立即可用)
布尔表达式赋值
三元运算符
提前返回
宏定义常量
中级(理解后使用)
位运算优化
数组索引计算
函数封装
查找表
高级(谨慎使用)
复杂位运算表达式
函数指针表
嵌套三元运算符
宏函数
推荐实践
第1步:优化你的Led_Proc
// 立即改进,减少76%代码
void Led_Proc()
{
ucLed[0] = (Temperature_Data > TMAX);
ucLed[1] = (Temperature_Data >= TMIN) && (Temperature_Data <= TMAX);
ucLed[2] = (Temperature_Data < TMIN);
ucLed[3] = Data_Error;
Led_Level = (Temperature_Data > TMAX) ? 3 :
(Temperature_Data >= TMIN) ? 6 : 9;
}
第2步:封装Clear_Input函数
void Clear_Input(void)
{
unsigned char i;
Temperature_Input_Index = 0;
Num_Input = 0;
Point_Input = 0;
for(i = 0; i < 3; i++)
{
Temperature_Real[i] = 0;
Temperature_Input_Point[i] = 0;
Temperature_Input[i] = 13;
}
}
第3步:添加宏定义
#define TEMP_MAX 85
#define TEMP_MIN 0
#define PARAM_MAX 70
#define PARAM_MIN 10
#define KEY_POINT 11
#define KEY_MODE 12
#define KEY_PARAM 13
#define KEY_ADD 14
#define KEY_SUB 15
#define KEY_CONFIRM 16
总结
代码简洁性的黄金法则
- 消除重复:提取公共代码为函数
- 直接表达:布尔值直接赋值,不用if-else
- 利用运算符:三元运算符、位运算
- 优化结构:数组索引计算替代条件判断
- 宏定义常量:消除魔法数字
- 提前返回:减少嵌套层级
- 平衡权衡:简洁但不失可读性
实战检查清单
- 是否有重复代码可以提取为函数?
- if-else赋值0/1能否改为布尔表达式?
- 是否使用了魔法数字?
- 条件判断能否用三元运算符?
- 多个if能否改为switch-case?
- 循环是否可以合并?
- 数组操作能否用memset?
- 变量命名是否语义化?
文档创建时间:2026-01-31
适用场景:51单片机嵌入式C编程
难度等级:初级 → 高级
预期效果:代码减少30-50%,可读性保持或提升