簡體   English   中英

從C ++中的函數返回數組

[英]Returning Arrays from functions in C++

美好的一天:)我正在研究從加速度計和陀螺儀獲得俯仰,偏航和滾轉角度的代碼。 為了創建一個易於理解的更清晰的代碼,我使用了兩個不同的功能。 一個用於計算俯仰偏轉和俯仰的陀螺儀,另一個用於加速度計也可以做同樣的事情。

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;

    }
}

我無法找到我的代碼錯誤。 在此之前,我咨詢了許多參考文獻。 但是我仍然無法解決它。 非常感謝你的幫助:)

C ++的內置數組繼承自C,並不一定按照大多數人的預期方式工作。 假設您有這樣的函數:

float* get_vec() {
    float vec[3] = { 1.0f, 2.0f, 3.0f };
    return vec;
}

這實際上做的是返回堆棧分配的變量vec地址 ; 不幸的是,當函數結束時, vec將超出范圍,返回的地址將毫無意義。

這種方法是將數組包裝在一個struct ,該struct 可以通過值返回。 您可以定義自己的,也可以使用C ++標准庫中的std::array ,如下所示:

std::array<float, 3> get_vec() {
    std::array<float, 3> vec = { 1.0f, 2.0f, 3.0f };
    return vec;
}

你正在做的是返回函數本地的數組的地址 ,該函數在函數退出時被銷毀。

如果你想要一個數組用於索引的原因,那么我建議使用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};
}

你正在做什么將永遠不會工作,因為你正在將指針返回到readGyroreadAccel的堆棧上。 當這些函數退出時,堆棧的該部分將被回收,並且您將留下未定義的行為。

一種方法是分配數組並返回它,但是你自己也不得不刪除那個分配。

您可以為所需參數創建2個結構並將它們傳遞給您的函數。 這樣,函數可以寫入返回后會持續存在的地方。

例如

#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;
    }
}

請注意,這比示例更具可讀性,因為它明確命名每個變量,而不是將它們表示為返回值的偏移量。 不再需要賦予新變量以便理解值的含義。

這兩個結構實際上是相同的,因此如果需要可以壓縮成一個通用結構。

將數組換行為按值返回的結構

將數組復制為數據成員時,將逐個復制數組元素,而不是復制衰減的指針。 這避免了返回局部變量的地址。

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]類型。

void readGyro(float (&fs)[3])
{        
    fs[0] = gyroPitch;
    fs[1] = gyroRoll;
    fs[2] = gyroYaw;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM