美好的一天:)我正在研究一种用于从加速度计和陀螺仪获得俯仰角,偏航角和滚转角的代码。为了创建一个易于理解的更清晰的代码,我使用了两个不同的功能。一个用于计算俯仰偏转和俯仰的陀螺仪,另一个用于加速度计也可以做同样的事情。
float *readGyro(){
/*get data from sensor here*/
float gyroAngles[4]={gyroPitch,gyroRoll,gyroYaw};
float* gyroPRY=gyroAngles;
return gyroPRY;
}
float *readAccel(){
/*get data from sensor here*/
float accelAngles[4]={accelPitch,accelRoll,accelYaw};
float* accelPRY=accelAngles;
return accelPRY;
}
如上所示,我将函数的输出存储到一个数组中以传递给main函数。基本上指针被传递。但是,在从传递的指针访问值时,会打印常量垃圾值(不会随着我移动IMU而改变)(例如,2.38221e-44和-3.84146e-06)。我通过打印这些函数中的值来检查陀螺仪和加速度计的功能输出,它们很好。
int main(void){
float *accelData;
float *gyroData;
while(1){
accelData=readGyro();
gyroData=readAccel();
float accelPitch=*(accelData);
float accelRoll=*(accelData+1);
float accelYaw=*(accelData+2);
float gyroPitch=*(gyroData);
float gyroRoll=*(gyroData+1);
float gyroYaw=*(gyroData+2);
cout << "AccelPitch=" << accelPitch <<endl;
cout << "AccelRoll=" << accelRoll <<endl;
cout << "AccelYaw=" << accelYaw <<endl;
cout << "GyroPitch=" << gyroPitch <<endl;
cout << "GyroRoll=" << gyroRoll <<endl;
cout << "GyroYaw=" << gyroYaw <<endl;
}
}
我无法找到我的代码错误。在此之前,我咨询了许多参考文献。但是我仍然无法解决它。非常感谢您的帮助:)
答案 0 :(得分:5)
C ++的内置数组是从C继承而来的,并不像大多数人期望的那样工作。让我们说你有这样的功能:
float* get_vec() {
float vec[3] = { 1.0f, 2.0f, 3.0f };
return vec;
}
实际上做的是返回堆栈分配变量vec
的地址;不幸的是,当函数结束时,vec
将超出范围,返回的地址将毫无意义。
绕过这个方法是将数组包装在struct
中,可以按值返回。您可以定义自己的,也可以使用C ++标准库中的std::array
,如下所示:
std::array<float, 3> get_vec() {
std::array<float, 3> vec = { 1.0f, 2.0f, 3.0f };
return vec;
}
答案 1 :(得分:3)
你正在做的是返回函数本地数组的地址,该函数在函数退出时被销毁。
如果您想要一个数组用于建立索引,那么我建议您使用std::array
。
std::array<float, 3> readGyro() {
/*get data from sensor here*/
return {gyroPitch, gyroRoll, gyroYaw};
}
但更好的方法是使用这样的struct
。
struct angles
{
float pitch;
float roll;
float yaw;
};
angles readGyro() {
/*get data from sensor here*/
return {gyroPitch, gyroRoll, gyroYaw};
}
答案 2 :(得分:1)
当你将指针返回readGyro
和readAccel
的堆栈时,你正在做的事情永远不会奏效。当这些函数退出时,堆栈的该部分将被回收,并且您将留下未定义的行为。
一种方法是分配数组并将其返回,但是你也必须自己也必须删除该分配。
您可以为所需参数创建2个结构并将它们传递给您的函数。这样,函数可以在返回后继续写入某个地方。
e.g。
#include <iostream>
using std::cout;
using std::endl;
struct gyro_data_t
{
float pitch;
float roll;
float yaw;
};
struct accel_data_t
{
float pitch;
float roll;
float yaw;
};
void readGyro(gyro_data_t* gd)
{
/*get data from sensor here*/
gd->pitch = 1.0f;
gd->roll = 1.1f;
gd->yaw = 1.2f;
}
void readAccel(accel_data_t* ad)
{
/*get data from sensor here*/
ad->pitch = 1.0f;
ad->roll = 1.1f;
ad->yaw = 1.2f;
}
int main(void)
{
accel_data_t accelData;
gyro_data_t gyroData;
while(1)
{
readGyro(&gyroData);
readAccel(&accelData);
cout << "AccelPitch=" << accelData.pitch << endl;
cout << "AccelRoll=" << accelData.roll << endl;
cout << "AccelYaw=" << accelData.yaw << endl;
cout << "GyroPitch=" << gyroData.pitch << endl;
cout << "GyroRoll=" << gyroData.roll << endl;
cout << "GyroYaw=" << gyroData.yaw << endl;
}
}
请注意,这比示例更具可读性,因为它明确命名每个变量,而不是将它们表示为返回值的偏移量。不再需要赋予新变量以便理解值的含义。
这两个结构实际上是相同的,因此如果需要可以压缩成一个通用结构。
答案 3 :(得分:1)
将数组复制为数据成员时,将逐个复制数组元素,而不是复制衰减的指针。这样可以避免返回局部变量的地址。
foreach (TreeNode tn in tvPermission.Nodes)
tn.Checked = (role.AccessPages.Where(p => p.Url == tn.Value).ToList().Count() > 0);
但是使用struct float3{
float fs[3];
};
float3 readGyro(){
float3 f3 = {};
f3.fs[0] = gyroPitch;
f3.fs[1] = gyroRoll;
f3.fs[2] = gyroYaw;
return f3;
}
作为其他答案说是非常合适的。你不需要发明另一个轮子。
如果您希望通过参数获取结果,请使用引用而不是指针来避免丢失大小信息(衰减到指针)。这也确保只传递std::array<float, 3>
类型。
float[3]