C 比“如果”更好的解决方案?
我必须根据一个大数字的值做一些事情,比如83025(大于65535)。为此,我不能使用switch case,因为它只使用最大值为255的整型参数。(或者至少我是这样知道的。我仍然尝试过,但是它编译了,但是switch案例没有很好地工作。) 所以我想我会做一个C 比“如果”更好的解决方案?,c,embedded,C,Embedded,我必须根据一个大数字的值做一些事情,比如83025(大于65535)。为此,我不能使用switch case,因为它只使用最大值为255的整型参数。(或者至少我是这样知道的。我仍然尝试过,但是它编译了,但是switch案例没有很好地工作。) 所以我想我会做一个if-else-if梯子,像下面这样,但看起来不太优雅 if ((refnum == 32120) || (refnum == 32075)) { else if (refnum == 51036)
if-else-if
梯子,像下面这样,但看起来不太优雅
if ((refnum == 32120) ||
(refnum == 32075)) {
else if (refnum == 51036) {
else if ((refnum == 61024) ||
(refnum == 61060)) {
else if ((refnum == 71030) ||
(refnum == 71048)) {
else if ((refnum == 72012) ||
(refnum == 72024) ||
(refnum == 72048)) {
else if ((refnum == 81025) ||
(refnum == 81050) ||
(refnum == 81100)) {
else if ((refnum == 82012) ||
(refnum == 82024) ||
(refnum == 82048) ||
(refnum == 82096)) {
else if ((refnum == 83050) ||
(refnum == 83100)) {
你能确认这是正确的方法吗?还是你有更好的主意
其他信息:
- refnum是32位无符号整数
- 大数字来自字符串的中间,并且
将其转换为DWORDstrtol
- 在每种情况下,我必须执行
,然后strcpy
返回一个特定的值
- 代码嵌入并在16位微控制器上运行
- 在这种情况下,Switch语句可以为您完成这项工作
switch (refnum) {
case 0:
case 1:
//Do stuff when refnum is 0 or 1
break;
case 2:
//Do stuff when refnum is 2
break;
case 36371:
case 36372:
case 36373:
case 36374:
// if (refnum == 36371 || refnum == 36372 || refnum == 36373 || refnum == 36374)
break;
default: break;
}
美妙之处在于,您可以在if语句中应用多个case语句(如我的例子中的case 0
和case 1
),它们的作用类似于或
GCC扩展还允许您以以下方式编写交换机:
switch (refnum) {
case 36371 ... 36374:
//Do the job when refnum is >= 36371 && refnum <= 36374
break;
}
开关(refnum){
判例36371…36374:
//当refnum>=36371&&refnum时执行此操作。您可以创建一个全局数组,其中包含要检查的所有值。只需循环设置此数组。如果您需要为每个数组指定特定行为,请创建一个结构数组并使用函数指针设置不同的行为
下面是一个例子:
// For int variables
#include <stdint.h>
// For printf
#include <stdio.h>
#define VALUE_TO_GUESS 3
#define NB_VALUES 4
#define MY_VALUE_1 1
#define MY_VALUE_2 2
#define MY_VALUE_3 3
#define MY_VALUE_4 4
void behavior_1(void) {
printf("Behavior 1 !\n");
}
void behavior_2(void) {
printf("Behavior 2 !\n");
}
void behavior_3(void) {
printf("Behavior 3 !\n");
}
void behavior_4(void) {
printf("Behavior 4 !\n");
}
// Definition of the struct using a function pointer
typedef struct s_compare {
uint32_t value_to_compare;
void (*ptr)(void);
}t_compare;
// Setting up my struct
t_compare g_compare[] = {
{MY_VALUE_1, behavior_1},
{MY_VALUE_2, behavior_2},
{MY_VALUE_3, behavior_3},
{MY_VALUE_4, behavior_4}
};
int main(void) {
for (int i = 0; i < NB_VALUES; i++) {
/* If your current value match the value set in the current struct
then call the function pointer associated, with these 2 lines i can
compare an infinite quantity of numbers */
if (g_compare[i].value_to_compare == VALUE_TO_GUESS) {
g_compare[i].ptr();
}
}
}
//用于int变量
#包括
//用于printf
#包括
#定义值_至_猜测3
#定义NB_值4
#定义我的\u值\u 1
#定义我的\u值\u 2
#定义我的\u值\u 3
#定义我的\u值\u 4
无效行为_1(无效){
printf(“行为1!\n”);
}
空洞行为_2(空洞){
printf(“行为2!\n”);
}
空洞行为_3(空洞){
printf(“行为3!\n”);
}
空洞行为_4(空洞){
printf(“行为4!\n”);
}
//使用函数指针定义结构
类型定义结构s_比较{
uint32\u t值要进行比较;
无效(*ptr)(无效);
}比较;
//设置我的结构
t_compare g_compare[]={
{MY_VALUE_1,behavior_1},
{MY_VALUE_2,behavior_2},
{MY_VALUE_3,behavior_3},
{MY_VALUE_4,behavior_4}
};
内部主(空){
对于(int i=0;i
如果你需要关于这个的解释,请随时告诉我。
这需要一点设置,但它是解决问题的强大解决方案,而且比if/else/else-if树更优雅
必须根据一个大数字的值做一些事情,比如83025
然后确保所有涉及的变量都使用uint32\u t
为此,我不能使用switch case,因为它只使用最大值为255的整数参数
这是一个误解,不知道你是从哪里得到这个想法的。switch
语句适用于所有整数常量表达式。switch语句本身没有数字限制
(实际上,switch语句的控制表达式被隐式提升为int
,如果它恰好是较小的整数类型。)
所以我想我会做一个像下面这样的“如果-如果-如果-如果”梯子,但它看起来不太优雅。你能确认这是正确的方法吗?或者你有更好的主意吗
if-else可能会产生与相应开关相同的机器代码。该开关可能会稍微增加可读性,因此可能是更好的选择:
switch (refnum)
{
case 32120: do_this(); break;
case 61024: do_that(); break;
...
default: do_something();
}
备选方案:
我注意到这些是按排序的整数值。如果有很多值或需要快速查找,也可以用二进制搜索来代替整个搜索。这可能会加快代码速度,但也会增加复杂性。最好使用C标准bsearch()
但是,如果您希望最终实现的是返回字符串指针,则此解决方案可能是理想的。然后,您可以将数字和字符串存储为键值对:
typedef struct
{
uint32_t key;
const char* str;
} thingie_t;
static const thingie_t things [] =
{
{ 32120, "text string" },
{ 32075, "another text string" },
...
};
大数字来自字符串的中间,strtol将其转换为DWORD
为什么要使用有符号的数字?数据似乎没有符号。什么是DWORD?DWORD
?这是Windows编程中的一些难闻的类型,在嵌入式系统中绝对应该避免。使用stdint.h中的类型,而不是一些丑陋的自制类型
我必须根据一个大数字的值做一些事情,比如83025(大于65535)。为此,我不能使用switch case,因为它只使用最大值为255的整数参数(或者至少我是这样知道的)
您的理解不正确:以下是C标准的措辞:
6.8.4.2开关
语句
switch语句的控制表达式应为整数类型
[…]每个case
标签的表达式应为整数常量表达式,同一switch
语句中的case
常量表达式在转换后不得有相同的值。[…]
对控制表达式执行整数提升。每个大小写
标签中的常量表达式转换为控制表达式的提升类型。如果转换后的值与提升后的控制表达式的值匹配,则控制跳到匹配的大小写
标签后面的语句。[…]
因此,一般情况下,案例值在65535
处没有限制,最大值至少为18446744073709551615int action1( unsigned long refnum ) ;
int action2( unsigned long refnum ) ;
int action3( unsigned long refnum ) ;
int action4( unsigned long refnum ) ;
int action5( unsigned long refnum ) ;
...
int action8( (unsigned long ) ;
int doRefnumAction( unsigned long refnum )
{
typedef void(*refnumFn)(unsigned long ) ;
static const struct
{
unsigned long refnum,
refnumFn refnum_action
} refnum_lookup[] = { {32120, action1}, {32075, action1},
{51036, action2},
...
{82012, action7}, {82024, action7}, {82048, action7}, {82096, , action7},
{83050, action8}, {83100, action8} } ;
// Find refnum in lookup and call action...
for( int i = 0 ;
i < sizeof(refnum_lookup) / sizeof(*refnum_lookup) ;
i++ )
{
if( refnum == refnum_lookup[i].refnum )
{
return refnum_lookup[i].refnum_action( refnum ) ;
}
}
}