Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Задача с указателями 
:(
    Опции темы
Dark Elf
Дата 3.8.2005, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 576
Регистрация: 26.12.2003
Где: Брисбен

Репутация: 9
Всего: 10



Привет всем

Есть такая задача - есть следующий код:

Код

    long double s[4][4];
    bool result = Zeidel(s, b, mbx, n);


Выдаёт ошибки:
[C++ Error] Approximator.cpp(185): E2034 Cannot convert 'long double ( *)[4]' to 'long double * *'
[C++ Error] Approximator.cpp(185): E2342 Type mismatch in parameter 'a' (wanted 'long double * *', got 'long double ( *)[4]')

Вопрос: как передать данный массив в функцию Zeidel?

Заранее спасибо

Оффтоп:сегодня все интересуются указателями я смотрю smile


--------------------
PM MAIL WWW ICQ Skype GTalk Jabber MSN   Вверх
LPBOY
Дата 3.8.2005, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



У тебя видимо первый параметр функции типа long double **, а должен быть типа long double (*)[4]

Вообще двухмерный массив передается в функцию как указатель на одномерный массив.
long double ** это не очень логично.

Напиши такой прототип Zeidel(long double (*arr)[4], /*...*/)

Это сообщение отредактировал(а) LPBOY - 3.8.2005, 19:07
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
Dark Elf
Дата 3.8.2005, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 576
Регистрация: 26.12.2003
Где: Брисбен

Репутация: 9
Всего: 10



Функцию я переделать могу - но мне нужно будет передавать и long double [5][5] и т.д. я бы хотел что-то универсальное т.к. выяснил что boost::multi_array не катит smile


--------------------
PM MAIL WWW ICQ Skype GTalk Jabber MSN   Вверх
Kaskad
Дата 3.8.2005, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 324
Регистрация: 24.9.2004

Репутация: нет
Всего: 3



Цитата(LPBOY @ 3.8.2005, 19:03)
Вообще двухмерный массив передается в функцию как указатель на одномерный массив.

а трёх и более мерный так же? smile
И зачем скобки:
int *[4]
int (*)[4]

в чём фишка? smile


--------------------
Well come to America!
PM MAIL   Вверх
LPBOY
Дата 3.8.2005, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



Указатели на массивы с разными размерами - это разные типы... Вывод один: писать шаблон...
Сейчас еще подумаю и напишу че-нить smile
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
LPBOY
Дата 3.8.2005, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



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

Кстати если ты собирался "передавать и long double [5][5] и т.д" почему не передавал
в параметрах размеров? С помощью шаблонов это можно красиво избежать.
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
Dark Elf
Дата 3.8.2005, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 576
Регистрация: 26.12.2003
Где: Брисбен

Репутация: 9
Всего: 10



Ты имеешь в виду так:

Код

template <size_t M, size_t N>
bool Approximator::Zeidel(long double a[M][N], long double *b, long double *x, int n)


Тут возникает следуюущая проблема:

Как сделать так?

int n = 5;
long double ** x = new long double[5][5];

Т.е. как создавать многомерные динамические массивы?

Оффтоп:ой как плохо что для Борланда нету boost::multi_array smile


--------------------
PM MAIL WWW ICQ Skype GTalk Jabber MSN   Вверх
Void
Дата 3.8.2005, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Dark Elf
Не печалься! smile Я вот только что изобрел простенький адаптер для двумерных массивов, можно еще немного подумать и изловчиться с многомерными:
Код
#include <iostream>

template <typename T, unsigned Rows, unsigned Columns>
class matrix {
    T m[Rows][Columns];
public:
    T *operator [](unsigned i) { return &m[i][0]; }
    const T *operator [](unsigned i) const { return &m[i][0]; }
};

template <typename T>
class matrix_ref {
    T *arr_ref;
    unsigned rows_, cols_;
public:
    template <unsigned Rows, unsigned Columns>
    matrix_ref(matrix<T, Rows, Columns> &m) :
        arr_ref(m[0]), rows_(Rows), cols_(Columns) { }
    T *operator [](unsigned i) { return &arr_ref[cols_ * i]; }
    unsigned rows() const { return rows_; }
    unsigned cols() const { return cols_; }
};

template <typename T>
class matrix_cref {
    const T *arr_ref;
    unsigned rows_, cols_;
public:
    template <unsigned Rows, unsigned Columns>
    matrix_cref(const matrix<T, Rows, Columns> &m) :
        arr_ref(m[0]), rows_(Rows), cols_(Columns) { }
    const T *operator [](unsigned i) const { return &arr_ref[cols_ * i]; }
    unsigned rows() const { return rows_; }
    unsigned cols() const { return cols_; }
};

void foo(matrix_cref<int> m) {
    std::cout << m.rows() << " x " << m.cols() << std::endl;
    for (unsigned i = 0; i < m.rows(); ++i) {
        for (unsigned j = 0; j < m.cols(); ++j)
            std::cout << m[i][j] << " ";
        std::cout << std::endl;
    }
}

int main() {
    matrix<int, 5, 6> m;
    for (int i = 0; i < 5; ++i)
        for (int j = 0; j < 6; ++j)
            m[i][j] = i + j;
    foo(m);
}


Это сообщение отредактировал(а) Void - 3.8.2005, 19:50


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
LPBOY
Дата 3.8.2005, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



Цитата(Dark @ 3.8.2005, 19:32)
Ты имеешь в виду так:
template <size_t M, size_t N>
bool Approximator::Zeidel(long double a[M][N], long double *b, long double *x, int n


Нет так не будет работать, надо так
Код

template<size_t x, size_t y, typename T>
bool Zeidel(T (&arr)[x][y])

Передавать надо ссылку на массив.

Цитата(Dark @ 3.8.2005, 19:32)
как создавать многомерные динамические массивы?

Ну если тебе нужны еще и динамические массивы, передавай отдельно размер... а шаблоны тогда не пойдут.
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
Dark Elf
Дата 3.8.2005, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 576
Регистрация: 26.12.2003
Где: Брисбен

Репутация: 9
Всего: 10



LPBOY - спасибо smile

Void - я сам в своё время написал двумерный массив, правда с использование оператора () например

MyArray(3,2) = 7;

но хотел просто обойтись стандартными средствами


--------------------
PM MAIL WWW ICQ Skype GTalk Jabber MSN   Вверх
Void
Дата 3.8.2005, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Dark Elf
А зачем? Любой адаптер будет в 50-100 строчек, и при этом удобнее в использовании и типобезопаснее кода с указателями. Шаблонный вариант LPBOY тоже неплох, но он ведет к генерации экземпляра функции Zeidel для каждой размернсоти массива. Если тебя это не волнует - имхо, это наилучший вариант.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
LPBOY
Дата 3.8.2005, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



Цитата(Dark @ 3.8.2005, 20:03)
LPBOY - спасибо

Вообще-то я, в отличие от Void'a ничего такого не предложил... Только пару советов попытался дать...
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
LPBOY
Дата 3.8.2005, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



Kaskad,
Цитата(Kaskad @ 3.8.2005, 19:10)

а трёх и более мерный так же? 


Если мы передаем в функцию массив, то происходит преобразование массива в указатель.
Поэтому следующие объявления функций:
Код

void fun1(int arr[5]); //массив преобразуется в указатель на int
void fun2(int *);

абсолютно эквивалентны.
2-хмерный массив, можно сказать что это одномерный массив элементами которого являются
другие одномерные массивы. Поэтому после преобразования получаем указатель на одномерный массив.
Код

void fun1(int arr[5][5]); => void fun2(int (*)[5]);

Аналогично с 3-хмерными массивами
Код

void fun1(int arr[5][5][5]); => void fun2(int (*)[5][5]);


Цитата(Kaskad @ 3.8.2005, 19:10)

И зачем скобки:
int *[4]
int (*)[4]

в чём фишка?

Объявление int (*arr)[5]; означает указатель на массив из 5-ти элементов int.
А без скобок: int *arr[5]; значит массив из 5-ти указателей на int.
Если понятно почему, остальное можешь не читать...

Б.Эккель предлагает так читать такие выражения:
-сначала начинаем читать от имени переменной (т.е. arr)
-затем идем направо пока не встретим скобку
-затем налево опять пока не встретим скобку, затем опять направо и т.д. и попутно произносим то что встречается на пути smile
* произносим "указатель"
[5] произносим "массив из 5 элементов"

Например: int (*arr)[5],
начинаем от имени переменной (говорим "arr это...")
теперь идем направо и сразу же встречаем скобку (пока молчим потому что ничего не встретили),
идем налево пока не встретим другой скобки, и попутно мы встретили * поэтому продолжаем "arr это... указатель..."
Встретили скобку опять идем направо, встречаем [5], поэтому продолжаем "arr это... указатель...на массив из 5 элементов"
Идем налево, встречаем int и заканчиваем "arr это... указатель...на массив из 5 элементов... типа int"

В случае int *arr[5] получится "arr это... массив из 5-ти элементов... типа int*(т.е. указателей на int)"

Теперь чуть-чуть посложнее void * (*(*fp)(int))[5];
(int) - читается "функция принимающая аргумент типа int"
Читаем "fp это... указатель... на функцию принимающую аргумент типа int... которая возвращает указатель... на массив из 5-ти элементов
... типа void* (т.е. указателей на void)"

А такие выражения int (*)[4], в которых пропущены имена переменных означают соответствующие типы.
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
comcon1
Дата 4.8.2005, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

Репутация: 12
Всего: 17



А почему бы в духе C не передавать long ***a в функцию. А массив как-нибудь так:
Код

long **arr;
arr = new (long*)[n];
for (int i=0; i < n; ++i)
   arr = new long[n];
// задание массива
arr[0][0] = 1;
...
arr[n-1][n-1] = 12;
/

function(&arr, n);

Ведь это, по-моему самое простое..

2 LPBOY - клевая цитатка.


--------------------
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0721 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.