LINUX.ORG.RU

используй «нуль терминальные» последовательности указателей на «вектора» .

а вообще или оберни в обьект у которого есть поля размеры . или ещё как.

qulinxao ★★☆
()

а он отличается от любого другого указателя?

nokachi
()
Ответ на: комментарий от yoghurt

«Ошибка: cannot convert 'QwMatrixElement (*)[20]' to 'QwMatrixElement**' for argument '1' to 'void QwDrawMatrix(QwMatrixElement**, int, int)'»

puding
() автор топика

Ты хоть напиши как переменная объявлена и какая функция, ни черта же непонятно, что у тебя там за проблема

ilovewindows ★★★★★
()
Ответ на: комментарий от ilovewindows

const int QwMatrixWidth = 20;
const int  QwMatrixHeight = 20;

QwMatrixElement QwMatrix[QwMatrixHeight][QwMatrixWidth];

void QwDrawMatrix(QwMatrixElement** matrix, int n, int m) {

    //Производятся операции над элементами матрицы

}


puding
() автор топика
Ответ на: комментарий от yoghurt

Благодарю за развернутый и понятный ответ.

puding
() автор топика
Ответ на: комментарий от ilovewindows

QwDrawMatrix((QwMatrixElement**) QwMatrix, 20, 20)

Сегодня просто какой-то парад уникумов на ЛОРе. Ты знаешь, что статически аллоцированный T[][] и динамически аллоцированный Т** по-разному лежат в памяти?

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Может я не правильно задал вопрос. Смысл в том, чтобы задавать размер матрицы (например из GUI, const надо убрать), и чтобы функция принимала этот новый размер и учитывала при операциях с матрицей внутри своего тела.

puding
() автор топика
Ответ на: комментарий от ilovewindows

и что из этого ?

Из этого потом легенды слагают.

Ладно, так и быть. В качестве подсказки скажу, что T[][] - это реально двумерный массив, а вот Т** - всего лишь указатель на указатель.

yoghurt ★★★★★
()
Ответ на: комментарий от puding

Нет под рукой компилятора, тогда попробуй объявить QwMatrixElement** matrix и динамически выделить,все равно придется делать, это приколы компилятора, явное преобразование типов работало вроде как всегда.

ilovewindows ★★★★★
()
Ответ на: комментарий от puding

Смысл в том, чтобы задавать размер матрицы (например из GUI, const надо убрать)

В том виде, в котором оно сейчас, массив по размерам, идущим из GUI, ты не создашь, и убирание const тут не спасёт.

Память тебе надо выделять динамически, как вариант - сначала под массив указателей, потом заполнить его указателями уже на массивы объектов. Получим тот же самый T** (в данном случае - QwMatrixElement**).

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

Прочитай хоть какую-нибудь более менне приличную книжку по С++.

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

У реального двухмерного массива адреса в памяти нет, то бишь указателя ? зы. у меня браузер рисует Т и два квадратика - это реально ..., там что под квадратами ? это скобки что ли ?

ilovewindows ★★★★★
()
Последнее исправление: ilovewindows (всего исправлений: 1)
Ответ на: комментарий от puding

Ты должен передать размерности. Как это принято в Си++ - не знаю, но можно набыдлить элементарную обертку:

template<class T> class Array2D {
  int d1, d2;
  T *data;

  Array2D(int _d1, int _d2) : d1(_d2), d2(_d2) {}
  T& operator()(int i1, int i2) { return data[i1*d2 + i2]; }
};

Для протокола: я не предлагаю делать именно так, но общая идея такая. А трюк с T** - это скорее jagged array, совсем другая вещь.

tailgunner ★★★★★
()
Ответ на: комментарий от ilovewindows

У реального двухмерного массива адреса в памяти нет, то бишь указателя ?

Есть, просто у [][] для T[][] и T** разная семантика. T[][] представлен в памяти непрерывным куском.

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Это единственное определение «двумерного массива», которое я знаю. T** - это вообще не массив, T*[] - одномерный.

tailgunner ★★★★★
()
Ответ на: комментарий от yoghurt

Сегодня просто какой-то парад уникумов на ЛОРе.

Так конец августа на календаре. Школотроны уже вернулись из летних резерваций, но еще не успели отправиться в зимние.

anonymous
()
Ответ на: комментарий от tailgunner

