这个构造函数代码如何将指针作为参数?
How is this constructor code taking pointers as arguments?
下面的代码有三个 double* 类型的参数。该代码是 Arduino PID 库的一部分,用户通常会将模拟端口或某种传感器的读数作为 "input" 项的参数,并将一些固定值或用户控制变量作为 "input" 项的值"setpoint" 项。但参数是 double* 类型。用户提供 double 时不应该得到错误吗?
PID::PID(double* Input, double* Output, double* Setpoint,
double Kp, double Ki, double Kd, int ControllerDirection)
{
myOutput = Output;
myInput = Input;
mySetpoint = Setpoint;
inAuto = false;
PID::SetOutputLimits(0, 255); // default output limit corresponds to
// the arduino pwm limits
SampleTime = 100; // default Controller Sample Time is 0.1 seconds
PID::SetControllerDirection(ControllerDirection);
PID::SetTunings(Kp, Ki, Kd);
lastTime = millis()-SampleTime;
}
构造函数是否只取用户提供的double地址?
如果用户正在读取一些温度数据,比如 double temp=AnalogRead(1)。因此,读取来自模拟引脚 1 的任何内容,myOutput 是否只是那些传入温度读数的地址?
myInput、myOutput 和 mySetpoint 在另一个成员函数中被取消引用。
double input = *myInput;
double error = *mySetpoint - input;
对此有几种可能的解释。
可选参数:
一个可能的解释是Setpoint
是可选的,所以你可以传递nullptr
。
在代码中,如果您传递了一个空指针,则不会使用任何设置点。
您提到 Setpoint
在另一个函数中被取消引用,因此它可能不是可选的。
输出参数:
C 没有引用,所以输出参数通常作为指针传递。为了更改函数调用者可见的参数,您将其作为指针传递
void setFoo(double* in)
{
*in = 5;
}
double foo;
setFoo(&foo); // pass the memory address of your variable
此时foo
的值为5.
在 C++ 中你可以使用引用,所以如果你想要一个输出参数,但需要用户提供一个值,你可以使用 double& Setpoint
.
允许外部更改可见:
可能最可能的解释是让你提供Setpoint
的地址,然后如果你稍后更改Setpoint
的值,对象将观察这些变化。
double setpoint = 1;
PID p(&input, &output, &setpoint, ...)
p.foobar(); // setpoint=1
setpoint = 3;
p.foobar(); // setpoint=3
同样,在 C++ 中,您可以使用引用来获得相同的行为(尽管这会使您的对象不可分配)。
如您所见,有几种可能的解释,因此如果没有进一步的详细信息,您无法真正确定为什么库作者要求您使用指针而不是按值语义
下面的代码有三个 double* 类型的参数。该代码是 Arduino PID 库的一部分,用户通常会将模拟端口或某种传感器的读数作为 "input" 项的参数,并将一些固定值或用户控制变量作为 "input" 项的值"setpoint" 项。但参数是 double* 类型。用户提供 double 时不应该得到错误吗?
PID::PID(double* Input, double* Output, double* Setpoint,
double Kp, double Ki, double Kd, int ControllerDirection)
{
myOutput = Output;
myInput = Input;
mySetpoint = Setpoint;
inAuto = false;
PID::SetOutputLimits(0, 255); // default output limit corresponds to
// the arduino pwm limits
SampleTime = 100; // default Controller Sample Time is 0.1 seconds
PID::SetControllerDirection(ControllerDirection);
PID::SetTunings(Kp, Ki, Kd);
lastTime = millis()-SampleTime;
}
构造函数是否只取用户提供的double地址?
如果用户正在读取一些温度数据,比如 double temp=AnalogRead(1)。因此,读取来自模拟引脚 1 的任何内容,myOutput 是否只是那些传入温度读数的地址?
myInput、myOutput 和 mySetpoint 在另一个成员函数中被取消引用。
double input = *myInput;
double error = *mySetpoint - input;
对此有几种可能的解释。
可选参数:
一个可能的解释是Setpoint
是可选的,所以你可以传递nullptr
。
在代码中,如果您传递了一个空指针,则不会使用任何设置点。
您提到 Setpoint
在另一个函数中被取消引用,因此它可能不是可选的。
输出参数:
C 没有引用,所以输出参数通常作为指针传递。为了更改函数调用者可见的参数,您将其作为指针传递
void setFoo(double* in)
{
*in = 5;
}
double foo;
setFoo(&foo); // pass the memory address of your variable
此时foo
的值为5.
在 C++ 中你可以使用引用,所以如果你想要一个输出参数,但需要用户提供一个值,你可以使用 double& Setpoint
.
允许外部更改可见:
可能最可能的解释是让你提供Setpoint
的地址,然后如果你稍后更改Setpoint
的值,对象将观察这些变化。
double setpoint = 1;
PID p(&input, &output, &setpoint, ...)
p.foobar(); // setpoint=1
setpoint = 3;
p.foobar(); // setpoint=3
同样,在 C++ 中,您可以使用引用来获得相同的行为(尽管这会使您的对象不可分配)。
如您所见,有几种可能的解释,因此如果没有进一步的详细信息,您无法真正确定为什么库作者要求您使用指针而不是按值语义