![]() |
Модераторы: Daevaorn Страницы: (14) Все « Первая ... 7 8 [9] 10 11 ... Последняя »
( Перейти к первому непрочитанному сообщению ) |
![]() ![]() ![]() |
|
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
||||
|
||||
apook |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
для ясности в кавычках "" не видиш смайлик улыбающийся
-------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
|||
|
||||
Dov |
|
||||||||||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Ы-ы-ыы, машину разбил. Вернее три машины. Сначала одному задом въехал на заправке, а потом другому в зад заехал на светофоре. Хорошо хоть страховка есть. Ладно, переживём.
![]()
Я и сейчас это утверждаю. А где ты увидел противоречие? Да, я это говорил, не отрицаю. И буду говорить. А ещё я говорил, что тип int** это ни что иное, как указатель на указатель на int. Говорил??? Говорил. И что такое указатель на указатель на int тоже говорил. Могу ещё раз повторить. Это значит, что его значением может быть только адрес. Причём не просто какой-то адрес, а именно адрес указателя на int, т.е. такого указателя, который имеет тип int*.
Имя одномерного массива А[0], который является подмассивом двумерного массива А[3][3] является указателем потому, что хранит адрес первого элемента А[0][0]. Поэтому имя подмассива А[0] имеет тип int*, точно так же, как и &А[0][0]. Но ведь подмассив А[0] сам является первым элементом массива А. Имя массива А, в свою очередь, является указателем потому, что хранит адрес первого элемента, т.е. подмассива А[0]. И если имя подмассива А[0] имеет тип int*, то его адрес имеет тип int**, так как является указателем на указатель на int. Вот и получается, что имя массива А имеет тип int** и является указателем на указатель на int. Почему, опять же? Да всё потому же, ёлы-палы. Потому что адрес его первого элемента это указатель на указатель на int, имеющий тип int**. Это понятно? Что же мы имеем? Смотрите внимательно. Показываю последний раз. Больше повторять не буду. ![]() Если объект(или его имя, или переменная, не важно) имеет тип int, то его адрес имеет тип int*. Если объект имеет тип int*, то его адрес имеет тип int**. Если объект имеет тип int**, то его адрес имеет тип int***... И так до... Не знаю сколько, но очень долго. Теперь мы видим, что если имя массива имеет тип int**, то его адрес имеет тип int***. Вот почему я говорил, что адрес двумерного массива имеет тип int***. Но это в том примере не главное. Я хотел сказать другое. Имя массива не потому указатель, что его можно или нельзя присвоить какому-нибудь указателю(указатель не этим определяется), а просто потому, что оно хранит адрес. И последнее. Разыменование указателя, т.е. получение значения с адреса можно применить только к указателям. И если это можно проделать с именем массива, то почему его нельзя считать указателем? Опять же, это моё мнение. И я его высказываю, и пытаюсь объяснить свою точку зрения. В ответ же слышу только одно. Dov, ты не прав. Ну, допустим я не прав. Ну пусть тогда мне хоть один знаток стандарта объяснит, почему самолёты летают, а крыльями не машут. То есть, почему он пользуется именем массива, как указателем, когда разыменовывает его и получает доступ к значениям, а называть его указателем не хочет. Это я не про индексы говорю, а про звёздочки... Да, впрочем, ничего мне говорить не нужно. Я уже вижу руки, тянущиеся к клавиатуре, что бы напечатать три слова. Dov, ты не прав. Ладно, развлекайтесь тут без меня. Пойду лучше FiMa1`е помогу. FiMa1, вариант Anikmar`а, тот что с индексами, очень хороший. Если есть проблемы с пониманием работы указателей, то лучше, с моей точки зрения, использовать его. Но я так понимаю, что ты просто хочешь потренироваться в использовании указателей. Это правильно. Так и нужно сделать. Вот тебе переделаный вариант Anikmar`а.
А что нам может помешать создать динамический массив? ![]()
Так, вроде всё. Всем пока. ![]() -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
||||||||||
|
|||||||||||
Ln78 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
FiMa1 и все желающие, первую часть статьи (случай статического распределения памяти) написал, можешь посмотреть.
Dov, сочувтвия по поводу машин. В своём опусе, по странному стечению обстоятельств, я упоминал и тебя, и гаишников. Надеюсь, что в аварии я всё-таки не виноват ![]() Присоединённый файл ( Кол-во скачиваний: 34 ) ![]() |
|||
|
||||
apook |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Во бл.. поэия! Ln78 Не ожидал от тебя такого. еще бы в стихотворной форме че полинился? А вообще наверно познавательно но длинно, я устал читать.
-------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Я имел в виду ограниченность применения приведенного примера в том, что там априоре предполагается размещение массива в едином блоке памяти:
Примененный метод адресации по сути использует только указатель на базовый адрес: p[(i*N1+j)*N2+k]=321;, при универсальной работе - нужно применять разименование: *(*(*(a + i) + j) + k) Вот поэтому, я и написал, что вариант Ln78 будет работать, если массив объявлен статически либо единым блоком памяти (в последнем случае нельзя будет применить скобки, а только метод вычисления смещения) В приведенном вами последнем варианте вы выделили под трехмерный массив один большой блок памяти, тем самым закрыв себе возможность доступа к массиву стандартными средствами языка - через индексы. Поэтому вы естественно будете вынуждены считать смещение самостоятельно. Я не проверял, но почему-то уверен, что такой подход гораздо медленнее чем стандартный через квадратные скобки. Мне кажется, путаница в данной теме возникла именно из-за того, что многие уверены, что массив должен занимать единый блок памяти и его адрес является адресом первого элемента массива. Во многих случаях это так, но единого блока памяти может и не быть, поэтому вычисление смещения элемента путем прибавления какого-то числа к базовому адресу заведомо ошибочно и работает только в ограниченных случаях. Разыменование вида *(*(*(a + i) + j) + k) работает при любом способе объявления и организации массива - и статического (когда это действительно один большой блок памяти) и динамического - когда подмасивы могут находится где угодно. |
|||
|
||||
apook |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Статический массив (если он полностью статический) всегда будет занимать единый блок помяти... -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
||||
|
|||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
А я как сказал? Именно это я и подразумевал как само собой разумеющееся: Хотя конечно это на сегодняшний день это так, может появится какой-нить чудо-компилятор, который и статические массивы будет распихивать по дыркам в памяти - кто знает. ![]() Интересно, а если я объявлю достаточно громадный статический массив, для которого будет нехватать единого блока памяти. Программа не запустится? Или линкер ругнется? Лень проверять. |
|||
|
||||
Fazil6 |
|
||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
и где я сказал, что это одно и тоже? Это ты сказал?
хотя до этого утверждал, что имя двумерного массива это указатель на указатель, т.е. int** и вдруг оно уже int***. p это имя двумерного массива. никто не говорит, что имя массива нельзя использовать как указатель, только вот указатель на что... не думай, что если можно написать
то из этого можно сделать вывод, что p это int**. Первое разыменовывание возвращает int[3] , а второе int. ты ведь не станешь утверждать, что здесь
pa это int* или ppa - это int**... Или pa это int* ? вот тебе пример
с удовольствием ознакомлюсь с примером использования двумерного массива или его имени в качестве int**. Вполне сойдет ссылка на приводимые ранее примеры или свежачек какой-нить...
Имя двумерного массива содержит адрес инта, до значения которого можно добраться [0][0]. Т.е. по адресу, который асоциирован с именем двумерного массива лежит int. Так почему бы на основании этого не сделать вывод, что имя двумерного массива является типом int* ??? Много всякой чепухи можно напридумывать.... Это сообщение отредактировал(а) Fazil6 - 27.4.2007, 10:15 |
||||||||||||
|
|||||||||||||
FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Зачотная статья, имхо! Молодец! Остаток статьи, после "Он говорит про себя «Ужо тебе, озорник»" дочитывал ПАДСТАЛОМ... Небольшая очепятка на 2-й странице "И тип int, мы договорились считать тоже 4-х битным". В целом все написано доходчивым языком. Обязательно буду ждать серии второй. |
|||
|
||||
Anikmar |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Для краткости: говорим о двухмерных массивах. Это нельзя. Имя массива, хоть и приводится спокойно к **, но дальше компилятор ничего не знает о размерности массива. Когда компилятор встречает конструкцию вида:
То он подразумевает, что в p[1] находится указатель на массив интов. В соответствии с этим, если мы напишем конструкцию:
То работать так не будет. Так как присваивание только базового адреса массива, а в случае со статическим массивом - по сути адреса 1-го элемента не даст никакой информации об указателях на подмассивы. Поэтому, для того, чтобы использовать двуойной указатель его необходимо проинициализировать конкретными значениями. А так, как эти конкретные значения знает только компилятор, в том блоке, в котором определен массив, то получится нечто подобное:
Я только такой способ знаю статический массив привести к динамическому. Наверное есть и другие. Конструкции вида *(p + RowCount*i+j) Я считаю медленными и громоздкими |
||||||
|
|||||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Ой... зря ты это написал. Была раньше темка, где обсуждалась косвенно эта проблема. Тему сейчас не буду искать, а предложу скомпилить следующий код:
В обоих случаях буду выданы идентичные числа. Жду возражений ![]() Dov, ты не прав. Да, кстати - здесь четыре слова ![]() |
|||
|
||||
_stranger_ |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 52 Регистрация: 3.10.2006 Где: город-герой Киев Репутация: 2 Всего: 2 |
вот что говорит стандарт ISO/IEC14882 пункт 8.3.4.8
Dov ты все таки не прав... Это сообщение отредактировал(а) _stranger_ - 27.4.2007, 13:50 |
|||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
по вашему reinterpret_cast это спокойно приводится??? ![]()
и что? вопрос в том как это использовать наоборот
|
||||
|
|||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
В каком смысле? Запихать в него какие-то свои значения? Я не понял слово "наоборот"
Си хорош тем, что можно что угодно привести к чему угодно. Правда будет ли это работать - это вопрос. Именно поэтому я и написал, что привести то спокойно можно, только дальнейшее использование невозможно. Или вы с этим не согласны? Просто я так понял вопрос, что каким образом можно работать со статическим массивом как с двойным указателем. Я знаю только один способ и я его привел. Наоборот - я просто не понял, т.е. вы хотите использовать имя массива как двойной указатель? Т.е. какие действия вы хотите от него получить, чтобы такие же действия получать от двойного указателя? Имеем объявление int a[3][4]; int **p; Соответственно: Конструкция p[0] должна вернуть указатель на int Конструкция a[0] также вернет указатель на int Какие конкретно действия "наоборот" вас интересуют? |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |