如何将char数组中的位操作字符串转为uint8_t无符号整数?
解决思路:从固定字符数组映射到位操作读取逻辑
首先明确你的核心需求:不能修改现有的switch_list字符数组,但要创建一个对应数组,能在for循环中通过索引直接获取对应PIN寄存器的位值。因为C语言没办法直接把字符串形式的代码转换成可执行的表达式(嵌入式场景也不适合动态解析),所以我们需要手动建立字符串和对应位操作的映射,而且因为PINB/PIND是实时硬件寄存器,每次都要读取当前值,所以不能预存结果,得用函数指针来封装每个位操作。
现有代码回顾
你的原始代码和目标循环结构如下:
原始判断逻辑
char switch_list[] = { "PINB >> 7", "PIND >> 1", "PINB >> 1", "PIND >> 0" }; void values(void){ uint8_t switch_value = 0; if (i == 0){ switch_value = (PINB >> 7) & 1; } if (i == 1){ switch_value = (PIND >> 1) & 1; } if (i == 2){ switch_value = (PINB >> 1) & 1; } if (i == 3){ switch_value = (PIND >> 0) & 1; } // SOME OTHER OPERATIONS GO HERE }
目标循环结构
uint8_t switch_value = 0; for (int i = 0; i < sizeof(switch_list)/sizeof(switch_list[0]); i++){ switch_value = **********[i] & 1; // SOME OTHER OPERATIONS GO HERE }
具体解决方案
方案1:函数指针数组(最贴合你的需求)
我们可以创建一个函数指针数组,每个指针指向一个封装了对应位操作的函数,这样就能像你期望的那样通过索引调用,获取实时的寄存器位值:
// 第一步:定义函数指针类型,指向返回uint8_t、无参数的函数 typedef uint8_t (*SwitchReader)(void); // 第二步:实现每个对应位操作的读取函数 static uint8_t read_pinb_bit7(void) { return (PINB >> 7) & 1; } static uint8_t read_pind_bit1(void) { return (PIND >> 1) & 1; } static uint8_t read_pinb_bit1(void) { return (PINB >> 1) & 1; } static uint8_t read_pind_bit0(void) { return (PIND >> 0) & 1; } // 第三步:创建和switch_list严格对应的函数指针数组 SwitchReader switch_readers[] = { read_pinb_bit7, read_pind_bit1, read_pinb_bit1, read_pind_bit0 }; // 第四步:在循环中使用 void values(void) { uint8_t switch_value = 0; // 注意:确保switch_readers的长度和switch_list一致 for (int i = 0; i < sizeof(switch_readers)/sizeof(switch_readers[0]); i++){ // 调用对应函数获取实时位值 switch_value = switch_readers[i](); // SOME OTHER OPERATIONS GO HERE } }
这个方案里,switch_readers就是你要的**********数组,只不过它存的是函数指针,调用后会返回你需要的(XX >> N) & 1结果。
方案2:结构体关联(可选,用于验证匹配)
如果担心switch_list和switch_readers的顺序错配,可以用结构体把字符串和函数指针绑定,还能在调试时验证对应关系:
typedef struct { const char* expr_str; uint8_t (*read_func)(void); } SwitchConfig; SwitchConfig switch_configs[] = { {"PINB >> 7", read_pinb_bit7}, {"PIND >> 1", read_pind_bit1}, {"PINB >> 1", read_pinb_bit1}, {"PIND >> 0", read_pind_bit0} }; void values(void) { uint8_t switch_value = 0; for (int i = 0; i < sizeof(switch_configs)/sizeof(switch_configs[0]); i++){ // 调试时可以验证字符串是否匹配,防止顺序错误 if (strcmp(switch_list[i], switch_configs[i].expr_str) == 0) { switch_value = switch_configs[i].read_func(); } // SOME OTHER OPERATIONS GO HERE } }
关键注意事项
- 严格对应顺序:必须保证你创建的数组(函数指针数组或结构体数组)的元素顺序和
switch_list完全一致,因为你不能修改原数组。 - 实时读取:因为PINB/PIND是硬件寄存器,每次读取的是当前状态,所以不能把计算结果预存在数组里,必须用函数每次实时读取。
内容的提问来源于stack exchange,提问作者david_10001
相关产品推荐
相关产品推荐

