如何最小化 if 和 else 语句

How to minimize the if and else statement

如何最小化 if 和 else 语句。原代码在这里:

    void decode (unsigned char* msg,unsigned char* msg2) {

        int result[12]; // Store values
        int a = 0; // start from UI0-UI4
        unsigned char lala[50]   ;


            for (a = 0; a < 13; a++)
            {
                AD1CHS0bits.CH0SA = a;  //select UI01 until UI12
                AD1CHS0bits.CH0NA = 0;  //vref as channel 0 -ve input
                AD1CON1bits.ADON = 1;   // 1, A/D Converter module is operating
                AD1CON1bits.SAMP = 1;   //Sampling
                __delay32(50);          // delay after sampling
                AD1CON1bits.SAMP = 0;   //sampling bit to 0
                while (!AD1CON1bits.DONE);
                result[a] = ADC1BUF0;   // Digital values
            }

        if (strstr (msg, "UI01?") != NULL)
        {                
            sprintf(lala,"UI01 %d \r\n",result[0]); // UIO1 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI02?") != NULL)
        {  
            sprintf(lala,"UI02 %d \r\n",result[1]); // UIO2 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI03?") != NULL)
        {  
            sprintf(lala,"UI03 %d \r\n",result[2]); // UIO3 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI04?") != NULL)
        {  
            sprintf(lala,"UI04 %d \r\n",result[3]); // UIO4 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI05?") != NULL)
        {  
            sprintf(lala,"UI05 %d \r\n",result[4]); // UIO5 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI06?") != NULL)
        {  
            sprintf(lala,"UI06 %d \r\n",result[5]); // UIO6 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI07?") != NULL)
        {  
            sprintf(lala,"UI07 %d \r\n",result[6]); // UIO7 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI08?") != NULL)
        {  
            sprintf(lala,"UI08 %d \r\n",result[7]); // UIO8 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI09?") != NULL)
        {  
            sprintf(lala,"UI09 %d \r\n",result[8]); // UIO9 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI10?") != NULL)
        {  
            sprintf(lala,"UI10 %d \r\n",result[9]); // UI10 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI11?") != NULL)
        {  
            sprintf(lala,"UI11 %d \r\n",result[10]); // UI11 ADC Value
            sendString(lala)  ;
        }
        else if (strstr (msg, "UI12?") != NULL)
        {  
            sprintf(lala,"UI12 %d \r\n",result[11]); // UI12 ADC Value
            sendString(lala)  ;
        }
}

这里是最小化的代码: 但是,从这段代码中,当我键入 UI01?UI12? 时,没有任何反应。还有其他方法可以最小化代码吗?

void decode (unsigned char* msg) {

        int result[12]; // Store values
        int a = 0; // start from UI0-UI4
        unsigned char lala[50]   ;


            for (a = 0; a < 13; a++)
            {
                AD1CHS0bits.CH0SA = a;  //select UI01 until UI12
                AD1CHS0bits.CH0NA = 0;  //vref as channel 0 -ve input
                AD1CON1bits.ADON = 1;   // 1, A/D Converter module is operating
                AD1CON1bits.SAMP = 1;   //Sampling
                __delay32(50);          // delay after sampling
                AD1CON1bits.SAMP = 0;   //sampling bit to 0
                while (!AD1CON1bits.DONE);
                result[a] = ADC1BUF0;   // Digital values
            }

        // Check content, allowing for upper/lower case.

        msg[0] = toupper (msg[0]);
        msg[1] = toupper (msg[1]); 

        // UI01 until UI12
        // Request ADC value from hardware through HyperTerminal
        if ((msg[0] != 'U') || (msg[1] != 'I')) return;
        if ((msg[2] >= '0')  || (msg[2] <= '9')) return;
        if ( msg[3] != '?') return;

        // UI01 until UI09
        if (msg[2] == '0')
            {
            switch (msg[2]) {
                case '1': sprintf(lala,"UI01 %d \r\n",result[0]); // UIO1 ADC Value
                          sendString(lala)   ; break;
                case '2': sprintf(lala,"UI02 %d \r\n",result[1]); // UIO2 ADC Value
                          sendString(lala)   ; break;
                case '3': sprintf(lala,"UI03 %d \r\n",result[2]); // UIO3 ADC Value
                          sendString(lala)   ; break;
                case '4': sprintf(lala,"UI04 %d \r\n",result[3]); // UIO4 ADC Value
                          sendString(lala)   ; break;
                case '5': sprintf(lala,"UI05 %d \r\n",result[4]); // UIO5 ADC Value
                          sendString(lala)   ; break;
                case '6': sprintf(lala,"UI06 %d \r\n",result[5]); // UIO6 ADC Value
                          sendString(lala)   ; break;
                case '7': sprintf(lala,"UI07 %d \r\n",result[6]); // UIO7 ADC Value
                          sendString(lala)   ; break;
                case '8': sprintf(lala,"UI08 %d \r\n",result[7]); // UIO8 ADC Value
                          sendString(lala)   ; break;
                case '9': sprintf(lala,"UI09 %d \r\n",result[8]); // UIO9 ADC Value
                          sendString(lala)   ; break;
                return;
                }
            }

        // UI10 until UI12
        if (msg[2] == '1') {
        switch (msg[2]) 
            {
            case '0': sprintf(lala,"UI10 %d \r\n",result[9]);  // UI10 ADC Value
                      sendString(lala)  ; break;
            case '1': sprintf(lala,"UI11 %d \r\n",result[10]); // UI11 ADC Value
                      sendString(lala)  ; break; 
            case '2': sprintf(lala,"UI12 %d \r\n",result[11]); // UI12 ADC Value
                      sendString(lala)  ; break;
            default: return;
            }
        }
    }

以下是我的做法。首先检查消息的固定部分,即开头的'U''I',以及结尾的'?'NUL。然后检查并将两位数字转换为数字n。该数字可用于输出消息,并作为数组的索引。

sprintf中,%02d表示将数字显示为两位数,如有必要,可在前导0。数组索引是 n-1,因为 n 介于 1 和 12 之间,但数组索引是从 0 到 11。

// Expecting a request of the form UIxx?  where xx is a number from 01 to 12    

// force the first two characters to uppercase
msg[0] = toupper (msg[0]);
msg[1] = toupper (msg[1]);

// check the fixed portion of the message and verify the message length
if ( msg[0] != 'U' || msg[1] != 'I' || msg[4] != '?' || msg[5] != '[=10=]' )
    return;

// verify that we have two digits
if ( !isdigit(msg[2]) || !isdigit(msg[3]) )
    return;

// convert the digits to a number, and verify the number is between 1 and 12
int n = (msg[2] - '0') * 10 + (msg[3] - '0');
if ( n < 1 || n > 12 )
    return;

// the rest is easy
sprintf(lala, "UI%02d %d \r\n", n, result[n-1] );
sendString(lala);

msg 转换为整数,如果需要,请使用 hash

unsigned long code = 0;
while (*msg) {
  code = 256*code + *msg++;
}

#define ENCODE5(s) ((((s[0]*256LU + s[1])*256 + s[2])*256 + s[3])*256 + s[4])
if (code == ENCODE5("UI06?") ...
else if (code == ENCODE5("UI07?") ...

或散列

#define A(a) (a - ' ')
unsigned code = 0;
while (*msg) {
  code = 95*A(code) + *msg++;  // 95 printable characters
}

#define ENCODE5(s) ((((A(s[0])*95U + A(s[1]))*95 + A(s[2]))*95 + A(s[3]))*95 + A(s[4]))
switch(code) {
  case ENCODE5("UI06?"): ... break;
  case ENCODE5("UI07?"): ... break;

好处:switch() 将报告冲突,只需更改哈希即可。

这是一种模仿您的初始代码并允许在 msg:

中进行多个查询的方法
for (int i = 0; i < 12; ++i)
{
    char search[6];
    sprintf(search, "UI%02d?", i+1);
    if ( strstr(msg, search) )
    {
        sprintf(lala, "UI%02d %d \r\n", i+1, result[i]);
        sendString(lala);
    }
}

注意:从技术上讲,这段代码应该给出一个编译错误,因为 lala 衰减到 unsigned char *,但 sprintf 期望 char *。一些编译器让这个滑动但是为了正确你可能需要写 sprintf((char *)lala,...

为什么不简单地 trim 字符串并直接复制它

msg[strlen(msg) - 1] = 0;
sprintf(lala, "%s %d \r\n", msg, result[0]);
sendString(lala);