Каков наилучший способ инициализации огромных постоянных многомерных массивов, которые не являются целыми числами? - PullRequest
0 голосов
/ 31 августа 2018

Я пытаюсь деформировать адаптированные функции алгоритма солнечной позиции (он же " spa "), созданный Военно-морской обсерваторией США, в мой код в классе, так что я могу легко просто вызвать один метод для вычисления солнечных позиций.

Этот код ниже взят из исходного кода USNO. Я пытаюсь инициализировать списки L_TERMS, B_TERMS и R_TERMS

#define L_COUNT 6
#define B_COUNT 2
#define R_COUNT 5
#define Y_COUNT 63

#define L_MAX_SUBCOUNT 64
#define B_MAX_SUBCOUNT 5
#define R_MAX_SUBCOUNT 40

enum {TERM_A, TERM_B, TERM_C, TERM_COUNT};
enum {TERM_X0, TERM_X1, TERM_X2, TERM_X3, TERM_X4, TERM_X_COUNT};
enum {TERM_PSI_A, TERM_PSI_B, TERM_EPS_C, TERM_EPS_D, TERM_PE_COUNT};
enum {JD_MINUS, JD_ZERO, JD_PLUS, JD_COUNT};
enum {SUN_TRANSIT, SUN_RISE, SUN_SET, SUN_COUNT};

#define TERM_Y_COUNT TERM_X_COUNT

const int l_subcount[L_COUNT] = {64,34,20,7,3,1};
const int b_subcount[B_COUNT] = {5,2};
const int r_subcount[R_COUNT] = {40,10,6,2,1};

const double L_TERMS[L_COUNT][L_MAX_SUBCOUNT][TERM_COUNT]=
 { ... }; // contains 3*(64+34+20+7+3+1) = 387 doubles
const double B_TERMS[B_COUNT][B_MAX_SUBCOUNT][TERM_COUNT]=
 { ... }; // contains 3*(5+2) = 21 doubles
const double R_TERMS[R_COUNT][R_MAX_SUBCOUNT][TERM_COUNT]=
 { ... }; // contains 3*(40+10+6+2+1) = 177 doubles

У меня проблемы с инициализацией массивов конструктором. Я попытался использовать список инициализации, но он не работает. Если я инициализирую массивы в конструкторе, все будет хорошо, но не попадет в область действия других методов, поскольку я не могу объявить их в заголовке. Я не могу инициализировать их как массив const int .

Есть ли лучший способ инициализации многомерного двойного массива const, о котором я не знаю?

Примечание: исходный код, написанный USNO, был написан на C, но я пытаюсь использовать его на C ++. Должен ли я просто включить их файл и вызвать вычислительную функцию?

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

Оказывается, в списке инициализации вы можете использовать () или {}, а не ({}). Так, например, инициализация массива должна быть сделана следующей строкой:

class Foo::Foo() : L_TERMS{{{ ... }}}, // rest of initialization

Вместо

class Foo::Foo() : L_TERMS( {{{ ... }}} ) // rest of initialization
0 голосов
/ 31 августа 2018

Вы абсолютно можете использовать список инициализатора. Что я люблю делать, когда занимаюсь такими вещами, так это начинать гораздо меньше. Начните с гораздо меньших массивов, чтобы им было легче управлять.

int main()
{
    const double d[2][3][4] =
    {
        {
            { 0.1, 0.2, 0.3, 0.4 },
            { 0.5, 0.6, 0.7, 0.8 },
            { 0.9, 1.0, 1.1, 1.2 }
        },
        {
            { 0.1, 0.2, 0.3, 0.4 },
            { 0.5, 0.6, 0.7, 0.8 },
            { 0.9, 1.0, 1.1, 1.2 }
        },
    };
}

Здесь мы объявляем d равным 2 x 3 x 4. Таким образом, мы можем использовать d[0] и d[1], а d[0][2] и d[1][2][3] - последний элемент.

Вот что печатают различные вещи, отмечая, что я ленив и только что объявил внешние массивы с теми же элементами:

std::cout << d[0][0][0] << ", " << d[1][0][0] << "\n"; // prints 0.1, 0.1
std::cout << d[0][2][3] << ", " << d[1][2][3] << "\n"; // prints 1.2, 1.2
std::cout << d[0][1][2] << ", " << d[1][1][2] << "\n"; // prints 0.7, 0.7

Надеюсь, это прояснит ситуацию. Обратите внимание, что нет причин оставлять строки, как у меня, я просто считаю, что их легче читать.

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