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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Многомерные массивы и указатели, Как получить адрес элемента массива 
V
    Опции темы
Dov
Дата 21.4.2007, 17:07 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

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



Fazil6, если тебе так сильно хочется поспорить или, что было бы лучше, поучиться чему-нибудь хорошему, то открой соответсвующую тему, зачем же здесь оффтопить.  smile 
По поводу этого.
Цитата(Fazil6 @  21.4.2007,  16:34 Найти цитируемый пост)
почему не приводится к int** ?

попробуй так:
Код

aa = (int**)a;
aa = reinterpret_cast<int**>(a);

Ну, а по поводу передачи двумерного массива в ф-цию в качестве аргумента, и здесь на форуме и в инете полным полно разных примеров. Нужно только поиском пользоваться.  smile  



--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
vinter
Дата 21.4.2007, 17:13 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

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



Цитата
попробуй так:код C++
1:
2:
  aa = (int**)a;
aa = reinterpret_cast<int**>(a);


так делать нельзя, они физически в памяти по разному расположены как ты себе представляешь обращение к элементам? вспоминаем арифметику указателей и понимаем почему написали ерунду.
Цитата(Dov @  21.4.2007,  17:07 Найти цитируемый пост)
Ну, а по поводу передачи двумерного массива в ф-цию в качестве аргумента, и здесь на форуме и в инете полным полно разных примеров. Нужно только поиском пользоваться.

тебе бы как раз не мешало бы их поочитать, прежде чем так яростно спорить


--------------------
Мой блог
PM MAIL WWW   Вверх
Dov
Дата 21.4.2007, 17:44 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

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



Цитата(vinter @  21.4.2007,  17:13 Найти цитируемый пост)
так делать нельзя

Блин, да что за день сегодня такой.  smile 
vinter, ты вопрос читал? Изначально вопрос звучал так:
Цитата(Fazil6 @  21.4.2007,  16:01 Найти цитируемый пост)
это скомпилится?

Я показал, что скомпилится. 
А описать указатель на двумерный массив можно так, например.
Код

int a[3][3] = {{0,1,2}, {3,4,5}, {6,7,8}};
int (*aa)[3];
    
aa = a;





--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
vinter
Дата 21.4.2007, 17:46 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

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



Цитата(Dov @  21.4.2007,  17:44 Найти цитируемый пост)
vinter, ты вопрос читал?

нет, я читал вашь спор, и исходил только из него.


--------------------
Мой блог
PM MAIL WWW   Вверх
FiMa1
Дата 21.4.2007, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата
Здесь указатель на указатель на int приводится к указателю на int.

Dov, вопросик в догонку - а как выполняется прведение указателя на указатель к у просто указателю.. я не нашел.. Ну в приведении double к int понятно дробная часть откидывается, а здесь не пойму как это срабатывает.. Подскажи плз.
PM   Вверх
Fazil6
Дата 21.4.2007, 18:50 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

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



Цитата(Dov @  21.4.2007,  17:07 Найти цитируемый пост)
Fazil6, если тебе так сильно хочется поспорить или, что было бы лучше, поучиться чему-нибудь хорошему, то открой соответсвующую тему, зачем же здесь оффтопить.

ты без конца отправляешь меня учиться чему-то (правда ты не говоришь чему именно). Я по твоему, ничего не понимаю, но внятно свою позицию ты отстоять не можешь. По твоему если я не согласен с высказываемыми тобой суждениям , то это офтоп? Мне кажется, что я могу доказать, что ты не прав, а добиться каких-то внятных объяснений почему я не прав от тебя я не могу. Постоянно отсылаешь к книгам... Можешь привести пример книги хоть одной, которая по твоему откроет мне глаза на проблемы многомерных массивов и связанных с ними указателей?

Dov, 
Я привел конкретный пример и спрашиваю "почему он не компилится?" Я не спрашиваю "как его скомпилировать?" Чувствуешь разницу?
 
reinterpret_cast - это ложь компилятору и с его помощью можно заставить много чего скомпилироваться. 

Цитата(Dov @  21.4.2007,  17:44 Найти цитируемый пост)
Я показал, что скомпилится. 
 