как обычно, tailgunner единственный, кто не упоротым заходит в dev.

Ты должен передать размерности. Как это принято в Си++ - не знаю, но можно набыдлить элементарную обертку:

Всё правильно, если готового класса нет, то так и его велосипедят. Си++ — он же весь про то, как в очередной раз навелосипедить класс строк и класс матрицы.

Но можно и не париться и просто передать вектор векторов, да (jagged array). Если именно физическое расположение в памяти не критично и требования производительности не заставлябют из этого куска кода выжиматьв сё до последнего такта.

anonymous
()
Ответ на: комментарий от puding

Каков вопрос, такой и ответ

Может ты подскажешь?

Как передать указатель на динамический двумерный массив в функцию в C++?

Подскажу.

void tvoya_funkcia(TvoyDvumernyjMassiv* v);

anonymous
()
#include <stdio.h>
const int W=3;
const int H=3;
typedef int i33[W][H];
void f(i33 *a, int n, int m) {
  (*a)[n][m] = 1;
}
i33 A;
void p() { int i,j;
  for(i=0;i<W;i++) {
    for(j=0;j<H;j++)
      printf("%i ",A[i][j]);
    printf("\n");
  }
}
int main() {
  p(); f(&A,2,2); p();
  return 0;
}
anonymous
()
Ответ на: комментарий от anonymous

можно и не париться и просто передать вектор векторов, да (jagged array)

Но его и создавать надо специальным образом, а не new T[m][n].

tailgunner ★★★★★
()

Вы не против, если в мой однообразный список издевательств над крестами будет занесен этот топик целиком?

stevejobs ★★★★☆
()
Ответ на: комментарий от tailgunner

Это единственное определение «двумерного массива», которое я знаю. T** - это вообще не массив, T*[] - одномерный.

Разве доступ к элементу i,j в Т*[] не работает как *(base + i*rows + j)? Тогда по сути он не отличается от этого «единственного определения».

yoghurt ★★★★★
()
Ответ на: комментарий от stevejobs

Тут и плюсов то нет, а чистый С. Ну а советы с ** это конечно, неплохой подход. Свежая струя, так сказать :)

vromanov ★★★
()
Ответ на: комментарий от yoghurt

Разве доступ к элементу i,j в Т*[] не работает как *(base + i*rows + j)?

Всё-таки C++ как электрон — неисчерпаемый источник лулзов знаний.

rows у тебя компилятор волшебным образом должен угадать?

Попробуй скомпилировать

int f(int* v[])
{
	return v[0][0];
}

и подумать: если этот пример скомпилировался, то что этот факт может значить? Можно кончено просто спецификацию языка почитать, но раз присутствующие её не читали, то уже поздно. Так что думаем своей головой.

anonymous
()
Ответ на: комментарий от anonymous

int* v[]

Тождественно int**.

Я говорю о int v[][n].

rows у тебя компилятор волшебным образом должен угадать?

Обчепятка, cols конечно же.

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

Какой нафиг «размер строки»? Весь пойнт использования T** в том, чтобы размер строки не таскать.

Обращение arr[ i][j] к T *arr[] - это (*(arr+i) + j), заметь косвенность, которой у тебя нет ни в примере, ни в хотфиксе. Почитай уже приличный учебник по Си. Блин, да хоть какой-нибудь почитай.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от nanoolinux

непонятно, зачем тут передавать размер. Можно воспользоваться sizeof

Ну и тех, кто передает массивы по значению, а на виде const T& - бить лопатой по голове.

vromanov ★★★
()
Ответ на: комментарий от vromanov

непонятно, зачем тут передавать размер. Можно воспользоваться sizeof

Функция шаблонная, при передаче в неё T** sizeof уже не прокатит.

yoghurt ★★★★★
()

Короче, буду юзать C.

#include <stdio.h>
#include <stdlib.h>

int f(int** array) {

    return array[10][10];

}

int main(void)
{

    int nrows = 20;
    int ncolumns = 20;

    int i;

    int **array1 = malloc(nrows * sizeof(int *));
        for(i = 0; i < nrows; i++)
            array1[i] = malloc(ncolumns * sizeof(int));

        int x = f(array1);

    printf("Hello World!\n");
    return 0;
}

Все равно, юзал классы просто как контейнеры для свойств объекта.

puding
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.