В вашем коде несколько проблем.
В C ++ собственный массив (например, askin
в main()
) преобразуется в указатель при передаче в функцию.Поэтому нет необходимости объявлять измерение в массиве в списке аргументов, НО все же необходимо передать второй аргумент, так как вы указываете размер.
Это означает, что функция C ++ должна иметь форму
void singlearrayd(double temp1[], int tempi, std::string str1)
или (эквивалентно)
void singlearrayd(double *temp1, int tempi, std::string str1)
Обратите внимание, что в качестве полного третьего имени я указал тип третьего аргумента как std::string
.Во многих случаях лучше избегать using namespace std
.
Вторая проблема заключается в том, что вы предполагаете, что индексирование массивов Fortran и индексирование массивов C ++ совпадают.В действительности индексирование массива Fortran основано на 1 (первый элемент массива по умолчанию имеет индекс один), а индексирование массива C ++ основано на 0 (первый элемент в массиве имеет нулевой индекс).Использование индексации массивов Fortran в C ++ вызывает неопределенное поведение, потому что оно будет обращаться к элементам за пределами допустимого диапазона.
Третья (потенциальная) проблема заключается в том, что ваша функция определяет две переменные с именем md_i
(одна в функции, а другая в цикле).Лучше избегать этого.
Обращение ко всему вышеперечисленному превратит вашу функцию в (полностью)
void singlearrayd(double temp1[], int tempi, std::string str1)
{
for (int md_i = 0; md_i < tempi; ++md_i) // note the differences here carefully
{
cout << temp1[md_i] << "," << str1 << "(" << md_i << ")";
}
}
Четвертая проблема заключается в том, что main()
в C ++ возвращает int
, а не void
.
Пятая проблема заключается в том, что main()
не инициализирует массивы до того, как singlearrayd()
напечатает их.В Фортране массивы, локальные для функции, (часто) инициализируются нулями.В C ++ они неинициализированы по умолчанию, поэтому доступ к их значениям (например, для их печати) дает неопределенное поведение.
int main()
{
double askin[21] = {0.0}; // initialise the first element. Other elements are initialised to zero
double fm[21] = {0.0};
singlearrayd(askin,21,"askin");
singlearrayd(fm,25,"fm");
}
Это заставит ваш код работать.Однако на практике возможны улучшения.Первое улучшение заключается в использовании стандартного контейнера, а не массива.Стандартные контейнеры знают свой размер, что позволяет упростить вашу функцию.Во-вторых, передайте нетривиальные аргументы (например, контейнеры или строки) по ссылке - и предпочтительно const
ссылку, если в аргумент не было внесено никаких изменений.В отличие от Fortran, где аргументы функции часто передаются по ссылке BY DEFAULT, необходимо БЕЗОПАСНО вводить ссылки в C ++.
#include <vector>
void singlearrayd(const std::vector<double> &temp1, const std::string &str1)
{
for (std::size_t md_i = 0; md_i < temp1.size(); ++md_i)
{
cout << temp1[md_i] << "," << str1 << "(" << md_i << ")";
}
}
int main()
{
std::vector<double> askin(21); // askin has 21 elements, initialised to zero
std::vector<double> fm(21);
singlearrayd(askin, "askin");
singlearrayd(fm, "fm");
}
C ++ контейнеры также поддерживают итераторы - которые на практике безопаснее и часто более эффективны - чемиспользуя индексирование массива.Я оставлю это в качестве упражнения для вас, чтобы научиться их использовать.
Ключевое сообщение, однако: не думайте, что простой механический перевод с Fortran на C ++ будет работать.Вы уже продемонстрировали подводные камни такого предположения.Потратьте время на изучение C ++ ПЕРЕД попыткой перевести слишком много кода с Fortran на C ++.Это необходимо как для правильной работы кода C ++, так и для его эффективной работы.