Передача массивов через Fuctions - «Ошибка: невозможно преобразовать« float ** »в« float * »для аргумента« 1 » - PullRequest
0 голосов
/ 10 апреля 2020

Долгое время Reader, впервые Asker.

Итак, я работаю над проектом по кодированию, долгосрочная цель которого - создать симулятор солнечной системы. Идея состоит в том, что она запускает рандомизированную солнечную систему с несколькими правилами, такими как «при формировании первого pl anet после того, как морозная линия должна быть самым большим газовым гигантом» et c, и вычисляет орбиты для проверки стабильности .

Очевидно, что это еще не сделано, у меня возникли проблемы с использованием массивов в подпрограммах. Я знаю, что вы не можете напрямую принимать и выводить массивы из функций, но вы можете использовать указатели на указанные массивы в и из функций, если вы все сделаете правильно.

Я, очевидно, не сделал это прямо ниже. Я попытался прокомментировать и сделать код максимально читабельным, вот он.

#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: - Получено кратковременное исправление, и компилятор сделает это через, но выдает ошибку сегментации (ядро сбрасывается), когда я пытаюсь запустить его. Похоже, мне нужно кое-что почитать и обновить, хотя с пространством имен, указателями и, возможно, заменой массивов на векторы. Такое ощущение, что если я сконцентрируюсь на них в первую очередь, это может исправить ошибку сегментации.

Ответы [ 2 ]

1 голос
/ 10 апреля 2020

Ваша переменная system объявлена ​​как

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

, которая является указателем на двумерный массив (который будет уменьшаться до float*** при передаче в функцию).

Ваш Time функция объявлена ​​как

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

, где 1-й аргумент должен быть float*.

Это означает, что этот вызов

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

на самом деле должен быть что-то вроде

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

При этом в вашем коде есть ряд проблем.

Для начала не делайте using namespace std;.

Кроме того, эта строка float sys[n]; не разрешена. Вы не можете иметь массивы переменной длины в c ++.

0 голосов
/ 10 апреля 2020
float* system[n][5]

system - это двумерный массив float* с, а не float с.

Так, другими словами, system распадается до float***, *system распадается до float**, **system распадается до float*, а ***system распадается до float.

Итак, компилятор верен. Вы передаете то, что распадается, на float** на Time(), который ожидает float*.

Вам нужно будет перенастроить свой код, чтобы передать правильную вещь, что бы это ни было.


Примечание: обратите внимание, что способ создания массивов недопустим C ++ и может вызвать проблемы позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...