c语言 - 如何改进此代码?我不喜欢放那么多如果



我有以下代码,但我觉得很脏。

我不喜欢写那么多if,然后在每个if中放置重复的代码。

关于如何改进此代码的任何想法?

char obj[5];
strlcpy(obj, &jarr[i], arr[i]);
if( !strcmp( obj, "led_r" ) ){
    i++;
    strlcpy( obj, &jarr[i], arr[i] );
    red_brightness = atoi( obj );
    Serial.print(" RED: ");
    Serial.println( red_brightness );
}
if( !strcmp( obj, "led_g" ) ){
    i++;
    strlcpy( obj, &jarr[i], arr[i] );
    green_brightness = atoi( obj );
    Serial.print(" GREEN: ");
    Serial.println( green_brightness );
}
if( !strcmp( obj, "led_b" ) ){
    i++;
    strlcpy( obj, &jarr[i], arr[i] );
    blue_brightness = atoi( obj );
    Serial.print(" BLUE: ");
    Serial.println( blue_brightness );
}

在此之前的其他答案也很好。 这个答案的优点是您可以将选项名称更改为任何内容,并且它仍然有效。 您还可以将这种选项分析扩展到更大的选项集。

// Assuming these are globals.
int red_brightness, green_brightness, blue_brightness;
// Use this array to help you parse.
static const struct {
    const char *optionName;
    int        *brightness;
    const char *label;
} ledOptions[] = {
    { "led_r", &red_brightness,   " RED: "   },
    { "led_g", &green_brightness, " GREEN: " },
    { "led_b", &blue_brightness,  " BLUE: "  },
};
// A handy macro for later.
#define DIM(array)  (sizeof(array) / sizeof(array[0]))
...
// Now in your actual code:    
strlcpy(obj, &jarr[i], arr[i]);
for (j=0;j<DIM(ledOptions);j++) {
    if( !strcmp( obj, ledOptions[i].optionName ) ){
        i++;
        strlcpy( obj, &jarr[i], arr[i] );
        *ledOptions[i].brightness = atoi( obj );
        Serial.print(ledOptions[i].label);
        Serial.println(*ledOptions[i].brightness);
    }
}

将前 4 个字符与"led_"进行比较,确保它的长度为 5,然后打开第五个字符。将代码的其余部分重构为函数。

公共代码可以从 if 语句中分解出来

您可以将 switch 语句用于字符串中唯一更改的字符

switch(obj[4]) {
    case 'r':
        Serial.println("RED: " + red_brightness );
    case 'g':
        Serial.println("GREEN: " + green_brightness );
    case 'b':
        Serial.println("BLUE: " + blue_brightness );
}

这就是我想出的。免责声明,我没有尝试编译/运行它。

for (int i=0; i<6; i++)
{
   i++;
   int b = atoi( &jarr[i] );
   switch (i)
   {
     case 1:
        Serial.print(" RED: ");
        red_brightness = b;
        break;
     case 3: 
        Serial.print(" GREEN: ");
        green_brightness = b;
        break;
     case 5:
        Serial.print(" BLUE: ");
        blue_brightness = b;
        break;
     default:
        break;
   }
   Serial.println(b);
}

这个想法是,您要打印的值位于奇数索引处的 &jarr[] 中。

只是为了好玩,我个人的方法...

#ifndef ARDUINO
#include <string.h>
#include <stdio.h>
/* PART of code derived from question but unspecified in code . done to be able to compile */
// this is not specified in question 
//   either it a char jarr[1024] but then why do we iterate on char ( i++ would go to next char and not to next word )
//   either it is a char* jar[6] but then we access its char * content with jarr[i] and not with &jarr[i]
//char * jarr[6];
// this look like to be size of each argument.
//int arr[6];
/*
TEST vectors
 */