если исправить, то скомпилится , но если 
Цитата(Dov @  21.4.2007,  15:51 Найти цитируемый пост)
Имя массива а[][] имеет тип int**, т.е. указатель на указатель на int
, то мой пример должен компиллироваться без изменений. Я ведь пытаюсь использовать имя массива а[][] именно как  int**, но компилятор упорно отказывается. 

Цитата(Dov @  21.4.2007,  14:05 Найти цитируемый пост)
Ну, что же, apook, у тебя есть 3 варианта.1. Обосновать своё утверждение и доказать свою правоту, тогда получишь +1 в репу.2. Не обосновывать и ничего не доказывать, тогда получишь -1 в репу за необоснованый наезд.3. Ивиниться за необоснованый наезд, тогда не получишь ничего. 




PM MAIL   Вверх
apook
Дата 21.4.2007, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Прекращайте этот непонятный спор, я не доволен вашим поведением
это что-за тон, кто вам показал дурацкий пример наезжать друг на друга. smile


--------------------
Мои руки из дуба, голова из свинца ну и пусть ...
PM MAIL   Вверх
JackYF
Дата 22.4.2007, 00:09 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Цитата(apook @  21.4.2007,  19:54 Найти цитируемый пост)
я не доволен вашим поведением

Эта фраза мне определенно нравится...

Имхо, правда больше на стороне Fazil6 здесь.

Цитата(Fazil6 @  21.4.2007,  18:50 Найти цитируемый пост)
reinterpret_cast - это ложь компилятору и с его помощью можно заставить много чего скомпилироваться. 
 +1.

Цитата(Fazil6 @  21.4.2007,  18:50 Найти цитируемый пост)
Цитата(Dov @  21.4.2007,  15:51 Найти цитируемый пост)
Имя массива а[][] имеет тип int**, т.е. указатель на указатель на int

Массив вообще не имеет законченного типа, а уж тем более int**. Этот факт тоже не один раз проскакивал и выяснялся в темах.
Dov, имхо, ты не прав.


Это сообщение отредактировал(а) JackYF - 22.4.2007, 00:27


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Dov
Дата 22.4.2007, 02:26 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

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



Цитата(JackYF @  22.4.2007,  00:09 Найти цитируемый пост)
Dov, имхо, ты не прав.

JackYF, в чём я не прав? 
В этом?
Цитата(JackYF @  22.4.2007,  00:09 Найти цитируемый пост)
Массив вообще не имеет законченного типа, а уж тем более int**.

Так я этого никогда не говорил. Я говорил только про имя массива, которое содержит адрес первого элемента массива, т.е. является указателем. 
Если массив состоит из элементов типа int, то имя массива имеет тип int*, т. е является указателем на 
тип int.
Код

int ar[2]; // массив целых чисел
int* p; // указатель на целое
p = &ar[0]; // р присвоили адрес первого эл-та
р = ar; // то же самое 

Отсюда следует, что и &ar[0] и ar имеют тип  int*, т.к. являются адресами. Абсолютно то же самое можно сказать и про двумерный массив, который, по сути, является одномерным массивом, каждый элемент которого так же является одномерным массивом, и про трёхмерный и т.д.
Код

char* ar[]  = {"qwe", "rty", "asd"}; // одномерный массив типа char* 
char ar1[][4] = {"qwe", "rty", "asd"}; //  он же двумерный массив типа char

И в том, и в другом случае имя массива имеет тип  char**, так как содержит адрес первого элемента массива, который в свою очередь имеет тип char*.
Разыменуем и тот и другой и посмотрим:
Код

cout << *ar  << endl; // получили доступ к элементу ar[0]
cout << *ar1 << endl; // то же самое

Оба выдают одинаковый результат. Доступ к элементам абсолютно идентичен. Можно объявить этот массив и так, это ни на что не повлияет:
Код

char ar2[3][4] = { {'q', 'w', 'e'},  "rty",  {'a', 's', 'd'} };
cout << **ar2; // получили доступ к элементу ar2[0][0]


