如何最小化if和else语句

时间:2015-09-03 03:22:07

标签: c pic mplab

如何最小化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;
            }
        }
    }

4 个答案:

答案 0 :(得分:3)

这是我怎么做的。首先检查邮件的固定部分,即开头的'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] != '\0' )
    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);

答案 1 :(得分:0)

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()将报告冲突,只需更改哈希。

答案 2 :(得分:0)

以下是一种模仿初始代码的方法,并允许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, ...

答案 3 :(得分:0)

为什么不简单地修剪字符串并直接复制

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