Russian Qt Forum
Ноябрь 23, 2024, 22:54 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Как передать в функцию указатель на (двумерный) массив?  (Прочитано 15361 раз)
Martiro
Гость
« : Июль 20, 2011, 11:18 »

Есть 3 массива, из них один - двумерный, + int.
Как правильно написать вызов и саму процедуру по их заполнению?
Похожая тема не помогла. Непонимающий
Пытаюсь сделать так:
Код:
MainClass::MainClass()
{
   ...
   double EF[9];
   double V[6];
   ...
   long int kt1 = LGL / h1 + 1;
   double BL1[kt1 + 2][2];
   ...
   INTdBds (LGL, h1, EF, &V, &BL1, &kt1 );
   ...
}

void MainClass::INTdBds (double S, double h0, double NU, double *REZ, double *B, long int *i)
{
   ...
   *i = 2;
   ...
   *B[*i-1][ 0] = x1[0];
   *B[*i-1][ 1] = y1[0];
   *REZ[0] = x1[0];
   *REZ[1] = y1[0];
   *REZ[2] = z1[0];
   *REZ[3] = Zd[0];
}
Компилятор ругает:
Цитировать
no matching function for call to 'MainClass::INTdBds (double&, double&, double [9], double(*)[6], double(*)[(((unsigned int)(((int)kt1)+1))][2], long int*)'
candidates are: void MainClass::INTdBds(double, double, double*, double**, double**, long int*)
Совсем я запутался с этими указателями...
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Июль 20, 2011, 12:25 »

третий параметр ожидается double, а ты туда подставляешь массив;
чтоб передать указатель на двумерный массив, в сигнатуре функции поменяй на double B[][2] или double **B;

при передаче массива в качестве параметра писать перед ним & необязательно;
при обращении к элементам массива, даже если он и передан в виде указателя, ставить перед ними * не нужно
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
shirushizo
Гость
« Ответ #2 : Июль 20, 2011, 12:38 »

Ваша процедура:
Код:
void MainClass::INTdBds(double S, double ho, double *NU, double *REZ, double **B, long int &i)
   ...
   i = 2;
   ...
   B[i-1][ 0] = x1[0];
   B[i-1][ 1] = y1[0];
   REZ[0] = x1[0];
   REZ[1] = y1[0];
   REZ[2] = z1[0];
   REZ[3] = Zd[0];
}

Вызов:
Код:
INTdBds (LGL, h1, EF, V, BL1, kt1 );

Массив  - указатель на первый элемент (m == &m[0]) и в функции обычно передается как указатель, т.е. адрес первого элемента. Передавая параметры по ссылке мы также передаем адрес, но работаем с параметром как с обычной переменной, т.е. разадресация не нужна (i = 2; вместо *i = 2;).
« Последнее редактирование: Июль 20, 2011, 14:03 от shirushizo » Записан
Martiro
Гость
« Ответ #3 : Июль 20, 2011, 13:19 »

shirushizo, вот теперь всё понятно стало.  Смеющийся
Спасибо огромное!
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #4 : Июль 20, 2011, 13:29 »

Передавая параметры по ссылке мы также передаем адрес, но работаем с параметром как с обычной переменной, т.е. разадресация не нужна (i = 2; вместо *i = 2;).
Недоправили: B[*i-1] => B[i-1]
Записан
Martiro
Гость
« Ответ #5 : Июль 20, 2011, 13:42 »

...хотя поторопился я.
Пишу:
Цитировать
void MainClass::INTdBds(double S, double ho, double *NU, double *REZ, double **B, long int &i)
и вызываю: INTdBds (LGL, h1, EF, V, BL1, kt1 );
Пишет опять:
Цитировать
no matching function for call to 'MainClass::INTdBds (double&, double&, double [9], double[6], double[(((unsigned int)(((int)kt1)+1))][2], long int&)'
candidates are: void MainClass::INTdBds(double, double, double*, double*, double**, long int&)
Когда правлю на
Цитировать
void MainClass::INTdBds(double S, double ho, double *NU, double *REZ, double B[][2], long int &i)
Все собирается, но есть подозрение что в
Цитировать
MainClass::MainClass()
{
   ...
   INTdBds (LGL, h1, EF, V, BL1, kt1 );
   ...
}
BL1 - не заполнится... Или я не прав?
Записан
shirushizo
Гость
« Ответ #6 : Июль 20, 2011, 14:02 »

LisandreL, проглядел Улыбающийся.
Martiro, да в случае, double B[][2] будет передано значение, т.е. копия массива, а не указатель. Массив BL1 не изменится.

выдели память ручками:
Код:
double *EF= new double[9];
double *V=new double[6];

long int kt1 = LGL / h1 + 1;
double **BL1=new double[kt1 + 2];

for(int j=0;j<kt1 + 2; ++j) BL1[j]=new double[2];
и пробуй вариант:
Код:
void MainClass::INTdBds(double S, double ho, double *NU, double *REZ, double **B, long int &i)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Июль 20, 2011, 14:04 »

