【问题标题】:Passing Arrays through Fuctions - "Error: Cannot Convert 'float**' to 'float*' for argument '1'"通过函数传递数组 - “错误:无法将参数 '1' 的 'float**' 转换为 'float*'”
【发布时间】:2020-04-10 17:53:07
【问题描述】:

长期阅读,第一次提问。

所以我正在进行一个编码项目,其长期目标是制作一个太阳系模拟器。这个想法是,它用一些规则来创建一个随机的太阳系,比如“在形成时,霜线之后的第一颗行星必须是最大的气态巨行星”等,并计算轨道以检查稳定性。

显然它还没有完成,我在子例程中使用数组时遇到了一些麻烦。我知道你不能直接将数组传入和传出函数,但是如果你做得对,你可以将指向所述数组的指针传入和传出函数。

我显然没有在下面做。我试图评论并使代码尽可能可读,就在这里。

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <tuple>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <complex>
#include <stdint.h>
#include <time.h>
#include <string.h>
#include <algorithm>

//#include "mpi.h"

using namespace std;

double MyRandom(){

//////////////////////////
//Random Number Generator
//Returns number between 0-99
//////////////////////////

    double y = 0;
    unsigned seed = time(0);
    srand(seed);
    uint64_t x = rand();

    x ^= x << 13;
    x ^= x >> 7;
    x ^= x << 17;

    x = (1070739 * x) % 2199023255530;
    y = x / 21990232555.31 ;
    return y;
}
////////////////////////

///////////////////////
tuple< char& , float& , float& , float& , int& > Star(){

////////////////////////////
//Star will generate a Star
//Randomly or User Selected
//Class, Luminosity, Probability, Radius, Mass, Temperature
//Stars always take up 99% of the mass of the system.
///////////////////////////

char Class;
string Choice;
float L, R, M;
int T;
tuple< char& , float& , float& , float& , int& > star( Class = 'i', L = 1 , R = 1 , M = 1 , T = 3000) ;
cout << "Select Star Class (OBAFGKM) or Select R for Random: ";
cin >> Choice;
if ( Choice == "R" ) {
    double y;
    y = MyRandom();
    if (y <= 0.003) Class = 'O';
    if ((y > 0.003) && (y <= 0.133)) Class = 'B';
    if ((y > 0.133) && (y <= 0.733)) Class = 'A';
    if ((y > 0.733) && (y <= 3.733)) Class = 'F';
    if ((y > 3.733) && (y <= 11.333)) Class = 'G';
    if ((y > 11.333) && (y <= 23.433)) Class = 'K';
    else Class = 'M';
    }
    if (Class == 'O') {
        L = 30000;
        R = 0.0307;
        M = 16;
        T = 30000;
    }
    if (Class == 'B') {
        L = 15000;
        R = 0.0195;
        M = 9;
        T = 20000;
    }
    if (Class == 'A') {
        L = 15;
        R = 0.00744;
        M = 1.7;
        T = 8700;
    }
    if (Class == 'F') {
        L = 3.25;
        R = 0.00488;
        M = 1.2;
        T = 6750;
    }
    if (Class == 'G') {
        L = 1;
        R = 0.00465;
        M = 1;
        T = 5700;
    }
    if (Class == 'K') {
        L = 0.34;
        R = 0.00356;
        M = 0.62;
        T = 4450;
    }
    if (Class == 'M') {
        L = 0.08;
        R = 0.00326;
        M = 0.26;
        T = 3000;
    }

    return star;
}
////////////

////////////
float* Planet( float &L, float &R, float &M, int &T, int &n){

///////////////////////////
//Planet generates the Planets
//Random 1 - 10, Random distribution 0.06 - 6 JAU unless specified by User
//Frost line Calculated, First Planet after Frost line is the Jupiter
//The Jupiter will have the most mass of all Jovian worlds
//Otherwise divided into Jovian and Terrestrial Worlds, Random Masses within groups
//Also calculates if a planet is in the Habitable Zone
////////////////////////////

    float frostline, innerCHZ, outerCHZ;
    float a = 0.06; // a - albedo
    float m = M / 100; //Mass of the Jupiter always 1/100th mass of the Star.
    float sys[n];
    float* system[n][5] = {{0}};

    for (int i = 0 ; i < n ; i++){
        sys[i] = MyRandom()/10 * 3; //Distances in terms of Sol AU
    }
    sort(sys, sys + n );
    for (int i = 0 ; i < n ; i++){
        system[i][0] = &sys[i];
        system[i][1] = 0; //system[i][0] is x, system[i][1] is y
    }

    frostline = (0.6 * T / 150) * (0.6 * T/150) * R / sqrt(1 - a);
    innerCHZ = sqrt(L / 1.1);
    outerCHZ = sqrt(L / 0.53);

    for (int i = 0 ; i < n ; i++){
        if (system[i][0] <= &frostline) {
            float tmass = m * 0.0003 * MyRandom();
            system[i][2] = &tmass ; //system[i][2] is mass, [3] is marker for the Jupter
            system[i][3] = 0 ;
        }

        if ((system[i][0] >= &frostline) && (system[i-1][0] < &frostline)){
            system[i][2] = &m ;
            float J = 1;
            system[i][3] = &J ;
        }

        if ((system[i][0] >= &frostline) && (system[i-1][0] >= &frostline)) {
            float jmass = m * 0.01 * MyRandom();
            system[i][2] = &jmass ;
            system[i][3] = 0 ;
        }

        if ((system[i][0] >= &innerCHZ) && (system[i][0] <= &outerCHZ)){
            float H = 1;
            system[i][4] = &H;
        }
        else system[i][4] = 0; //[4] is habitable marker

    }

    return system[n][5];
}
////////////

////////////
float* Time( float *system , int n){

///////////////////////////
//Time advances the solar system.
//Plots the Orbits
//Uses MPI to spread it's calculations.
///////////////////////////

    return system;
}
////////////

////////////
void FinalCheck( float system){

///////////////////////////
//Final Checks
//Reports if a Planet spent the whole Time in the Habitable Zone
///////////////////////////

/*for (int i = 0 ; i < row ; i++){
    if (system[i][4] == 1.0) {
        cout << "Planet " << i << " in this system is Habitable." ;
        }
    // The Habitable stat only means liquid water can exist on the surface
    // Add pi if planet enters habitable zone, minus 1 if it leaves.
    // If planet was habitable but left, assuming all life was destroyed
    }
*/
}
////////////

int main(){

char Class;
int T;
float L, R, M;

tuple< char , float , float , float , int > star( Class , L , R , M , T );
star = Star();

int n = MyRandom()/10 + 1;

float * system[n][5] = {{0}};
float system1[n][5] = {{0}};
system[n][5] = Planet( L , R , M, T, n);

for (int i = 0 ; i < 100 ; i++) {
 system1[n][5] = Time( *system, n );
 system[n][5] = &system1[n][5];
}
FinalCheck( *system[n][5]);

///////////////////////////
//Report cleans everything up and gives the results
//Shows the plot, lists the Planets
//Reports the Positions and Masses of all Planets
//Reports which was the Jupiter and which if any were Habitable
//////////////////////////
return 0;
}

问题是当我在这一行运行编译器时,第 227 行被标记 -

  system1[n][5] = Time( *system, n );

出现以下错误:

  error: cannot convert 'float**' to 'float*' for argument '1' to 'float* Time(float*, int)

我知道这意味着我试图将指向指针的指针等同于指针的编译器事物,但我不确定它是如何得出该结论或如何修复它的。我很感激这方面的帮助,尤其是第二部分。我也很想听听有关通过子例程传递数组的任何信息,因为显然我做得不对,或者至少做得不好。

更新 1 : - 得到了短期修复,编译器通过了,但是当我尝试运行它时给出了分段错误(核心转储)错误。看起来我有一些阅读和更新要处理命名空间、指针,并可能将数组更改为向量。感觉如果我先专注于那些,它可能会解决分段错误。

【问题讨论】:

  • 不是你的编译器错误,而是stackoverflow.com/questions/6441218/…
  • float sys[n]; -- 这不是有效的 C++。 C++ 中的数组的大小必须由编译时常量表示,而不是运行时值,例如 n。您应该改用std::vector&lt;float&gt; sys(n);。同样的问题:float* system[n][5] = {{0}};
  • system 应该是一维结构数组。

标签: c++ arrays function debugging


【解决方案1】:

您的变量 system 被声明为

float * system[n][5] = {{0}};

这是一个指向 2D 数组的指针(当传递给函数时,它将衰减为 float***)。

您的Time 函数声明为

float* Time( float *system , int n);

第一个参数必须是float*

这意味着这个电话

system1[n][5] = Time( *system, n );

实际上应该是这样的

system1[n][5] = Time( **system, n );

话虽如此,您的代码中存在许多问题。

首先,不要使用using namespace std;

另外,这条线float sys[n]; 是不允许的。在 C++ 中不能有可变长度数组。

【讨论】:

  • 不知道衰变的事情,所以它实际上可以解释这一点。我尝试了您在第 227 行提出的建议,并将错误更改为 error: cannot convert 'float*' to 'float' in assignment 否则没有变化。也不知道不使用命名空间 std 是什么意思。并且不允许在 C++ 中动态调整大小的数组?我一定不明白你的实际意思。
  • 如果你不确定指针是如何工作的,你不应该使用这么多指针。试试 std::vector ,它更容易使用。另请参阅 thisthis
【解决方案2】:
float* system[n][5]

system 这里是float*s 的二维数组,而不是floats。

因此,换句话说,system 衰减为 float****system 衰减为 float****system 衰减为 float****system 衰减为 float

所以,编译器是正确的。您正在将衰减到 float** 的内容传递给 Time(),后者需要 float*

你将不得不重新配置你的代码来传递正确的东西,不管是什么。


旁注:请注意the way you're creating arrays isn't valid C++,以后可能会引起问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 2014-06-28
    • 1970-01-01
    相关资源
    最近更新 更多