一个函数超过1000行?

今天维护公司的一个老产品,因为要清库存,有一些bug需要修复,开发这个产品的那些同事早已不知去向,查了下git上的提交log,开发过这个产品的有好几个人呢,本来就是在炬芯方案上做的二次开发,现在到我这不知道几手了。。。

有问题,那就查代码改呗,不看不知道,一看吓一跳,什么牛鬼蛇神写的,全局变量满天飞,一个函数动辄几百行,还没什么注释,更有好些函数是上千行的,我倒是不奇怪,几年前我就领教过上1000行一个函数的代码,逻辑重复混乱,TM谁写的,真想揪出来让他把它吃掉。。。

一般我们宁可自己写也不愿意去维护别人写的代码,就是怕碰到这种情况,更有甚者,昨天写的程序,今天就想不起为何要这么写,让另外的人去维护,如何看得懂?

写代码,不说要写的多么多么的优美,但一个函数写短一点能做到吧,一个函数,一个功能,一个逻辑,层次分明,结构清晰,才有利于代码的可读性、可维护性、可移植性,不需要什么注释别人也能看懂,这才是我们写代码应该追求的。

<think> 我们一解释每个函数的作用。注意,由于代码较长,我们将按照函数逐个进详细解释。每个函数的每一代码都会给出解释。 1. 函数:s4_g_led_transformInput 作用:将输入的8位无符号整数(0-255)转换为一个带符号的32位整数(固定点格式),转换公式为:result = input * multiplier - subtractor。 代码解释: S4 s4_g_led_transformInput(U1 u1_a_input_value) { S4 s4_t_trans_result; // 定义一个S4类型(32位有符号整数)的变量,用于存放转换结果 s4_t_trans_result = (S4)u1_a_input_value * (S4)LED_MULTIPLIER - (S4)LED_SUBTRACTOR; // 转换公式:输入值乘以一个乘数,再减去一个减数 return s4_t_trans_result; // 返回转换结果 } 2. 函数:u1_g_led_determineLedCount 作用:根据转换后的输入值(s4_a_TRANS_value)和当前方向(b_a_direction)以及上一次的LED数量(u1_a_last_led_count)来确定当前要点亮的LED数量(0-8)。 代码解释: U1 u1_g_led_determineLedCount(S4 s4_a_TRANS_value, bool b_a_direction, U1 u1_a_last_led_count) { U1 u1_t_led_count; // 定义变量,用于存储最终要返回的LED数量 // 如果上一次的LED数量非0,则从该值开始(但实际上下面的条件判断会覆盖,这里可能是为了初始化,但逻辑上并不需要这样) if (u1_a_last_led_count) { u1_t_led_count = u1_a_last_led_count; // 将上一次的LED数量作为初始值 } else { u1_t_led_count = (U1)DATAZERO; // 如果上一次是0,则初始化为0 } // 判断当前方向(上升或下降) if (b_a_direction) // 如果方向为上升(true) { // 使用一系列的阈值(UP_THRESHOLD_0到UP_THRESHOLD_8)来比较转换后的值,以确定LED数量 if (s4_a_TRANS_value < (S4)UP_THRESHOLD_0) { u1_t_led_count = (U1)DATAZERO; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_1) { u1_t_led_count = (U1)DATAONE; } // ... 中间类似,省略 else if (s4_a_TRANS_value <= (S4)UP_THRESHOLD_8) { u1_t_led_count = (U1)DATAEIGHT; } else { // 如果值超过最大阈值,则保持上一次的状态(通过打印提示) printf("Unsigned range, the light status remains in the previous state.\n"); // 注意:这里没有改变u1_t_led_count,所以它仍然保持为上一次的初始值(即上次的LED数量) } } else // 方向为下降(false) { // 使用下降方向的阈值(DOWN_THRESHOLD_1到DOWN_THRESHOLD_8) if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_8) { u1_t_led_count = (U1)DATAEIGHT; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_7) { u1_t_led_count = (U1)DATASEVEN; } // ... 中间类似,省略 else { u1_t_led_count = (U1)DATAZERO; } } return u1_t_led_count; // 返回计算得到的LED数量 } 3. 函数:u1_g_led_generateLedStates 作用:根据要点亮的LED数量(u1_a_led_count)生成一个8位的LED状态掩码,每一位代表一个LED的亮灭状态。 代码解释: U1 u1_g_led_generateLedStates(U1 u1_a_led_count) { U1 u1_t_generate_result; // 定义一个8位无符号整数,用于存储生成的掩码 u1_t_generate_result = (U1)DATAZERO; // 初始化为0,即所有LED熄灭 // 如果要点亮的数量大于等于LED总数(8个),则全部点亮 if (u1_a_led_count >= (U1)NUM_LEDS) { u1_t_generate_result = (U1)LED_ALL_ON_MASK; // 赋值全亮掩码(0xFF) } // 如果要点亮的数量在1到7之间 else if (u1_a_led_count > (U1)DATAZERO) { // 生成一个掩码:低u1_a_led_count位为1,其余为0 // 方法:将1左移u1_a_led_count位,然后减1。例如,u1_a_led_count=3: (1<<3) = 0x08, 减1得0x07(二进制00000111) u1_t_generate_result = ((U1)DATAONE << u1_a_led_count) - (U1)DATAONE; } else // 数量为0 { u1_t_generate_result = (U1)DATAZERO; // 全部熄灭 } return u1_t_generate_result; // 返回状态掩码 } 4. 函数:b_g_hyst_determineDirection 作用:根据当前转换值(s4_a_TRANS_value)和状态机(stp_a_STATE)确定当前的方向(上升或下降)。 代码解释: bool b_g_hyst_determineDirection(S4 s4_a_TRANS_value, VALUESTATEMACHINE* stp_a_STATE) { bool b_t_determine_result; // 存储最终确定的方向 S4 s4_t_value_difference; // 当前值与上一次值的差值 S4 s4_t_abs_diff; // 差值的绝对值 // 计算当前值和状态机中记录的上一次值的差值 s4_t_value_difference = s4_a_TRANS_value - stp_a_STATE->s4_t_hyst_last_value; // 计算绝对值:如果差值大于0则取原值,否则取相反数 s4_t_abs_diff = (s4_t_value_difference > (S4)DATAZERO) ? s4_t_value_difference : -s4_t_value_difference; // 判断绝对值是否超过滞回阈值 if (s4_t_abs_diff >= (S4)HYSTERESIS_THRESHOLD) { // 如果超过阈值,则根据差值的正负确定方向:非负为上升(1),负为下降(0) b_t_determine_result = (s4_t_value_difference >= (S4)DATAZERO) ? (bool)DATAONE : (bool)DATAZERO; } else { // 变化未超过阈值,保持状态机中记录的上一次方向 b_t_determine_result = stp_a_STATE->b_t_hyst_lsb_direction; printf("Did not reach the threshold of change, maintain the original state.\n"); } return b_t_determine_result; // 返回方向 } 5. 函数:vd_Output_Led_Light_Ctl 作用:主控制函数,处理输入值并更新LED状态。 代码解释: void vd_Output_Led_Light_Ctl(VALUESTATEMACHINE* stp_a_STATE, U1 u1_a_input_value) { // 声明多个局部变量,用于存储中间结果 S4 s4_t_trans_value; // 转换后的值 bool b_t_curr_direction; // 当前方向 bool b_t_is_led_on; // 临时变量,表示某个LED是否亮 S1P s1p_t_curr_state; // 字符串指针,用于表示方向("UP"或"DOWN") U1 u1_t_led_count; // LED数量 U1 u1_t_led_states; // LED状态掩码 S4 s4_t_trans_integer; // 转换值的整数部分 S4 s4_t_trans_decimal; // 转换值的小数部分(放大100倍后的整数形式) U1 u1_t_process_index; // 循环索引 U1 u1_t_led_maskid; // 用于生成LED掩码的临时变量 // 步骤1:转换输入值 s4_t_trans_value = s4_g_led_transformInput(u1_a_input_value); // 步骤2:确定方向 b_t_curr_direction = b_g_hyst_determineDirection(s4_t_trans_value, stp_a_STATE); // 步骤3:确定要点亮的LED数量 u1_t_led_count = u1_g_led_determineLedCount(s4_t_trans_value, b_t_curr_direction, stp_a_STATE->u1_t_last_led_count); // 步骤4:生成LED状态掩码 u1_t_led_states = u1_g_led_generateLedStates(u1_t_led_count); // 更新状态机中的值:记录当前转换值、方向和LED数量 stp_a_STATE->s4_t_hyst_last_value = s4_t_trans_value; stp_a_STATE->b_t_hyst_lsb_direction = b_t_curr_direction; stp_a_STATE->u1_t_last_led_count = u1_t_led_count; // 将转换后的值拆分为整数和小数部分(用于显示) // 整数部分:除以缩放因子(例如100,假设LED_MULTIPLIER是10,那么这里可能是1000?但代码中用SCALE_FACTOR) // 注意:原转换值可能是整数,但为了显示两位小数,这里除以100(SCALE_FACTOR可能是100) s4_t_trans_integer = s4_t_trans_value / (S4)SCALE_FACTOR; // 小数部分:取绝对值后对缩放因子取模,再取绝对值是为了避免负数取模问题 s4_t_trans_decimal = (s4_t_trans_value < (S4)DATAZERO ? -s4_t_trans_value : s4_t_trans_value) % (S4)SCALE_FACTOR; // 根据方向设置字符串 s1p_t_curr_state = b_t_curr_direction ? "UP" : "DOWN"; // 打印LED状态:通过循环检查每一位,输出LED状态(亮'*',灭'.') printf("LED STATE: "); for (u1_t_process_index = (U1)DATAZERO; u1_t_process_index < (U1)NUM_LEDS; u1_t_process_index++) { u1_t_led_maskid = (U1)DATAONE << u1_t_process_index; // 生成当前LED的掩码位(1<<index) b_t_is_led_on = u1_t_led_states & u1_t_led_maskid; // 检查该位是否为1 putchar(b_t_is_led_on ? (S1)LED_TURN_ON : (S1)LED_TURN_OFF); // 根据状态输出字符(如'*'或'.') } // 打印LED状态掩码的十六进制值 printf(" (0x%02X)\n", u1_t_led_states); // 打印详细处理信息:输入值,转换后的值(带小数),方向,LED数量 printf("INPUT: %3u -> TRANS: %ld.%02ld (%s) -> LED COUNT: %u\n\n", u1_a_input_value, s4_t_trans_integer, s4_t_trans_decimal, s1p_t_curr_state, u1_t_led_count); } 注意:以上代码中使用的数据类型(如U1, S4)可能是通过typedef定义的,例如: typedef unsigned char U1; typedef signed long S4; 常量(如LED_MULTIPLIER, LED_SUBTRACTOR, UP_THRESHOLD_0等)可能在头文件中定义。 总结:整个模块实现了带滞回控制的LED亮度显示(用LED数量模拟亮度级别),通过状态机保存历史状态,避免在阈值附近抖动。 §§相关问题§§: 1. 在函数`u1_g_led_determineLedCount`中,为什么在上升方向中使用了`<`比较而在下降方向中使用了`>`比较? 2. 函数`u1_g_led_generateLedStates`中,当LED数量为0时返回0,当数量大于等于8时返回0xFF,为什么在1到7之间使用`(1 << N) - 1`来生成掩码? 3. 在滞回方向判断函数`b_g_hyst_determineDirection`中,为什么需要计算差值的绝对值? 4. 主函数`vd_Output_Led_Light_Ctl`中,将转换后的值拆分成整数和小数部分显示,这里为什么要使用取绝对值的操作? </think> ### 函数详解 #### 1. `s4_g_led_transformInput()` 函数 ```c S4 s4_g_led_transformInput(U1 u1_a_input_value) { S4 s4_t_trans_result; // 定义转换结果变量 s4_t_trans_result = (S4)u1_a_input_value * (S4)LED_MULTIPLIER - (S4)LED_SUBTRACTOR; // 执缩放变换 return s4_t_trans_result; // 返回转换结果 } ``` - **1**:声明32位有符号整型变量存储转换结果 - **2**:执线性变换 `y = kx - b`,将[0,255]映射到目标范围 - **3**:返回转换后的值 #### 2. `u1_g_led_determineLedCount()` 函数 ```c U1 u1_g_led_determineLedCount(S4 s4_a_TRANS_value, bool b_a_direction, U1 u1_a_last_led_count) { U1 u1_t_led_count; // 定义LED计数变量 // 初始化逻辑(防抖动) if (u1_a_last_led_count) { u1_t_led_count = u1_a_last_led_count; // 使用上次值初始化 } else { u1_t_led_count = (U1)DATAZERO; // 初始化归零 } // 上升方向阈值检测 if (b_a_direction) { if (s4_a_TRANS_value < (S4)UP_THRESHOLD_0) u1_t_led_count = (U1)DATAZERO; else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_1) u1_t_led_count = (U1)DATAONE; /* ... 中间6个阈值省略 ... */ else if (s4_a_TRANS_value <= (S4)UP_THRESHOLD_8) u1_t_led_count = (U1)DATAEIGHT; else printf("Unsigned range...\n"); // 超范围警告 } // 下降方向阈值检测 else { if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_8) u1_t_led_count = (U1)DATAEIGHT; else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_7) u1_t_led_count = (U1)DATASEVEN; /* ... 中间6个阈值省略 ... */ else u1_t_led_count = (U1)DATAZERO; // 最低阈值归零 } return u1_t_led_count; // 返回最终LED数量 } ``` - **4-9**:基于上次LED计数初始化,防止微小波动 - **11-21**:上升方向使用递增阈值序列检测 - **23-34**:下降方向使用递减阈值序列检测 - **35**:返回确定的LED数量 #### 3. `u1_g_led_generateLedStates()` 函数 ```c U1 u1_g_led_generateLedStates(U1 u1_a_led_count) { U1 u1_t_generate_result = (U1)DATAZERO; // 初始化为全0 // 全亮判断 if (u1_a_led_count >= (U1)NUM_LEDS) { u1_t_generate_result = (U1)LED_ALL_ON_MASK; // 设置全1掩码 } // 部分亮状态生成 else if (u1_a_led_count > (U1)DATAZERO) { u1_t_generate_result = ((U1)DATAONE << u1_a_led_count) - (U1)DATAONE; // 位掩码算法 } return u1_t_generate_result; // 返回LED状态掩码 } ``` - **2**:初始化LED状态为全灭(0x00) - **4-6**:处理全亮情况(0xFF) - **7-9**:核心算法 `(1<<N)-1` 生成低N位为1的掩码 - **11**:返回8位控制掩码 #### 4. `b_g_hyst_determineDirection()` 函数 ```c bool b_g_hyst_determineDirection(S4 s4_a_TRANS_value, VALUESTATEMACHINE* stp_a_STATE) { bool b_t_determine_result; // 方向结果变量 S4 s4_t_value_difference = s4_a_TRANS_value - stp_a_STATE->s4_t_hyst_last_value; // 计算差值 // 计算绝对差值(防溢出) S4 s4_t_abs_diff = (s4_t_value_difference > (S4)DATAZERO) ? s4_t_value_difference : -s4_t_value_difference; // 滞回阈值判定 if (s4_t_abs_diff >= (S4)HYSTERESIS_THRESHOLD) { // 超过阈值:根据差值符号更新方向 b_t_determine_result = (s4_t_value_difference >= (S4)DATAZERO); } else { // 未达阈值:维持原方向 b_t_determine_result = stp_a_STATE->b_t_hyst_lsb_direction; printf("Did not reach the threshold...\n"); // 滞回提示 } return b_t_determine_result; // 返回方向判定 } ``` - **4**:计算当前值与历史值的差值 - **6-7**:使用条件运算符避免abs()函数调用 - **10-16**:核心滞回逻辑,决定是否更新方向 - **17**:返回最终方向判定 #### 5. `vd_Output_Led_Light_Ctl()` 主控函数 ```c void vd_Output_Led_Light_Ctl(VALUESTATEMACHINE* stp_a_STATE, U1 u1_a_input_value) { // 数据转换 S4 s4_t_trans_value = s4_g_led_transformInput(u1_a_input_value); // 滞回方向判定 bool b_t_curr_direction = b_g_hyst_determineDirection(s4_t_trans_value, stp_a_STATE); // LED数量判定 U1 u1_t_led_count = u1_g_led_determineLedCount(s4_t_trans_value, b_t_curr_direction, stp_a_STATE->u1_t_last_led_count); // 生成LED状态掩码 U1 u1_t_led_states = u1_g_led_generateLedStates(u1_t_led_count); // 更新状态机历史值 stp_a_STATE->s4_t_hyst_last_value = s4_t_trans_value; stp_a_STATE->b_t_hyst_lsb_direction = b_t_curr_direction; stp_a_STATE->u1_t_last_led_count = u1_t_led_count; // 值分解(调试用) S4 s4_t_trans_integer = s4_t_trans_value / (S4)SCALE_FACTOR; S4 s4_t_trans_decimal = (s4_t_trans_value < (S4)DATAZERO ? -s4_t_trans_value : s4_t_trans_value) % (S4)SCALE_FACTOR; // 方向字符串(调试用) S1P s1p_t_curr_state = b_t_curr_direction ? "UP" : "DOWN"; // LED状态可视化输出 printf("LED STATE: "); for (U1 u1_t_process_index = 0; u1_t_process_index < (U1)NUM_LEDS; u1_t_process_index++) { U1 u1_t_led_maskid = (U1)DATAONE << u1_t_process_index; // 位掩码生成 bool b_t_is_led_on = u1_t_led_states & u1_t_led_maskid; // 状态检测 putchar(b_t_is_led_on ? '*' : '.'); // 可视化输出 } // 调试信息输出 printf(" (0x%02X)\n", u1_t_led_states); printf("INPUT: %3u -> TRANS: %ld.%02ld (%s) -> LED COUNT: %u\n\n", u1_a_input_value, s4_t_trans_integer, s4_t_trans_decimal, s1p_t_curr_state, u1_t_led_count); } ``` - **4-17**:完整处理流水线(转换→方向→计数→掩码) - **19-21**:状态机历史值更新 - **24-26**:值分解用于调试显示 - **29-35**:LED阵列可视化输出 - **38-41**:详细调试信息输出
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东皇※太一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值