从范围值使用 for 循环
Using for loop from range value
我从中得到了一些数据table:
是否可以使用(for循环)?
最近用了(if else)函数,但是好像太长了
我是 C 编程新手。这是我完成的代码(如果还有的话)功能:
if (0 < result < 409 ) // 0 to 408
{
volt = 0 ;
}
else if (409 < result < 818 ) //408 to 817
{
volt = 1 ;
}
else if (818 < result < 1227 ) //818 to 1226
{
volt = 2 ;
}
else if (1227 < result < 1636 ) //1227 to 1635
{
volt = 3 ;
}
else if (1636 < result < 2045 ) // 1636 to 2044
{
volt = 4 ;
}
else if (2045 < result < 2454 ) // 2045 to 2453
{
volt = 5 ;
}
else if (2454 < result < 2863 ) //2454 to 2862
{
volt = 6 ;
}
else if (3271 < result < 2863 ) //2863 to 3271
{
volt = 7 ;
}
else if (3860 < result < 3272 ) //3272 to 3860
{
volt = 8 ;
}
else if (4094 < result < 3861 ) //3861 to 4094
{
volt = 9 ;
}
else if (result >= 4095 ) //4095++
{
volt = 10 ;
}
首先,409 < result < 818
不是一个表达式,它的作用与您认为它在 C 中的作用相同。它在数学上可能有意义,但 C 需要您稍微具体一些:
(409 < result) && (result < 818)
Explaining further, the expression 409 < result < 818
will first work out the truth value for 409 < result
, giving either zero or one, which we'll call X
. Then the result of that will be fed into X < 818
to give a new truth value.
So, in that case, you'll always get true simply because an X
of zero or one is always less than 818
. The following program shows this in action:
#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;
}
The first result on each line is your original one, old
. The second is my suggested fix, new
. As you can see, all of your expressions give 1
(true) while the fix only gives true for the value between the limits:
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
:
else if (3860 < result < 3272 ) //3272 to 3860
而且,最重要的是,独占使用 <
而不是 <=
意味着您 缺少 某些情况,例如何时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
语句,我可能会寻找更好的解决方案,但十行代码也不错。
如果您想使代码相对较短,但仍允许进行大量检查,则可以 table 使用类似于以下内容的驱动程序:
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;
}
有一个限制,即 return 值必须从零开始连续(与索引相同,0..9
加上默认值 10
)但这没关系你的具体情况。
同上 paxdiablo 所说的第一部分,但为了回答您的问题,您 可以 将其放入 for 循环中,但是如果您查看您的数字,范围每个 if
/else if
代码块中的数字是相同的; 409. 然后在该块内,设置伏特 = 您所在部分的编号。在第一部分中设置伏特 = 0,在第二部分中设置伏特 = 1,依此类推。由于每个部分的范围每次都增加 409,因此您可以将您编写的所有内容替换为
volt = result / 409
.
记住(假设结果是一个整数)c 语言将使用整数除法处理 result/409
。因此,如果结果 >= 0 且 < 409,则 result/409 等于 0。如果结果 >= 409 且 < 818,则 result/409 等于 1,依此类推。然而,这确实意味着如果结果 = 4094,伏特将等于 9,这不是您的图表所说的应该发生的情况,但可能是您想要的。
如果您需要做类似的事情(范围不断增加),那么您可能会想要使用 for 循环。 for 循环也应该更快(我认为)。你必须再次利用你的范围以 409 的恒定增量上升的事实,所以做类似
的事情
for (int i = 0; i < max; i++ )
{
int lowerBound = (result / i);
int upperBound = (result / i + 408);
//or something
//...other necessary code here...
}
它只是一个 12 位(4096 计数)ADC,具有 10V 的满量程输入。它在该范围内是线性的,因此不需要 table 或循环:
#define ADC_BITS 12
#define ADC_MIN_VOLTS 0
#define ADC_MAX_VOLTS 10
#define ADC_COUNTS (1 << ADC_BITS)
#define ADC_VRANGE (ADC_MAX_VOLTS - ADC_MIN_VOLTS)
double adc_counts_to_volts(int counts)
{
return counts * (double)ADC_VRANGE / ADC_COUNTS;
}
您可以将其替换为整数版本以提供整数输出:
int adc_counts_to_volts(int counts)
{
return counts * ADC_VRANGE / ADC_COUNTS;
}
我从中得到了一些数据table:
是否可以使用(for循环)?
最近用了(if else)函数,但是好像太长了
我是 C 编程新手。这是我完成的代码(如果还有的话)功能:
if (0 < result < 409 ) // 0 to 408
{
volt = 0 ;
}
else if (409 < result < 818 ) //408 to 817
{
volt = 1 ;
}
else if (818 < result < 1227 ) //818 to 1226
{
volt = 2 ;
}
else if (1227 < result < 1636 ) //1227 to 1635
{
volt = 3 ;
}
else if (1636 < result < 2045 ) // 1636 to 2044
{
volt = 4 ;
}
else if (2045 < result < 2454 ) // 2045 to 2453
{
volt = 5 ;
}
else if (2454 < result < 2863 ) //2454 to 2862
{
volt = 6 ;
}
else if (3271 < result < 2863 ) //2863 to 3271
{
volt = 7 ;
}
else if (3860 < result < 3272 ) //3272 to 3860
{
volt = 8 ;
}
else if (4094 < result < 3861 ) //3861 to 4094
{
volt = 9 ;
}
else if (result >= 4095 ) //4095++
{
volt = 10 ;
}
首先,409 < result < 818
不是一个表达式,它的作用与您认为它在 C 中的作用相同。它在数学上可能有意义,但 C 需要您稍微具体一些:
(409 < result) && (result < 818)
Explaining further, the expression
409 < result < 818
will first work out the truth value for409 < result
, giving either zero or one, which we'll callX
. Then the result of that will be fed intoX < 818
to give a new truth value.So, in that case, you'll always get true simply because an
X
of zero or one is always less than818
. The following program shows this in action:
#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;
}
The first result on each line is your original one,
old
. The second is my suggested fix,new
. As you can see, all of your expressions give1
(true) while the fix only gives true for the value between the limits:
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
:
else if (3860 < result < 3272 ) //3272 to 3860
而且,最重要的是,独占使用 <
而不是 <=
意味着您 缺少 某些情况,例如何时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
语句,我可能会寻找更好的解决方案,但十行代码也不错。
如果您想使代码相对较短,但仍允许进行大量检查,则可以 table 使用类似于以下内容的驱动程序:
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;
}
有一个限制,即 return 值必须从零开始连续(与索引相同,0..9
加上默认值 10
)但这没关系你的具体情况。
同上 paxdiablo 所说的第一部分,但为了回答您的问题,您 可以 将其放入 for 循环中,但是如果您查看您的数字,范围每个 if
/else if
代码块中的数字是相同的; 409. 然后在该块内,设置伏特 = 您所在部分的编号。在第一部分中设置伏特 = 0,在第二部分中设置伏特 = 1,依此类推。由于每个部分的范围每次都增加 409,因此您可以将您编写的所有内容替换为
volt = result / 409
.
记住(假设结果是一个整数)c 语言将使用整数除法处理 result/409
。因此,如果结果 >= 0 且 < 409,则 result/409 等于 0。如果结果 >= 409 且 < 818,则 result/409 等于 1,依此类推。然而,这确实意味着如果结果 = 4094,伏特将等于 9,这不是您的图表所说的应该发生的情况,但可能是您想要的。
如果您需要做类似的事情(范围不断增加),那么您可能会想要使用 for 循环。 for 循环也应该更快(我认为)。你必须再次利用你的范围以 409 的恒定增量上升的事实,所以做类似
的事情for (int i = 0; i < max; i++ )
{
int lowerBound = (result / i);
int upperBound = (result / i + 408);
//or something
//...other necessary code here...
}
它只是一个 12 位(4096 计数)ADC,具有 10V 的满量程输入。它在该范围内是线性的,因此不需要 table 或循环:
#define ADC_BITS 12
#define ADC_MIN_VOLTS 0
#define ADC_MAX_VOLTS 10
#define ADC_COUNTS (1 << ADC_BITS)
#define ADC_VRANGE (ADC_MAX_VOLTS - ADC_MIN_VOLTS)
double adc_counts_to_volts(int counts)
{
return counts * (double)ADC_VRANGE / ADC_COUNTS;
}
您可以将其替换为整数版本以提供整数输出:
int adc_counts_to_volts(int counts)
{
return counts * ADC_VRANGE / ADC_COUNTS;
}