Для начала 409 < result < 818
не выражение, которое делает то, что вы думаете, он делает в C. Это может иметь смысл математически, но C нуждается в вас, чтобы быть немного более конкретно:
(409 < result) && (result < 818)
Объясняя далее, выражение 409 < result < 818
будет первым работать значение истинности для 409 < result
, давая ноль или один, который мы будем называть X
, Затем результат будет передан в X < 818
, чтобы дать новое значение истины.
Таким образом, в этом случае, вы всегда будете получать истинное просто потому, что X
нуля или одного является всегда меньше 818
. Следующая программа демонстрирует это в действии:
#include <stdio.h>
void Between400And600 (int n) {
printf ("%d between 400 and 600? Old = %d, new = %d\n",
n,
400 < n < 600,
(400 < n) && (n < 600));
}
int main (void) {
Between400And600 (111);
Between400And600 (555);
Between400And600 (999);
return 0;
}
первый результат на каждой линии оригинал один, old
. Во-вторых, мое рекомендуемое исправление, new
. Как вы можете видеть, все ваши выражения дают 1
(истина), в то время как исправление только дает истинное для значения между пределами:
111 between 400 and 600? Old = 1, new = 0
555 between 400 and 600? Old = 1, new = 1
999 between 400 and 600? Old = 1, new = 0
Кроме того, некоторые из ваших проверок диапазонвыхода с номерами, находящимися в неправильном порядке. Кроме возможности некоторого более высокого порядка по математике я не в курсе, ни один номер не может быть больше, чем 3860
и менее 3272
в то же время:
И, сверх того, исключительное использование <
, а не <=
означает, что вы отсутствует некоторые случаи, например, когда result
является 409
.
Если вы только после того, как сжатый способа сделать отображение, я выбрал бы что-то вроде:
unsigned int getVolt (unsigned int adc) {
if (adc < 409) return 0;
if (adc < 818) return 1;
if (adc < 1227) return 2;
if (adc < 1636) return 3;
if (adc < 2045) return 4;
if (adc < 2454) return 5;
if (adc < 2863) return 6;
if (adc < 3272) return 7;
if (adc < 3681) return 8;
if (adc < 4095) return 9;
return 10;
}
и назвать его просто с:
volt = getVolt (result);
Это много короче , намного яснее и, следовательно, намного меньше подвержены ошибкам.
Учитывая, что все, кроме последнего кратна 409
, вы могли бы сократить его еще больше, что-то вроде:
unsigned int getVolt (unsigned int adc) {
if (adc < 4090) return adc/409;
if (adc < 4095) return 9;
return 10;
}
но вы теряете ясность (и гибкость, должны изменить пороги) в этом случае я бы, наверное, придерживался своей первой реализации, учитывая, что это не тоже большой. Конечно, если бы это закончилось пятьюдесятью if
заявлениями, я бы, вероятно, искал лучшее решение, но десять строк кода не так уж плохи.
Если вы хотите сохранить код относительно короткий пока еще позволяют значительно увеличить число проверок, вы могли бы сделать его управлялся таблицей нечто похожее на:
unsigned int getVolt (unsigned int adc) {
const static unsigned thresholds[] = {
409, 818, 1227, 1636, 2045, 2454, 2863, 3272, 3681, 4095,
// as many entries as you need.
};
const static int sz = sizeof(thresholds)/sizeof(*thresholds);
for (int idx = 0; idx < sz; idx++)
if (adc < thresholds[idx])
return idx;
return sz;
}
То есть ограничение, возвращаемые значения должны начинаться с нуля (то же самое, что и индекс, 0..9
плюс значение по умолчанию 10
), но это нормально для вашего конкретного случая.
Как насчет чтения хорошей C книги? Это покажет вам все, что вам нужно, чтобы решить это самостоятельно. – Olaf
Хорошо исправить ошибки компиляции перед публикацией здесь –