char * jarr0[] = { "led_r", "200", "led_g", "100", "led_b", "150" };
int arr0[] = { 5, 3, 5,3, 5,3 };
char * jarr1[] = { "led_g", "200", "led_r", "100", "led_b", "150" };
int arr1[] = { 5, 3, 5,3, 5,3 };
char * jarr2[] = { "lgd_g", "200", "ged_r", "100", "led_b", "150" };
int arr2[] = { 5, 3, 5,3, 5,3 };
int red_brightness = 0;
int blue_brightness = 0;
int green_brightness = 0;
/* end of unspecified PART */
#endif
/*real code *
/* use indirection */
struct led_color_map {
  int * color_brightness_p;
  const char * color_name;
  char key;
} led_color[] = {
  {&red_brightness,"RED",'r'},
  {&green_brightness,"GREEN",'g'},
  {&blue_brightness,"BLUE",'b'}
};

enum { RED_IDX=0, GREEN_IDX, BLUE_IDX };
// for perf test
int miss = 0;
#ifdef ARDUINO
void led_setup()
#else
  void led_setup(char * jarr[], int arr[])
#endif
{
  char* obj=NULL;
  int i=0;
  int offset=0;
  for (i=0; i <6; i+=2)
    {
      obj=jarr[i];
      // test 'led_' prefix with reverse statistical letter apparence
      // which is 'l' then 'd' then 'e' , guessing that '_' can be used in other words ... 
      if ( ( obj[0] == 'l' ) && ( obj[2] == 'd' ) && (obj[1] == 'e' ) && (obj[3] == '_') )
    {
      int idx=0;
      for ( idx = 0; idx <= BLUE_IDX; idx ++)
        {
          int rolling_idx = (idx + offset) % ( BLUE_IDX + 1 );
          struct led_color_map * color_found = &led_color[rolling_idx]; 
          if ( color_found->key == obj[4] )
        {
          char ivalue[32];
          if ( arr[i+1] < sizeof(ivalue) )
            {
              #ifdef ARDUINO
              strlcpy(ivalue, jarr[i+1], arr[i+1]);
              #else
              strncpy(ivalue, jarr[i+1], arr[i+1]);
              #endif
              {
            int brightness = atoi( ivalue );
            *(color_found->color_brightness_p) = brightness;
            #ifdef ARDUINO
            Serial.print( color_found->color_name );
            Serial.println( *color_brightness );
            #else
            printf(" %s :%in", color_found->color_name, brightness);
            #endif
              }
              offset=(rolling_idx + 1) % ( BLUE_IDX + 1 ); // try with next color first next time.
              break;
            }
        }
          else
        {
          miss ++;
          printf("miss %i wrong color order expected %sn",miss, led_color[rolling_idx].color_name);
        }
        }     
    }
      else
    {
      miss ++;
      printf("miss %i wrong variable expected led_%cn", miss, led_color[offset % ( BLUE_IDX + 1 )].key);
    }
    }
}
#ifndef ARDUINO
int main(int argc, char ** argv)
{
led_setup(jarr0, arr0);
 printf("test0 : miss %in",miss);
miss=0;
led_setup(jarr1, arr1);
 printf("test1 : miss %in",miss);
miss=0;
led_setup(jarr2, arr2);
 printf("test2 : miss %in",miss);
}
#endif

GCC Led.C./a.out

 RED :200
 GREEN :100
 BLUE :150
test0 : miss 0
miss 1 wrong color order expected RED
 GREEN :200
miss 2 wrong color order expected BLUE
 RED :100
miss 3 wrong color order expected GREEN
 BLUE :150
test1 : miss 3
miss 1 wrong variable expected led_r
miss 2 wrong variable expected led_r
miss 3 wrong color order expected RED
miss 4 wrong color order expected GREEN
 BLUE :150
test2 : miss 4
char obj[5];
strlcpy(obj, &jarr[i], arr[i]);
int *brightness;
String ostr();
if( !strcmp( obj, "led_r" ) ){
 ostr = " RED: ";
 brightness = red_brightness;
}
if( !strcmp( obj, "led_g" ) ){
 ostr = " GREEN: ";
 brightness = green_brightness;
}
if( !strcmp( obj, "led_b" ) ){
 ostr = " BLUE: ";
 brightness = blue_brightness;
}
i++;
strlcpy( obj, &jarr[i], arr[i] );
*brightness = atoi( obj );
Serial.print(ostr);
Serial.println(*brightness);

最新更新