Как минимизировать оператор if и else
Как минимизировать оператор 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 ответа
Вот как бы я это сделал. Сначала проверьте фиксированную часть сообщения, то есть '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);
Перерабатывать msg
в целое число, если хотите, используйте хеш.
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,
...
Почему бы просто не обрезать строку и скопировать ее напрямую
msg[strlen(msg) - 1] = 0;
sprintf(lala, "%s %d \r\n", msg, result[0]);
sendString(lala);