Показал на пальцах, но уж извиняйте, как смог. Добавлю только, что многие не понимают разницу между массивом и именем массива. 
Имя массива - это указатель, хотя и константный, но всё же указатель. Почему? Да хотя бы потому, что содержит адрес, а адреса могут хранить только указатели.
Массив - это последовательность элементов одного и того же типа, имеющих одно имя.
Отсюда следует, что имя массива это только часть массива, и что оно указывает на начало массива.

За сим откланиваюсь и иду спать, ибо лучше объяснить не смогу.  smile 




--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
FiMa1
Дата 22.4.2007, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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




Модератор: Сообщение скрыто.

PM   Вверх
JackYF
Дата 22.4.2007, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Цитата(Dov @  22.4.2007,  02:26 Найти цитируемый пост)
то имя массива имеет тип int*

Нет. Не имеет. Читаем Страуструпа и/или стандарт.



Цитата(Dov @  22.4.2007,  02:26 Найти цитируемый пост)
Отсюда следует, что и &ar[0] и ar имеют тип  int*

Нет, отсюда это не следует. Я тебе могу написать свой произвольный класс, который будет имитировать точно такое же поведение (возвращение элементов по индексу). Но у него явно не будет тип int*

Цитата(Dov @  22.4.2007,  02:26 Найти цитируемый пост)
cout << **ar2; // получили доступ к элементу ar2[0][0]

Ха. Это ты к первому элементу матрицы так можешь обратиться через [0][0], так как смещений нет.

Постараюсь показать, что a[x][y] не имеет тип int**
Следующий код принципиально неверен:
Код

int a[10][20];
for (int i = 0; i < 10; ++i)
  for (int j = 0; j < 20; ++j)
    a[i][j] = i*j;

int** b = reinterpret_cast<int**>(a);
for (int i = 0; i < 10; ++i)
  for (int j = 0; j < 20; ++j)
    cout << b[i][j] << ' ';


Вторая часть этого кода работать принципиально не будет.


Это сообщение отредактировал(а) JackYF - 22.4.2007, 12:17


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Xenon
Дата 22.4.2007, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Dov @  22.4.2007,  02:26 Найти цитируемый пост)
Если массив состоит из элементов типа int, то имя массива имеет тип int*, т. е является указателем на тип int.

Код

int arr [] = { 11, 40 };
int* pTr = arr; //неявное преобразование из int [] в int*

Следовательно утверждать, что имя массива имеет типа int* нельзя. К тому же похожий пример есть у Страуструпа - стр. 131

Добавлено @ 13:29
И вообще чего мы так спорим, если есть RTTI?
Код

int arr [] = { 10, 24 };
std::cout << typeid(arr).name();

Выдаст int [2], но никак не int*.

Это сообщение отредактировал(а) Xenon - 22.4.2007, 13:31


--------------------
user posted image  
PM MAIL   Вверх
Fazil6
Дата 22.4.2007, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

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



Цитата(Dov @  22.4.2007,  02:26 Найти цитируемый пост)
Показал на пальцах, но уж извиняйте, как смог. Добавлю только, что многие не понимают разницу между массивом и именем массива. Имя массива - это указатель, хотя и константный, но всё же указатель. Почему? Да хотя бы потому, что содержит адрес, а адреса могут хранить только указатели.

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

Цитата(Dov @  22.4.2007,  02:26 Найти цитируемый пост)

Код

char* ar[]  = {"qwe", "rty", "asd"}; // одномерный массив типа char* 
char ar1[][4] = {"qwe", "rty", "asd"}; //  он же двумерный массив типа char

И в том, и в другом случае имя массива имеет тип  char**, так как содержит адрес первого элемента массива, который в свою очередь имеет тип char*.

вопервых не имеет тип  char** ,  а может использоваться в таком качестве, но опустим эти лингвистические нюансы - дело намного хуже.  ar1 ну никак не   char**. И все потому, что кое кто действительно не понимает разницу между массивом и именем массива.

Цитата(Dov @  22.4.2007,  02:26 Найти цитируемый пост)
 Абсолютно то же самое можно сказать и про двумерный массив, который, по сути, является одномерным массивом, каждый элемент которого так же является одномерным массивом, и про трёхмерный и т.д.