BL1 - не заполнится... Или я не прав?
У Вас данные организованы настолько безобразно, что трудно что-то понять/сказать. Вы не хотите использовать stl, контейнеры - хорошо, но тогда создайте структуру и засуньте в нее все потроха, напр

Код
C++ (Qt)
struct MYData {
 double EF[9];
 double V[6];
 int kt1;
 double * BL1;
};
 
MyData data;
data.kt1 = LGL / h1 + 1;
data.BL1 = new double[(data.kt1 + 2) * 2];
  ...
 INTdBds (LGL, h1, &data);
 ...
 delete [] data.BL1;
 
А то бегать с разбросанными массивами можно очень долго
« Последнее редактирование: Июль 20, 2011, 14:06 от Igors » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #8 : Июль 20, 2011, 14:07 »

Martiro, да в случае, double B[][2] будет передано значение, т.е. копия массива, а не указатель. Массив BL1 не изменится.
массивы никогда не передаются по значению
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Martiro
Гость
« Ответ #9 : Июль 20, 2011, 14:43 »

Я прошу прощения за это "безобразие". Позже переделаю. А пока, для экономии места, написал так.
И спрашиваю для того чтобы увидеть советы от людей лучше меня разбирающихся в Си. Поэтому заранее прошу прощения за неграмотность в некоторых вопросах.
Вы не хотите использовать stl, контейнеры - хорошо...
Так научите, подскажите! Однако, здесь использование сторонних библиотек не желательно.

Далее по теме:
Как после этого вытащить значения из BL1?

Создал массив на подобии того, как Вы советовали:
Код
C++ (Qt)
double * BL1 = new double[(kt1 + 2)*2];
пытаюсь заполнить например так:
Код
C++ (Qt)
BL1[0][0] = 1.0;
компилятор ругается:
Цитировать
invalid types 'double[int]' for array subscript
Оно и понятно. Массив создался одномерный. Как сделать двумерный?
« Последнее редактирование: Июль 20, 2011, 15:03 от Martiro » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #10 : Июль 20, 2011, 14:55 »

Вы не хотите использовать stl, контейнеры - хорошо...
Так научите, подскажите!
вряд ли на этом форуме будут учить как пользоваться stl или контейнерами. для этого есть куча самых разных книг и статей в интернете.
Код
C++ (Qt)
double * BL1 = new double[(kt1 + 2)*2];
пытаюсь заполнить например так:
Код
C++ (Qt)
BL1[0][0] = 1.0;
компилятор ругается:
Цитировать
invalid types 'double[int]' for array subscript
Оно и понятно. Массив создался одномерный. Как сделать двумерный?
Код
C++ (Qt)
int rows = kt1 + 2;
double **BL1 = new double *[rows];
for (int i = 0; i < rows; ++i)
   BL1[i] = new double [2];
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #11 : Июль 20, 2011, 15:00 »

Я прошу прощения за это "безобразие". Позже переделаю. А пока, для экономии места, написал так.
И спрашиваю для того чтобы увидеть советы от людей лучше меня разбирающихся в Си. Поэтому заранее прошу прощения за неграмотность в некоторых вопросах.
Вы не хотите использовать stl, контейнеры - хорошо...
Так научите, подскажите!

Далее по теме:
Как после этого вытащить значения из BL1?

Создал массив на подобии того, как Вы советовали:
Код
C++ (Qt)
double * BL1 = new double[(kt1 + 2)*2];
пытаюсь заполнить например так:
Код
C++ (Qt)
BL1[0][0] = 1.0;
компилятор ругается:
Цитировать
invalid types 'double[int]' for array subscript
Оно и понятно. Массив создался одномерный. Как сделать двумерный?
Укуси меня пчела))

Код:
Оно и понятно. Массив создался одномерный. Как сделать двумерный?
Код
C++ (Qt)
int rows = 3;
int columns = 3;
double **Arr = new double*[rows];
   for (int i = 0; i < rows; ++i)
       Arr[i] = new double[columns];
 
kambala меня опередил))

А вообще, лучше использовать уже готовые контэйнеры.
В качестве двумерного массива могу посоветовать такую реализацию:
Код
C++ (Qt)
#ifndef ARRAY2D_H
#define ARRAY2D_H
 
#include <stdexcept>
 
template <class T>
class Array2D
{
public:
   typedef size_t size_type;
   Array2D();
   Array2D(size_type rows, size_type columns, const T &initValue = T());
   Array2D(const Array2D<T> &other);
   ~Array2D();
   T &operator() (size_type row, size_type column) throw(std::out_of_range);
   const T &operator() (size_type row, size_type column) const throw(std::out_of_range);
   Array2D &operator=(const Array2D<T> &array);
   void resize(size_type rows, size_type columns);
   bool swapRows(size_type i, size_type j);
   size_type columns() const { return m_columns; }
   size_type rows() const { return m_rows; }
private:
   T **m_arr;
   size_type m_rows;
   size_type m_columns;
};
//-----------------------------------------------------------------------------
 
template <class T>
Array2D<T>::Array2D()
   : m_arr(0), m_rows(0), m_columns(0)
{
}
//-----------------------------------------------------------------------------
 
template <class T>
Array2D<T>::Array2D(size_type rows, size_type columns, const T &initValue)
   : m_rows(rows), m_columns(columns)
{
   m_arr = new T*[m_rows];
   for (size_type i = 0; i < m_rows; ++i)
       m_arr[i] = new T[m_columns];
 
   for (size_type i = 0; i < m_rows; ++i) {
       for (size_type j = 0; j < m_columns; ++j) {
           m_arr[i][j] = initValue;
       }
   }
}
//-----------------------------------------------------------------------------
 
template <class T>
Array2D<T>::Array2D(const Array2D<T> &other)
{
   m_rows = other.rows();
   m_columns = other.columns();
 
   m_arr = new T*[m_rows];
   for (size_type i = 0; i < m_rows; ++i)
       m_arr[i] = new T[m_columns];
 
   for (size_type i = 0; i < m_rows; ++i) {
       for (size_type j = 0; j < m_columns; ++j) {
           m_arr[i][j] = other(i, j);
       }
   }
}
//-----------------------------------------------------------------------------
 
template <class T>
Array2D<T>::~Array2D()
{
   for (size_type i = 0; i < m_rows; ++i)
       delete []m_arr[i];
   delete []m_arr;
}
//-----------------------------------------------------------------------------
 
template <class T>
Array2D<T> &Array2D<T>::operator=(const Array2D<T> &array)
{
   if (this == &array) {
       return *this;
   }
   if (m_rows != array.rows() || m_columns != array.columns()) {
       for (size_type i = 0; i < m_rows; ++i)
           delete []m_arr[i];
       delete []m_arr;
 
       m_rows = array.rows();
       m_columns = array.columns();
 
       m_arr = new T*[m_rows];
       for (size_type i = 0; i < m_rows; ++i)
           m_arr[i] = new T[m_columns];
   }
 
   for (size_type i = 0; i < m_rows; ++i) {
       for (size_type j = 0; j < m_columns; ++j) {
           m_arr[i][j] = array(i, j);
       }
   }
   return *this;
}
//-----------------------------------------------------------------------------
 
template <class T>
T &Array2D<T>::operator ()(size_type row, size_type column) throw(std::out_of_range)
{
   if ((row >= m_rows) || (column >= m_columns))
       throw std::out_of_range("Array2D: out of range!");
 
   return m_arr[row][column];
}
//-----------------------------------------------------------------------------
 
template <class T>
const T &Array2D<T>::operator ()(size_type row, size_type column) const throw(std::out_of_range)
{
   if ((row >= m_rows) || (column >= m_columns))
       throw std::out_of_range("Array2D: out of range!");
 
   return m_arr[row][column];
}
//-----------------------------------------------------------------------------
 
template <class T>
void Array2D<T>::resize(size_type rows, size_type columns)
{
   if (rows != m_rows || columns != m_columns) {
       T **newArr = new T*[rows];
       for (size_type i = 0; i < rows; ++i)
           newArr[i] = new T[columns];
 
       for (size_type i = 0; i < rows; ++i) {
           for (size_type j = 0; j < columns; ++j) {
               newArr[i][j] = T();
           }
       }
 
       size_type r = (m_rows > rows) ? rows : m_rows;
       size_type c = (m_columns > columns) ? columns : m_columns;
 
       for (size_type i = 0; i < r; ++i) {
           for (size_type j = 0; j < c; ++j) {
               newArr[i][j] = m_arr[i][j];
           }
       }
 
       for (size_type i = 0; i < m_rows; ++i)
           delete []m_arr[i];
       delete []m_arr;
       m_arr = newArr;
 
       m_columns = columns;
       m_rows = rows;
   }
}
//-----------------------------------------------------------------------------
 
template <class T>
bool Array2D<T>::swapRows(size_type i, size_type j)
{
   if ((i >= m_rows) || (j >= m_rows))
       return false;
 
   if (i == j)
       return true;
 
   T *a = m_arr[i];
   m_arr[i] = m_arr[j];
   m_arr[j] = a;
   return true;
}
//-----------------------------------------------------------------------------
 
#endif // ARRAY2D_H
 
« Последнее редактирование: Июль 20, 2011, 15:20 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Martiro
Гость
« Ответ #12 : Июль 20, 2011, 15:13 »

Код
C++ (Qt)
int rows = kt1 + 2;
double **BL1 = new double *[rows];
for (int i = 0; i < rows; ++i)
   BL1[i] = new double [2];
Спасибо. Теперь собирается. Только теперь при
Код
C++ (Qt)
BL1[0][0] = 1.0;
вылетает на Segmentation fault.
Записан
Martiro
Гость
« Ответ #13 : Июль 20, 2011, 15:16 »

m_ax, спасибо за классы! Если сейчас ничего не получится, буду их прикручивать. Смеющийся
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #14 : Июль 20, 2011, 15:20 »

ищи ошибку у себя - может где-то обращаешься за границу массива. и не забудь освободить память в конце работы массива.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.729 секунд. Запросов: 23.