2015-03-21 3 views
1

Например, у меня есть функция, как (потребность c99)Как вызвать функцию с параметром, напечатанным высокоразмерным массивом, передав указатель?

void fun(int nx, int ny, double a[nx][ny]) 
{ 
    // some code here 
} 

и у меня есть указатель

double *p = new double[nx * ny]; 

и использовать его для вызова функции, как

fun(nx, ny, p); // error for the type is not matched 

Как сделай это? Разрешено преобразование любого типа.

+0

Конечно. Указатель на двойник принципиально не совпадает с 2D-массивом. –

+0

вы передаете указатель на одномерный массив, так как это не может работать так – Hristo

+0

Ваша функция fun принимает двумерный массив удвоений, тогда как вы определяете p как одномерный массив удвоений. Это принципиально неправильно. – therainmaker

ответ

2

То, что вы хотите, невозможно в C++, потому что C++ требует, чтобы размеры типов массива составляли константы времени компиляции. C99 не имеет этого ограничения, поэтому объявление функции

void fun(int nx, int ny, double a[nx][ny]); 

действителен C99, но не является допустимым C++. Кстати, в C99, правильный вызов этой функции будет выглядеть следующим образом:

int nx = ..., ny = ...; 
double (*matrix)[ny] = malloc(nx*sizeof(*matrix)); 
fun(nx, ny, matrix); 

Теперь у вас есть две возможности:

  1. Используйте C для вашего многомерного массива материала.

  2. Используйте обходной путь C++ для этого.


Самый простой C++ обходной путь будет vector<vector<double> >. Тем самым вы избегаете хлопот выделения памяти самостоятельно, однако строки в вашей 2D-матрице не являются последовательными.


Вы можете также использовать два слоя косвенность так:

double **matrix = new double*[nx]; 
for(int i = 0; i < ny; i++) matrix[i] = new double[ny]; 

и объявить функцию

void fun(int nx, int ny, double** a); 

Обратите внимание, что вам нужно один дополнительный массив индексов в дополнение к массивам которые хранят данные. Тем не менее, вы можете использовать один большой массив для хранения данных:

double** matrix = new double*[nx]; 
double* storage = new double[nx*ny]; 
for(int i = 0; i < ny; i++) matrix[i] = &storage[ny*i]; 

Окончательное Возможное решение является, чтобы сделать расчет индекса самостоятельно:

void fun(int nx, int ny, double* twoDArray) { 
    //access the array with 
    twoDArray[x*ny + y]; 
} 

//somewhere else 
double* matrix = new double[nx*ny]; 
fun(nx, ny, matrix); 

Это именно то, что C99 работает под капотом с кодом наверху, но со значительно меньшей проверкой типов.

0

Попробуйте это:

void fun(int nx, int ny, double** a){ 
// some code here 
// Get the element in this way: double myD = a[i][j]; 
} 

И в Main:

double** a = new double*[nx]; 
for (int i = 0; i < nx; i++) 
{ 
    a[i] = new double[ny]; 
} 

И вызовите функцию:

fun(nx, ny, a); 

или если вы хотите передать массив:

void fun(int nx, int ny, double* a){ 
int dim = nx*ny; 
double myD = a[i]; 
} 
0

Нет, вы не можете передать 1d-массив (или указатель на один) функции, объявленной для принятия 2d-массива.

Если необходимо выделить 2d массив динамически, что вы можете сделать, это:

// ny can be runtime variable in c99, but must be compile time constant in c++ 
constexpr int ny = 10; 
int nx = 10; 
double (*p)[ny] = new double[nx][ny]; 
fun(nx, ny, p); 

Если вы хотите использовать 1d массив, как это, вам нужно изменить fun принять 1d массив вместо этого:

// note that double a[] or double* a param would be identical, nx*ny is just for documentation 
void fun(int nx, int ny, double a[nx*ny]) 
    // access indices [i][j] like this: a[nx*j + i] 

В C++ однако я бы рекомендовал вам скрыть любое динамическое распределение за абстракцией, которая будет управлять памятью. Скажем, класс Matrix в этом случае.

Смежные вопросы