3

我现在将 arduino 代码移植到 stm32(c/c++)。请帮我完成这个功能:

constrain(x, a, b)

退货

x:如果 x 在 a 和 b 之间

a: 如果 x 小于 a

b:如果 x 大于 b

例子

sensVal = constrain(sensVal, 10, 150);

// limits range of sensor values to between 10 and 150 
4

3 回答 3

10

这里是一个模板版本,包括一个完整的程序来演示使用(你应该能够复制和粘贴):

#include <iostream>

template<class T>
const T& constrain(const T& x, const T& a, const T& b) {
    if(x < a) {
        return a;
    }
    else if(b < x) {
        return b;
    }
    else
        return x;
}

int main() {
    int value = 10;
    std::cout << constrain(value, 5, 20) << "\n"      // prints "10"
              << constrain(value, 15, 20) << "\n"     // prints "15"
              << constrain(value, 5, 9) << std::endl; // prints "9"
}

这可以用于任何具有 的类型operator<(这包括所有内置的数字类型,例如intand float)。

于 2012-01-20T12:17:54.580 回答
8

对于 Arduino,constrain它不是一个函数,它是一个 #define 的宏。

它在 Arduino IDE 的 Arduino.h 中定义。

Arduino 源代码是在开源许可下发布的,因此您可以阅读它:-)

它的定义是:

#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))

这将继续在您的 stm32 端口中工作。

当然,它是一个宏,所以只是一个文本替换。因此参数出现在您的源代码中,因此它们不是新的类型信息。

您可能更喜欢使用函数而不是宏,但由于您的代码是现有代码的一个端口,因此继续使用宏可能会更简单。然后,如果对原始代码进行改进或更改,则生成新端口的工作应该会减少。

关于尝试使用类型函数或模板函数而不是宏的一个小问题是它可能会在以后引起混淆。如果您尝试移植任何 Arduino 代码,使用函数而不是宏可能会产生新的警告、错误或错误。具体来说,如果原始代码使用constrain了您没有匹配函数的类型或类,则会出现在 Arduino 源代码中显然不存在的错误。或者更糟的是,类型化或模板化函数可能会触发一些在宏版本中不会发生的 C++ 类型转换。您可能会为自己或将来使用您的代码的任何人留下一个小“陷阱”。

于 2012-03-16T19:45:49.093 回答
2

查看Clamping (graphics)下的 Wikipedia ,看起来您可以拥有一个与类型无关的模板?

template<typename T>
T clamp(T Value, T Min, T Max)
{
  return (Value < Min)? Min : (Value > Max)? Max : Value;
}
于 2012-03-01T20:33:33.090 回答