вот именно, и что мы имеем? Имя ar1 это указатель на массив char[4]. Где здесь имя, которое можно представлять как указатель?
Запомни : имя двумерного массива интов - это указатель на массив интов, но не как не указатель на указатель на int именно по причине 
Цитата(Dov @  22.4.2007,  02:26 Найти цитируемый пост)
 разницу между массивом и именем массива


PM MAIL   Вверх
Xenon
Дата 22.4.2007, 18:05 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Опять же, RTTI :
Код

char ar1[][4] = {"qwe", "rty", "asd"};
std::cout << typeid(ar1).name();

Выдает char[3][4].  Нельзя приравнять два разных типа T[] и T* - это хоть и похожие вещи, но на самом деле разные.


--------------------
user posted image  
PM MAIL   Вверх
Dov
Дата 22.4.2007, 21:50 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

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



Ух, скока накатали. Сразу говорю, что всё ни асилю.  smile 
Цитата(JackYF @  22.4.2007,  12:05 Найти цитируемый пост)
Нет, отсюда это не следует. Я тебе могу написать свой произвольный класс, который будет имитировать точно такое же поведение (возвращение элементов по индексу). Но у него явно не будет тип int*

Оставлю без комментария, хотя этому перлу прямая дорога на башорг, имхо.

Цитата(JackYF @  22.4.2007,  12:05 Найти цитируемый пост)
Ха. Это ты к первому элементу матрицы так можешь обратиться через [0][0], так как смещений нет.

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

cout << **(ar1 + 1) //  доступ к эл-ту ar1[1][0]
cout << *(*(ar1+1)+2)// доступ к эл-ту ar1[1][2]
и т.д.

Цитата(JackYF @  22.4.2007,  12:05 Найти цитируемый пост)
Постараюсь показать, что a[x][y] не имеет тип int**

Каким образом ты это пытался показать, я так и не понял.  smile 

Цитата(JackYF @  22.4.2007,  12:05 Найти цитируемый пост)
Следующий код принципиально неверен
 Вторая часть этого кода работать принципиально не будет.

То, что код не верен, это правда. Но я опять не понял, что именно не работает? Не компилится или не приводится или вывод не работает или выводит, но не правильно? Что не работает?  smile Если хочешь, что бы выводился массив можешь так сделать, например:
Код
cout << *(int*)b + i * 20 + j << ' ';

Или тебе надо, что бы в виде таблицы выводилось? Скажи "принципиально"  smile , что тебе нужно.

Fazil6, весь твой пост оставляю без комментариев, кроме двух фраз, а именно:
Цитата(Fazil6 @  22.4.2007,  17:12 Найти цитируемый пост)
ar1 ну никак не   char**. И все потому, что кое кто действительно не понимает разницу между массивом и именем массива.

Цитата(Fazil6 @  22.4.2007,  17:12 Найти цитируемый пост)
Запомни : имя двумерного массива интов - это указатель на массив интов, но не как не указатель на указатель на int именно по причине разницу между массивом и именем массива

Эти, имхо, на башорг адназначна.  smile
 
Да, а по поводу этого:
Цитата(Fazil6 @  22.4.2007,  17:12 Найти цитируемый пост)
 Имя ar1 это указатель на массив char[4]. Где здесь имя, которое можно представлять как указатель?

Я уже говорил, но для тебя ещё раз повторю. ar1 это указатель на первый элемент массива, т.е. на строку(или массив, если хочешь) "qwe". А имя,  "которое можно представлять как указатель" звучит так(ты не поверишь) : ar1[0] или *ar1, как тебе больше нравится. 

Xenon, с тобой я соглашусь, конечно, но только  не сейчас. По той причине, что  ты не попадаешь в контекст текущей полемики. Здесь идёт разговор о типах данных в плане приведения типов...
 Что-то устал я уже, не могу правильно сформулировать, но это не важно. Ты в самом начале посмотри и всё поймёшь. 
Ну, типа того, что так сделать можно:
Код

char ar[3][4];
char* p = (char*)ar;

а так нельзя:
Код

char ar[3][4];
char[3][4] p = (char[3][4])ar;

А может и можно, но я не знаю как. Тогда покажи.  smile 

Камрады! Желаю всем удачи! 
А я из дискуссии выбываю. Притомился я тут с вами. Всем пока.  smile 


--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0688 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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