![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Привет всем!
Читаю "Программирование на языке Си" Афанасьева, появился вопрос... Автор пишет: "Следующие объявления переменных"
реализуют определенную схему размещения указателей на двумерный массив. Согласно этой схеме доступ к элементу a[0][0] можно получить по указателям a, p, pa при помощи следующих ссылок: a[0][0], *a, **a[0], *p, **pa, *p[0]. Уже на этапе инициализации массива int *pa[3] = { a, a[1], a[2] }; компилятор генерит error: 'initializing' : cannot convert from 'int [3][3]' to 'int *'. Помогите, пожалуйста, разобраться... |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
||||
|
||||
FiMa1 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Спасибо, но мне изначально было понятно, что в выражении int *pa[3] = { a, a[1], a[2] }; пытаются проинициализировать массив указателей целыми значениями.. Хорошо немного переформулирую вопрос. Есть следующие объявления переменных:
В данном случае, инициализация массива p указателями на элементы ОДНОМЕРНОГО массива a представлена второй строчкой кода. Теперь есть объявление МНОГОМЕРНОГО массива:
Как правильно проинициализировать массив указателей int *pa[3] элементами a[0][0], a[1][0] и a[2][0] ? |
||||||
|
|||||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Попробуйте так:
А инициализация {....} на сколько я помню допускается только константами (могу ошибаться - не помню, всегда инициализировал только константами, поэтому вопроса не возникало) |
|||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
FiMa1, выбирай:
-------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Ok, Dov, спасибо! До первого варианта уже сам додумался, а вот вариант int *pa[3] = { (int*)a, a[1], a[2] }; мне непонятен ... Здесь что указатель приводится к указателю на int? Не понимаю как это работает, поясните плз...
Anikmar, а что Вас смутило? Где используются НЕ константы? Это сообщение отредактировал(а) FiMa1 - 21.4.2007, 13:23 |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Смутило, что a[...] может быть не константный. Но я не уверен - поэтому и написал, что точно не уверен. Хотя если массив объявлен статическим - то наверное константы... Просто ни разу так не делал - поэтому и засомневался. |
|||
|
||||
apook |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Это ни кчемный вариант просто лажа какая-то Вот самый правильный вариант
-------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
||||
|
|||||
dizzy1984 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
Насколько я знаю инициализатором переменной в си и си++ выступает любое выражение.
Т.е вы можете, например, использовать вызов функции.
|
|||
|
||||
Dov |
|
||||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Здесь указатель на указатель на int приводится к указателю на int. Имя массива а[][] имеет тип int**, т.е. указатель на указатель на int. Мы его приводим к типу int*, т.е. указатель на int. Почему? Потому, что каждый элемент массива pa[3] имеет тип int*, т.е. указатель на int. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
||||
|
|||||
FiMa1 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
apook, извини, но я не совсем согласен.... Этот вариант можно назвать самым правльным лишь только с точки зрения читабельности кода. Здесь явно задано, что мы берем адрес элемента [ 0 ][ 0 ] массива а и присваиваем его первому элементу-указателю массива и т.д. для остальных элементов. Тем не менее запись int *pa[3] = { a[0], a[1], a[2] }; это абсолютно тоже самое тому, что ты написал, т.к. символическое имя a массива - это уже по-сути "скрытый" указатель на первый элемент данного массива. Т.о. указание амперсанда & в начале каждого из элементов a не обязательно. А вот по-поводу никчемности варианта int *pa[3] = { (int*)a, a[1], a[2] }; вопрос открытый.. Ведь это работает... Dov однозначно рулит!!! Ему пасиб! Всем оставшимся не равнодушными тоже спасибо. Топик закрыт... Это сообщение отредактировал(а) FiMa1 - 21.4.2007, 13:59 |
||||||
|
|||||||
apook |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
FiMa1 Да ты че не врубаешся в такую ерунду
int a[ 3 ] Dov привел к int *a это сущей воды пурга,
если знаешь че тогда спрашиваещ ![]() -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
|||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Ну, что же, apook, у тебя есть 3 варианта. 1. Обосновать своё утверждение и доказать свою правоту, тогда получишь +1 в репу. 2. Не обосновывать и ничего не доказывать, тогда получишь -1 в репу за необоснованый наезд. 3. Ивиниться за необоснованый наезд, тогда не получишь ничего. Желаю удачи. ![]() -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
apook |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
зачем вносить путанницу вот этим
вариантом. он вообще тогда не доделан надо так
Не надо мугать меня минусами тебе во всякой ерунде наезды чудятся -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
||||
|
|||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Я тебя не пугаю, а учу правилам хорошего тона. Ты должен уметь отвечать за свой базар. Если ты мои слова называешь 'пургой' и 'какой-то лажей', то потрудись, хотя бы это обосновать. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
apook |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Вынужден признать что моя решчь может показаться наездом
тада извиняй. Но не надо ни минусов не плюсов это не тот случай Dov "Черт возьми" надеюсь ты не в обиде..... Это сообщение отредактировал(а) apook - 21.4.2007, 14:29 -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
|||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Принято, проехали. ![]() -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
Rockie |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1143 Регистрация: 23.4.2006 Репутация: 8 Всего: 31 |
dizzy1984, если сигнатура функции позволяет, то конечно. Но в данном случае
-------------------- Чтобы иметь большой гардероб - надо иметь большой гардероб. |
||||
|
|||||
dizzy1984 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
И в данном случае все верно. Дело в том, что необходимость указания приведения присуща только компиляторам cи++ в си void* приводится к любому другому указателю и без явной указки. Пардон. Я писал и для того и для другого, тогда, конечно, мой пример работает только для си. Вы правы. Это сообщение отредактировал(а) dizzy1984 - 21.4.2007, 14:50 |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Fazil6, где у меня написано, что двумерный массив это указатель на указатель? -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Fazil6, в этой цитате написано, что Имя массива а[][] имеет тип int**, т.е. указатель на указатель на int. Если ты не понимаешь разницу между словами 'массив' и 'имя массива', то почитай какие-нить книжки по этой теме, а потом спрашивай кто мне что сказал.
![]() -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ну а вот это уже точно наезд... И какая же разница в данном случае? Я применил слово массив именно к его имени. И если тебе не нравится формулировка, то имя массива не тоже самое что указатель на указатель. это скомпилится?
как ты думаешь? |
||||
|
|||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Вот видишь, разницу ты не понимаешь. И ещё хочешь о чём-то спорить. Поэтому я тебе и сказал, что бы ты сначала книжки почитал, а потом уже спорил. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
apook |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Осмелюсь вторгнуться в вашу дискуссию чтоб довести до вашего внимания тот факт что имя массива не является переменной.
тогда может ли оно иметь тип? Тип может иметь начальный элемент массива синонимом расположения в памяти которого я вляется имя массива, тогда имя массива int а[3][3] имеет тот тип который у а[0] его элемента, а у того тип int a[3], поскольку это не массив указателей, а именно двумерный массив....или ( ![]() -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
|||
|
||||
FiMa1 |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
![]() И (int*)a[0] и a[0] и *a и &(a[0][0]) это ОДНО И ТОЖЕ © Dov. вообще можем написать:
все элементы массива pa - указатели на первый (нулевой) элемент массива a. Это сообщение отредактировал(а) FiMa1 - 21.4.2007, 16:28 |
||||||||
|
|||||||||
Fazil6 |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
не цепляйся к словам. Я коментируя твою фразу и в ней указано имя массива и все сказанное мной относится именно к имени массива. ок. Принимаем, что я ламер без доказательства. как насчет компиляции моего примера?
в свете того что
почему не приводится к int** ? |
||||||
|
|||||||
apook |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Ну просто нелепо показалось приведение к указателному характеру одного единственного элемента массива
получилось pa[0]--*a; pa[1]--a[3]; pa[2]--a[3]; хитро как-то, хотя пускай так будет ладно...
Это почти одно и то-же, у указателя на массив и массива разный принцип сейчас подумал они все будут указателями, тогда опять же не понятно это приведение Это сообщение отредактировал(а) apook - 21.4.2007, 17:12 -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
||||||
|
|||||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
Dov, ты не прав ,ты сам неверно выразился, а теперь еще и посылаешь книжки читать.
это два разных типа, а второй это как раз указатель на указатель, и это то к чему приципился Fazil6 |
|||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Fazil6, если тебе так сильно хочется поспорить или, что было бы лучше, поучиться чему-нибудь хорошему, то открой соответсвующую тему, зачем же здесь оффтопить.
![]() По поводу этого. попробуй так:
Ну, а по поводу передачи двумерного массива в ф-цию в качестве аргумента, и здесь на форуме и в инете полным полно разных примеров. Нужно только поиском пользоваться. ![]() -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
vinter |
|
||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
так делать нельзя, они физически в памяти по разному расположены как ты себе представляешь обращение к элементам? вспоминаем арифметику указателей и понимаем почему написали ерунду.
тебе бы как раз не мешало бы их поочитать, прежде чем так яростно спорить |
||||
|
|||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Блин, да что за день сегодня такой. ![]() vinter, ты вопрос читал? Изначально вопрос звучал так: Я показал, что скомпилится. А описать указатель на двумерный массив можно так, например.
-------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
нет, я читал вашь спор, и исходил только из него. |
|||
|
||||
FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Dov, вопросик в догонку - а как выполняется прведение указателя на указатель к у просто указателю.. я не нашел.. Ну в приведении double к int понятно дробная часть откидывается, а здесь не пойму как это срабатывает.. Подскажи плз. |
|||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ты без конца отправляешь меня учиться чему-то (правда ты не говоришь чему именно). Я по твоему, ничего не понимаю, но внятно свою позицию ты отстоять не можешь. По твоему если я не согласен с высказываемыми тобой суждениям , то это офтоп? Мне кажется, что я могу доказать, что ты не прав, а добиться каких-то внятных объяснений почему я не прав от тебя я не могу. Постоянно отсылаешь к книгам... Можешь привести пример книги хоть одной, которая по твоему откроет мне глаза на проблемы многомерных массивов и связанных с ними указателей? Dov, Я привел конкретный пример и спрашиваю "почему он не компилится?" Я не спрашиваю "как его скомпилировать?" Чувствуешь разницу? reinterpret_cast - это ложь компилятору и с его помощью можно заставить много чего скомпилироваться. если исправить, то скомпилится , но если
|
||||
|
|||||
apook |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Прекращайте этот непонятный спор, я не доволен вашим поведением
это что-за тон, кто вам показал дурацкий пример наезжать друг на друга. ![]() -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
|||
|
||||
JackYF |
|
||||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Эта фраза мне определенно нравится... Имхо, правда больше на стороне Fazil6 здесь.
Массив вообще не имеет законченного типа, а уж тем более int**. Этот факт тоже не один раз проскакивал и выяснялся в темах. Dov, имхо, ты не прав. Это сообщение отредактировал(а) JackYF - 22.4.2007, 00:27 |
||||
|
|||||
Dov |
|
||||||||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
JackYF, в чём я не прав? В этом? Так я этого никогда не говорил. Я говорил только про имя массива, которое содержит адрес первого элемента массива, т.е. является указателем. Если массив состоит из элементов типа int, то имя массива имеет тип int*, т. е является указателем на тип int.
Отсюда следует, что и &ar[0] и ar имеют тип int*, т.к. являются адресами. Абсолютно то же самое можно сказать и про двумерный массив, который, по сути, является одномерным массивом, каждый элемент которого так же является одномерным массивом, и про трёхмерный и т.д.
И в том, и в другом случае имя массива имеет тип char**, так как содержит адрес первого элемента массива, который в свою очередь имеет тип char*. Разыменуем и тот и другой и посмотрим:
Оба выдают одинаковый результат. Доступ к элементам абсолютно идентичен. Можно объявить этот массив и так, это ни на что не повлияет:
Показал на пальцах, но уж извиняйте, как смог. Добавлю только, что многие не понимают разницу между массивом и именем массива. Имя массива - это указатель, хотя и константный, но всё же указатель. Почему? Да хотя бы потому, что содержит адрес, а адреса могут хранить только указатели. Массив - это последовательность элементов одного и того же типа, имеющих одно имя. Отсюда следует, что имя массива это только часть массива, и что оно указывает на начало массива. За сим откланиваюсь и иду спать, ибо лучше объяснить не смогу. ![]() -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
||||||||
|
|||||||||
FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Модератор: Сообщение скрыто. |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Нет. Не имеет. Читаем Страуструпа и/или стандарт. Нет, отсюда это не следует. Я тебе могу написать свой произвольный класс, который будет имитировать точно такое же поведение (возвращение элементов по индексу). Но у него явно не будет тип int* Ха. Это ты к первому элементу матрицы так можешь обратиться через [0][0], так как смещений нет. Постараюсь показать, что a[x][y] не имеет тип int** Следующий код принципиально неверен:
Вторая часть этого кода работать принципиально не будет. Это сообщение отредактировал(а) JackYF - 22.4.2007, 12:17 |
|||
|
||||
Xenon |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Следовательно утверждать, что имя массива имеет типа int* нельзя. К тому же похожий пример есть у Страуструпа - стр. 131 Добавлено @ 13:29 И вообще чего мы так спорим, если есть RTTI?
Выдаст int [2], но никак не int*. Это сообщение отредактировал(а) Xenon - 22.4.2007, 13:31 |
||||||
|
|||||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
похоже ты как раз и относишься к тем многим, которые этого не понимают. Все, что ты привел по поводу одномерного массива, его имени и приведения его к указателю правильно, вот только когда речь зашла о двумерном массиве твоя теория поплыла... Причем сильно.... вопервых не имеет тип char** , а может использоваться в таком качестве, но опустим эти лингвистические нюансы - дело намного хуже. ar1 ну никак не char**. И все потому, что кое кто действительно не понимает разницу между массивом и именем массива.
вот именно, и что мы имеем? Имя ar1 это указатель на массив char[4]. Где здесь имя, которое можно представлять как указатель? Запомни : имя двумерного массива интов - это указатель на массив интов, но не как не указатель на указатель на int именно по причине |
|||
|
||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Опять же, RTTI :
Выдает char[3][4]. Нельзя приравнять два разных типа T[] и T* - это хоть и похожие вещи, но на самом деле разные. |
|||
|
||||
Dov |
|
||||||||||||||||||||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Ух, скока накатали. Сразу говорю, что всё ни асилю.
![]()
Оставлю без комментария, хотя этому перлу прямая дорога на башорг, имхо.
JackYF, так я могу обритится к любому этементу матрицы, используя адресную арифметику указателей. Ну, например так:
Каким образом ты это пытался показать, я так и не понял. ![]()
То, что код не верен, это правда. Но я опять не понял, что именно не работает? Не компилится или не приводится или вывод не работает или выводит, но не правильно? Что не работает? ![]()
Или тебе надо, что бы в виде таблицы выводилось? Скажи "принципиально" ![]() Fazil6, весь твой пост оставляю без комментариев, кроме двух фраз, а именно:
Эти, имхо, на башорг адназначна. ![]() Да, а по поводу этого:
Я уже говорил, но для тебя ещё раз повторю. ar1 это указатель на первый элемент массива, т.е. на строку(или массив, если хочешь) "qwe". А имя, "которое можно представлять как указатель" звучит так(ты не поверишь) : ar1[0] или *ar1, как тебе больше нравится. Xenon, с тобой я соглашусь, конечно, но только не сейчас. По той причине, что ты не попадаешь в контекст текущей полемики. Здесь идёт разговор о типах данных в плане приведения типов... Что-то устал я уже, не могу правильно сформулировать, но это не важно. Ты в самом начале посмотри и всё поймёшь. Ну, типа того, что так сделать можно:
а так нельзя:
А может и можно, но я не знаю как. Тогда покажи. ![]() Камрады! Желаю всем удачи! А я из дискуссии выбываю. Притомился я тут с вами. Всем пока. ![]() -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
||||||||||||||||||||
|
|||||||||||||||||||||
Fazil6 |
|
||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
как всетаки сильно желание выдать желаемое за действительное.... Я и код привел тебе, на который компиллятор упорно твердит, что int [][] это не int** и никто с тобой не соглашается, но ты уверенно гнешь свою линию... Почему не компиллируется всетаки мой пример?
не работает приведение типов в том виде, в котором ты утверждаешь. не приведется это
и не приведется именно потому, что твое утверждение по поводу многомерных массивов ошибочно.
повторяю, что имя многомерного массива можно использовать как указатель на его первый элемент, но 1-м элементом многомерного массива является массив, а не имя массива и рассматривать его в свою очередь указателем вкорне неправильно. Ты ведь сам просил не путать массив с его именем кстати внизу есть ссылки. Вот например и там сразу рассматривается именно этот вопрос http://forum.vingrad.ru/topic-98636.html а как же твои слова ???
Это сообщение отредактировал(а) Fazil6 - 22.4.2007, 22:14 |
||||||||||||
|
|||||||||||||
apook |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Dov Повторяю :указатель это переменная, а имя массива переменной не является(Не по той причине что это константный указатель) Есть имя массива a и есть обьект массива с именем a[0], так вот они синонимы, в памяти не указывает, а есть начало массива. походу так и рассматривается компилятором. Есть указатель pa который являясь указателем выступает в роли имени массива, в памяти он указывает на начальный элемент массива но сам им не является, он расположен в другом месте.
Все свелось к выяснению разницы между массвами и указателями и вот еще: Если имя массива передается функции, то последняя получает в качестве аргумента адрес его начального элемента. Внутри вызываемой функции этот аргумент является локальной переменной,содержащей адрес. т.е функция действительно всегда имеет дело с указателем. тогда уж имя массива это массив имен переменных ![]() Это сообщение отредактировал(а) apook - 23.4.2007, 04:58 -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
||||
|
|||||
Ln78 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
Dov, зачем споришь, если сам давно понял, что неправ? Помог FiMa1
разобраться - молодец. Но дальше:
это как раз ошибка, такое приведение, будь это так, недопустимо. Fazil6 как раз и указал тебе на это. И привёл короткий и наглядный пример. Допустим, элемент a[0][0] расположен по адресу 0x00123400. Получаем: &a[0][0] = 0x00123400; &a[0][1] = 0x00123404; &a[1][0] = 0x0012340C; a[0] = 0x00123400; a[1] = 0x0012340C; a = 0x00123400; *a = 11; (в исходном примере, или 0 в примере Fazil6). Именно это и означает, что a - указатель на int, а потому твоё первое приведение типа совсем не "пурга", а правильно работает. Если бы a был указателем на указатель на int, это бы означало, что для доступа к этому int нужно брать *(*a), т.е. содержимое с адресом 11 (или 0). Своим спором ты, с одной стороны, теряешь репутацию у тех, кому очевидна твоя неправота, с другой, что хуже, запутываешь начинающих. И зачем оно тебе надо? Добавлено через 10 минут и 12 секунд Для большей аккуратности вместо *a = 11; Следовало бы написать *((int*)a) = 11; |
|||
|
||||
dizzy1984 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
Dov, ты в самом деле не прав [][] и ** это разные типы.
Будет правильно если ты разберешься в теме и тебе, похоже, стоит извениться перед Fazil6. |
|||
|
||||
bel_nikita |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
дабы прекратить спор раз и навсегд читаем: тут (А разве char a[] не эквивалентно char* a ?)
Это сообщение отредактировал(а) bel_nikita - 24.4.2007, 09:44 |
|||
|
||||
JackYF |
|
||||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
обоснования? А ты запусти и узнаешь.
+1, поддерживаю. |
||||
|
|||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
bel_nikita имел ввиду это http://www.rsdn.ru/Forum/Message.aspx?mid=177690&only=1
Это сообщение отредактировал(а) Xenon - 23.4.2007, 18:32 |
|||
|
||||
Dov |
|
||||||||||||||||||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Ничего не нужно выдавать. Нужно всего лишь написать одну строку:
А если ты утверждаешь, что имя массива или же сам массив имеет тип int [][], то покажи мне, как нужно написать. Так, что ли, или как то иначе:
Это да, хотя никто не говорит в чём имеено. Вернее, не соглашаются в том, чего я не говорил. А я откуда знаю, это ты должен знать. Мои примеры все компиллируются.
![]() Если рассматривать его, как одномерный массив массивов(например массив строк), то да. А если просто, как двумерный(например, двумерный массив одиночных символов), то нет. В этом случае 1-м элементом многомерного массива будет элемент с индексом[0][0], т.е. первый одиночный символ этого массива. Имя массива(например, целочисленного, в данном случае), не может быть не только первым, но и вообще никаким элементом массива, по одной простой причине. Имя массива это адрес певого элемена массива, т.е. указатель, а не целое число. Сколько раз я ещё должен это повторять, что бы до вас дошло? ![]() Ур-ра, дошло. ![]() Совершенно верно, массив это не указатель. Указателем является только адрес первого элемента массива, т.е. его(массива) имя. Fazil6, как-то полосами до тебя доходит, имхо. ![]() ![]() ![]() Так это ж я не тебе говорил, а apook`у. Или ты хочешь, что бы я это к тебе применил? ![]() Кстати, прошу всех обратить внимание на то, что apook после этого стал намного культурнее в общении, вот посмотрите на его посты до этого и после. Это две большие разницы. apook, ты молодец. Стало намного приятнее читать твои посты. Честно. ![]()
Читай выше. ![]() Ну, что тут можно сказать? Читай книжки. Пока всё.
![]() dizzy1984, читай выше или ткни меня носом, где я говорил, что это одно и то же. Про такой тип int[][], я только в этой теме узнал, что он вобще существует. И до сих пор не могу понять, как можно его, или к нему что-либо привести. Лады, постараюсь. ![]() Не вопрос, скажи только в чём я виноват. JackYF, это моё мнение и я не должен его обосновывать или что-то доказывать, я его просто высказываю. Это не значит, что я хочу тебя чем-то обидеть, боже упаси. Просто, мне это показалось смешным. Я то запущу, конечно, но перед этим мне хотелось бы, что бы ты сказал, что твой код должен делать по твоему разумению, но, гадюка такая, не делает. Если кому-то не ответил, извините. Вас много, а я один тут за всех отбиваюсь. ![]() Всем удачи. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
||||||||||||||||||
|
|||||||||||||||||||
Fazil6 |
|
||||||||||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
Dov, Твое высокомерие переходит всякие границы...
возможно, ты сильно удивишься, но строка "qwe" имеет тип char[4] - и никакой другой (совсем не char*)
Бред... Ахинея... Приведи мне выдержку из стандарта или цитату из любой книги, где так будет написано (про двумерный массив и его имя и что его имя это указатель на указатель). Это указатель на первый элемент. А массив int a[3][3] является одномерным массивом массивов int[3], поэтому первым элементом будет массив и имя а является указателем на int[3] , а это не указатель и поэтому a не является указателем на указатель.
вот это кто говорил?
Именно с этим не соглашаются.
Ну ты же все знаешь.... Не можешь простейшие ошибки найти в пяти строках? не компилится именно потому, что имя двумерного массива int не является указателем на указатель int (int**). Именно об этом говорит компилятор. Не надо только приводить доводы, что reinterpret_cast поможет. Если бы твои домыслы были верны, то пример обязан был компилироваться.
Это мой код. Ты отвечай за себя. Скомпилится Это? a здесь имя массива. По твоему это int**, получается , что одному int** присваивается другой int**,что мешает здесь скомпилироваться?
Вот только не надо строить из себя дядю наставляющего молодежь. После будешь выглядеть очень смешно...
Я хочу чтобы ты их к себе применил, раз уж берешь на себя ответственность делать замечания, то начни с себя. |
||||||||||||||||||||
|
|||||||||||||||||||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
вот еще примерчик
Добавлено @ 01:03
полный тест http://faqs.org.ru/progr/c_cpp/cfaqrus2.htm Это сообщение отредактировал(а) Fazil6 - 24.4.2007, 01:04 |
||||
|
|||||
vinter |
|
|||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 13 Всего: 56 |
![]() |
|||
|
||||
Dov |
|
||||||||||||||||||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Причём здесь высокомерие?
Fazil6, послушай меня. Вот ты не злись, когда читаешь, то, что я написал, а вдумывайся и старайся понять смысл написанного. Выкинь ты из головы эти стандарты, как будто нет их, ведь для того, что бы понять принцып работы они не нужны. Цитаты из книги я могу тебе дать, но книга написана на иврите. Если ты хочешь, я могу тебе дать цитаты с переводом на русский язык. Книгу написал Йоав Натив, израильский специалист. Он автор многих книг по программированию, в частности по С/С++, системный аналитик, имеет научную степень. Кстати, это к твоему вопросу о том, кто мне сказал. И вобще, не важно, что кто где сказал. Важно понять, как это всё работает.
Я понимаю, что компилятор тебе написал char[4], но ты пойми, он это сделал для того, что бы ты увидел и понял к чему он придрался. Иначе, как он тебе это объяснит? Но сам он воспринимает эту строку именно, как char*.
Рассмотрим подробнее подмассив а[0]. Это массив из 3 целых чисел типа int. Если а это имя для всего двумерного массива, то а[0] это имя только для этого подмассива. Ко всем трём элементам этого подмассива можно обращаться, указывая его имя а[0] и добавляя к нему индекс элемента. Что бы обратиться, например к последнему элементу, нужно написать a[0][2]. Поскольку этот подмассив, по-существу, является обычным массивом, то его имя а[0] является указателем на первый элемент а[0][0] и содержит его адрес. В этом легко убедиться.
Выведется один и тот же адрес. Делаем вывод, что имя подмассива a[0] является указателем на первый элемент, так как хранит его адрес, поэтому имеет тип указатель на инт, т.е. int*. Это понятно?
Разыменуй его:
Отсюда следует, что имя массива а, указывая на первый элемент т. е. на а[0], является указателем на указатель на инт, потому что, как мы выяснили выше, имя подмассива а[0] это указатель на инт. А поскольку имя массива а это указатель на указатель на инт, то он имеет тип int**. Все эти объяснения даны, как бы, с точки зрения компилятора, а не с точки зрения того, кто смотрит на экран монитора и видит там надпись int[][], а что это такое и как его применить он не знает. Всё, на этом пока остановимся. Если кто не понимает моих объяснений, я не виноват. Я ни кому не навязываю своё мнение. Если кто-то считает, что int[3] или int[333] или int[3][3] это какой-то тип, к которому можно хоть что-то привести, то ради бога, я не возражаю. Хотелось бы только взглянуть на это приведение. ![]() Ну, вот. Написал несколько строчек, а потратил на это несколько часов. ![]() Всем пока. Извиняюсь, забыл про пример. Если ты внимательно прочтёшь то, что я написал, то поймёшь, что нужно было бы, хотя бы, написать так:
А почему, я уже устал объяснять. Удачи. Это сообщение отредактировал(а) Dov - 24.4.2007, 12:14 -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
||||||||||||||||||
|
|||||||||||||||||||
bel_nikita |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
Dov,
Чтобы понять разницу между int a[] и int *a - не нужно никаких книг, и уж тем более цитат. .
Смотрим через дизасм:
Из этого всего видно, что a[3] и b[3] компилятор получает по-разному. Когда встречается а[3]: компилятор генерирует код, чтобы считать с позиции a[3]: 1) перемещается на три символа вперед 2) читает требуемый символ. В случае b[3] компилятор генерирует код, чтобы начать с позиции b: 1) считывает значение указателя 2) прибавляет к указателю 3 3) читает символ, на который указывает указатель. Т.е. int a[] != int *b. |
||||||
|
|||||||
Fazil6 |
|
||||||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
очень смешно... Сам придумал? Когда-то строки определялись char*, но это было когда-то и
Страуструп. Язык программирования С++. Специальное издание. стр. 84
там же стр.130
нифига подобного. Он воспринимает тип char[n] вот довольно простой пример
ничего я не путаю. Это ты путаешь.
именно можно использовать, но не является. И по поводу первого элемента многомерного масива - это массив ибо Многомерный массив - это массив массивов. Все мои примеры абсурдности твоих умозаключений ты игнорируешь.
ничего из этого не следует кроме того, что указатель и массив - это разные типы. |
||||||||||||||||
|
|||||||||||||||||
dizzy1984 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
Хранятся ли в массиве char[10][10] указатели можно проверить с помощью окна Memory.
|
|||
|
||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
||||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
М-да. Как горохом об стену...
![]() bel_nikita, я тебе про ерёму, а ты мне про фому. ![]() Нет. Я вроде бы по-русски пишу, а вы не понимаете. Щас напишу большими буквами, что видно было хорошо. Я говорю, что ИМЯ ОДНОМЕРНОГО МАССИВА ЦЕЛЫХ ЧИСЕЛ - ЭТО УКАЗАТЕЛЬ НА ТИП ИНТ( ПОТОМУ ЧТО ХРАНИТ АДРЕС СВОЕГО ПЕРВОГО ЭТЕМЕНТА, КОТОРЫЙ ИМЕЕТ ТИП ИНТ) И ПО ЭТОМУ ИМЕЕТ ТИП ИНТ*(КАК И ВСЕ ОБЫЧНЫЕ УКАЗАТЕЛИ НА ТИП ИНТ). А ИМЯ ДВУМЕРНОГО МАССИВА ЭТО УКАЗАТЕЛЬ НА УКАЗАЗАТЕЛЬ НА ТИП ИНТ(ПОТОМУ ЧТО ХРАНИТ АДРЕС СВОЕГО ПЕРВОГО ЭТЕМЕНТА, КОТОРЫЙ ИМЕЕТ ТИП УКАЗАЗАТЕЛЬ НА ТИП ИНТ) И ПО ЭТОМУ ИМЕЕТ ТИП ИНТ**(КАК И ВСЕ ОБЫЧНЫЕ УКАЗАТЕЛИ НА ТИП ИНТ*). И не имеет никакого значения, как был объявлен этот массив, так или так Оба имени это указатели на тип инт, а по этому имеют тип инт*, не смотря на те разтичия, что есть между ними. Ладно, у меня такой вопрос. Есть двумерный статический массив 3х3 .И вот есть такой кусок кода. Вопрос очень простой. Какой тип, по вашему, имеет указатель pAr и как он был объявлен. Если кому не трудно допишите недостающий код в начале main.
-------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
likehood |
|
|||
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
||||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Вообще этот разговор похож на это.
А. - дважды два равно 4. Б. - нет. трижды три не равно 4. А. - так я и не говорю, что трижды три равно 4. я говорю, что дважды два равно 4. Б. - как оно может быть равно 4, если в таблице умножения не написано, что трижды три равно 4. А. - да выкинь ты свою таблицу умножения, на пальцах прибавь 2 + 2. Будет 4. Б. - прибавляй, не прибавляй, всё-равно трижды три не равно 4. Вот так мы и разговариваем. ![]() Добавлено через 7 минут и 31 секунду Можно и так, конечно, но давайте пока в рамках int`а, что бы не путаться. ![]() И как по-русски назвать его тип? Добавлено через 10 минут и 29 секунд Вот я, например писал так: int* это указатель на целое число. int** это указатель на указатель на целое число. И т.д. А вы как назовёте? Это сообщение отредактировал(а) Dov - 24.4.2007, 14:41 -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
Fazil6 |
|
||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
а мы все тебе говорим, что НЕТ, НЕ ТАК. ЭТО ТВОЕ ЗАБЛУЖДЕНИЕ.
Еще раз повторю, в первом случае имя может использоваться КАК указатель, а тип у него int[10] и правило по поводу имени массива нерекурсивно и имя многомерного массива не может использоваться как указатель на указатель и т.д. А все приемы типа явного приведения
это обман компилятора и ни к чему это привести не может. В этом примере, например, выведется совершенно разный результат. Твои примеры с строками просто неграмотные и ничего не доказывают просто из-за того что массивы char интерпретируются в соответтвующих операторах. Мой пример с шаблонами показывает что компилятор рассматривает именно как массивы, а для представления как указатель ему требуется выполнять приведение массива (или его имени как тебе будет удобнее). Добавлено через 31 секунду
и при чем здесь массивы? |
||||||||||||
|
|||||||||||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Я про pAr спрашиваю. Добавлено через 3 минуты и 51 секунду Fazil6, в предыдущем своём посте я тебе показал, как нужно делать. Или в предпредыдущем. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
Fazil6 |
|
||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ну вот так будет работать видимо как ты хотел показать. pAr здесь типа int[3][3], использовать можно как указатель на int[3]. Не совсем понимаю что ты хотел продемонстрировать.
правое выражение вполне нормально интерпретируется как значение инта по какому-то адресу... Ну продемонстрировал ты что элемент массива можно проинициализировать через одно место... Ну и что? Работает это потому же почему
выдаст абсолютно одно и тоже именно потому, что pAr массив Добавлено через 7 минут и 21 секунду
то чтоли?
и где здесь указатель на указатель? тут сказано, что значение в aa считать указателем на инт и вывести значение по этому адресу. И что? Ну обманул ты компилятор... Разве это что-то доказывает? |
||||||||||
|
|||||||||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Fazil6, совершенно верно, именно это я и хотел увидеть. Что бы показать ещё и такой код:
Теперь ты воочию можешь убедиться, что для компилятора без разницы, как был объявлен pAr. Главное это как его воспринимает компилятор. А для него это тип int**. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ха-ха... Зачем же ты его везде приводишь к int* ? Действительно для компилятора без разницы. Ты ведь заткнул ему рот явными приведениями совершенно к другому типу. И он его воспринимает именно как int* везде кроме объявления pAr
|
||||
|
|||||
likehood |
|
|||
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
Кстати, так тоже работает:
|
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
это как раз и доказывает, что int p[3][3]; никаким способом в int** не превратить
|
|||
|
||||
bel_nikita |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
Dov,
Повторюсь еще раз,
Но если по-твоему int a[3] это обычный указатель int*, тогда объясни всему миру почему не прокатывает:
Зашибись! Напиши pAr[1][1] = 1; и удивись ![]() |
||||||||||
|
|||||||||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Хорошо, тогда скажи мне, что тебя может убедить в том, что имя двумерного массива это указатель на указатель? -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
likehood |
|
|||
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
||||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
bel_nikita, ну ёлы-палы, ну сколько можно?
Цитату в студию, где я такое говорил? Только перед тем, как её постить, посмотри, что там написано, я тебя очень прошу. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ну, например если бы компиллировалось
то я вынужден был бы признать, что ничего не понимаю и не знаю. Не представляю что ты можешь привести для доказательства своей теории ибо она ошибочна и доказательства не имеет по определению. В противном случае никто с тобой не спорил бы. Со мной, например, кроме тебя никто не спорит в этой ветке. |
||||
|
|||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
likehood, тогда скажи мне, что же это такое указатель на указатель В твоём понимании, конечно. И какой тип он имеет.
А заодно скажи мне, что такое указатель, опять же в твоём понимании. Возможно, мы оперируем разными терминами? Я своё определение уже дал. Добавлено через 3 минуты и 55 секунд Fazil6, ты тоже скажи, если не трудно, про то, что я спросил у likehood. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
dizzy1984 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
Daevaorn, Имелось в виду средство для просмотра памяти отладчика vs.
View->Debug Windows->Memory (alt+6). С его помощью можно было бы посмотреть для случая char arr[10][10]={'a','b','c','d'}. На место памяти arr. Там должен был бы быть адрес одномерного массива, если бы был прав Dov, либо 'a''b''c''d', если бы был прав Fazil6. |
|||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
меня вполне устраивает тот смысл, который ты вкладываешь в указатели. Меня неустраивает то как ты легко мешаешь указатели, массивы и их имена(которые могут использоваться как указатели).
это неверно и безграмотно. |
||||
|
|||||
bel_nikita |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
Dov,
Итак, вернемся к дискусии. Хорошо, по-твоему int a[] == int *b, т.е. int a[] - указатель и int*b - указатель. Тогда объясни мне, пожалуйста, почему не прокатывает следующее:
И еще вернемся к твоему примеру,
Обясни, пожалуйста, почему происходит Ба-Бах! в 7-ой строке? З.Ы.: Dov, ты все просишь, чтоб другие отвечали на твои вопросы: что же это такое указатель на указатель; что такое указатель и т.д. И я тебя прошу: ответь хоть на один мой вопрос, вместо очередного увиливания от ответа и придирки к словам. |
||||||||
|
|||||||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
bel_nikita, не в обиду тебе, скажу. Во всей этой теме есть всего десяток моих постов. Там есть все ответы на твои вопросы. Там написано, что такое массив и что такое имя массива. Там написано, что имя массива, хоть и указатель, но константный, поэтому и не будет работать твоё присваивание, ну и так далее. Сначала нужно почитать всё внимательно, а потом уже обвинять меня в том, чего я не говорил. А то получается так, читать не хотим, давай рассказывай нам в 1000-й раз одно и тоже. Вы что думаете, мне больше заняться нечем ?
Убил здесь столько времени и всё заново начинать. Так что ли? Нет уж, надоело. Повторю ещё раз то, что я сказал раньше.
Всё сказанное в этой теме, моё личное, персональное имхо. всем удачи. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
Dov, жесть. Чушь несешь полную. Почитай перед сном стандарт. Должно вылечить.
|
|||
|
||||
Ln78 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
![]() Добавлено через 3 минуты и 13 секунд Для большей строгости, конечно, лучше
но это дело не меняет |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
Xenon |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Если бы было так, то ...
Почему-то всегда выдает false ![]() bel_nikita, в твоем примере
можно оправдаться и сказать, что a имеет тип int* const pTr, поэтому присваивание невозможно ![]() Это сообщение отредактировал(а) Xenon - 24.4.2007, 19:21 |
||||||
|
|||||||
Dov |
|
||||||||||||||||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Ты хоть понимаешь, что ты здесь написал. Ты пытаешься указателю на указатель на инт присвоить адрес двумерного массива. То есть, грубо говоря, вместо int** ты ему подсовываешь int*** и хочешь, что бы это работало. Без приведения это работать не будет. Такому указателю ты можешь присвоить адрес указателя на подмассив массива, но не как не адрес самого массива. Например, ты можешь сделать так:
Ну, или извращаться и использовать приведение... Fazil6, я тоже с тобой не спорю, я,лишь, высказываю своё мнение. ![]()
А самому что, никак не разобраться? ![]()
Так, а теперь к делу.
Я сказал, что имя двумерного целочисленного массива имеет тип указатель на указатель на инт. Именно эти мои слова считают здесь чушью и бредом. Вот мои утверждения: 1. Указатель хранит адрес той ячейки памяти, на которую он указывает. Если есть такой код:
2. Значением указателя р будет выражение &var, то есть адрес переменной var. 3. Значение по этому адресу можно получить разыменовав указатель р. 4.Доказательством того, что р является указателем служит тот факт, что переменной var2 было присвоено значение 5, которое хранится в ячейке памяти, на которую указывает р, то есть значение переменной var. 5. Разыменование указателя р, то есть получение значения с той ячейки памяти, на которую он указывает это доказательство того, что р это указатель на int. 6. Поскольку рр содержит адрес указателя р, который является указателем на int, то это доказательтство того, что рр является указателем на указатель на int. 7. Разыменование указателя рр, то есть получение значения с той ячейки памяти, на которую он указывает это доказательство того, что рр это указатель на указатель на int. 8. Если значение переменной var3 равно значению var, то это доказательство того, что рр это укзатеть на указатель на int, поскольку через указатель рр мы получили значение ячейки, на которую указывает указатель р, являющийся указателем на int. 9. Таким образом выражение var3 = *(*рр) это доказательство того, что рр это указатель на указатель на int. Я хочу знать кто с чем не согласен. Кто хочет поучаствовать пишите всего два слова, номер утверждения и ответ на него, т.е. да или нет. Например: 1. нет 2. да и т.д. На сегодня всё, ребятки. Пошёл читать устав, или как там его. А, вспомнил. Стандарт. Всем пока. И удачи... в изучении стандарта. ![]() -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
||||||||||||||||
|
|||||||||||||||||
JackYF |
|
||||||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Ну где, где ты там увидел int***? Мы уже разобрались. Мы просим тебя ответить.
Тебе уже не раз говорили. Еще раз повторяю. Имя массива вообще не имеет законченного типа! Кури стандарт. У тебя в коде ни одного массива. Спасибо за работу с указателями. Мы говорим про массивы, не так ли?
Привыкай. Устав - не устав, но против стандарта не попрешь. MFC - это еще не все. |
||||||
|
|||||||
apook |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Клевый спор
![]()
не имя может использоваться как указатель, а указатель может использоваться в качестве имени, а имя не есть указатель, а содержит адрес первого элемента массива.
Dov интересная гипотеза? Я думаю что 1-м элементом многомерного массива a[3][3] будет обьект с именем a[3], который в свою очередь содержит адрес элемента с индексом 0.
Dov я тебя понял ![]() Проникнувшись этим я утверждаю что не существует типа int[3][3] и int*, а есть int и все остальные значки это прибамбасы! И буду в чем-то прав. Бывает... Dov Хочется поставить плюсик но ситуация не позволяет, все же ты не прав Это сообщение отредактировал(а) apook - 25.4.2007, 04:45 -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
||||||
|
|||||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
||||
|
||||
Kipter |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 114 Регистрация: 2.5.2006 Репутация: нет Всего: нет |
Да ладно вам, застыдили Dov'a...
Он понимает как это работает и саму суть.... только с теорией плохо.... |
|||
|
||||
Fazil6 |
|
||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
Мда... Вот это уже точно жесть.... Такого отвязного бреда еще небыло в этой ветке.... Ты же все время утверждал, что имя двумерного массива является int**... Теперь это у тебя ты уж определись какой бред тебе ближе. Жесть... С приведением это будет компиллироваться. Работать это никогда не будет. Именно поэтому ты и не докажешь никому ничего. и где я сказал, что хочу чтобы это работало? Я сказал, что по твоей теории это правильный код
как правильно с массивами работать все понимают, вот только там нигде нет указателей на указатель как ни крути и не приводи.
воттолько причем здесь массивы и их имена? ![]()
эх, зря ты это написал... Добавлено через 1 минуту и 36 секунд
похоже, нихрена он не понимает... |
||||||||||
|
|||||||||||
bel_nikita |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Эксперт Сообщений: 2304 Регистрация: 12.10.2003 Где: Поезд №21/22 ( ст . Прага ) Репутация: 21 Всего: 47 |
Dov,
Не съезжай всторону. Чушью и бредом считают твой приведенный код. Вот, некоторый фрагмент:
Dov, почитал твои посты... И скажу твоими же цитатами:
![]() З.Ы.:
|
||||||||||
|
|||||||||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
dizzy1984 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 675 Регистрация: 15.2.2007 Репутация: 3 Всего: 25 |
А что интересно так, когда скучно становится всегда знаешь что почитать...
![]() |
|||
|
||||
FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Программа динамического размещения трехмерного массива. Вываливается Debug Assertion Failed при "освобождении памяти, выделенной под указатели на столбцы одномерных массивов" (сорри за корявый коммент).
Не пойму что не так делаю, поправьте, меня плз...
Это сообщение отредактировал(а) FiMa1 - 25.4.2007, 14:42 |
|||
|
||||
JackYF |
|
||||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Вот тут неверно. Инициализация делается отдельными тремя циклами. Надо так:
Это сообщение отредактировал(а) JackYF - 25.4.2007, 15:08 |
||||
|
|||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
JackYF, я не уверен, что вы правильно подсказали.
У вас по-моему память под строки не выделяется. Мой вариант:
Добавлено через 39 секунд Правда мой вывод отличается от того, что надо, ну и размеры 5.5.5 можно другие поставить |
|||
|
||||
FiMa1 |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Соответственно пишу:
Unhandled exception... Access violation writing location... при инициализации в строке ![]()
|
||||||||
|
|||||||||
apook |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
бросай указатели
-------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Так нельзя! a[i][j][k] !=***(a + i + j + k ) Так что действительно бросай использовать указательную арифметику там, где она не нужна. Добавлено через 2 минуты и 38 секунд
Чем отличается от моего варианта? Правда, у меня только создание, остальное тоже надо править. Если ты имел в виду, что я не написал исправления остального кода, тогда да. |
|||
|
||||
Partizan |
|
|||
![]() Let's do some .NET ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 2828 Регистрация: 19.12.2005 Где: Санкт-Петербург Репутация: 4 Всего: 67 |
Даааа ) Прочёл весь топик от начала до конца )
Интересные вещи начитал ) и даже несколько утверждений себе на заметку взял) Истина рождаеццо в споре, как говорят) -------------------- СУВ, Partizan. |
|||
|
||||
Anikmar |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
JackYF,
Ваш код:
Это мы выделили память под str двухмерных массивов
Это мы выделили память под массив указателей на строки двумерного массива (создали столбец) - Или создали строку с указаетлями на столбцы (как кто рассматривает)
А вот дальше я не понял. У нас есть только указатели. И сы создаем по одному элементу. А где используется третья размерность? В примере она tdim. Я ее не увидел. Получается по 3-му измерению у вас создается только 1 элемент. У меня эта часть сделана так:
Третье измерение - у меня Size2. Это сообщение отредактировал(а) Anikmar - 26.4.2007, 09:05 |
||||||||
|
|||||||||
FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Всем привет! Друзья, торжественно клянусь никогда не использовать (да и не собирался) указательную арифметику для подобного запутывания кода! Однако, следует заметить, что данной код писался исключительно в целях изучения процедур доступа к i-му элементу многомерного массива посредством указателей (с этим у меня затруднения). Посему, пожалуйста, ответьте на следующие мои вопросы: Есть массив int array[i][j][k]; 1. Как ПОСРЕДСТВОМ УКАЗАТЕЛЕЙ записать в элемент [0][1][2] массива array значение, к примеру, 100? 2. Как ПОСРЕДСТВОМ УКАЗАТЕЛЕЙ прочитать значение элемента [0][1][2] массива array? Отдельное СПАСИБО тому, кто отважится закрепить ответы написанием программы динамического размещения массива array[][][] ПОСРЕДСТВОМ УКАЗАТЕЛЕЙ и его инициализации ПОСРЕДСТВОМ УКАЗАТЕЛЕЙ (не забудьте удалить массив ;). PS: Думаю, это можно будет считать хорошим логическим завершением теоритических изысканий топика. |
|||
|
||||
Anikmar |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Не понял. Мой пример и создает и выводит и удаляет - и все только через указатели. Чем не устраивает?
|
||||||
|
|||||||
FiMa1 |
|
||||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Да через указатели, но не "явно"... Пусть есть одномерный массив int a[3]; тогда доступ к третьему (фактически второму, нумерация с нуля) элементу массива при явной записи с использованием указателей будет выглядеть как:
Как проделать тоже самое с трехмерным массивом array[][][] ? Добавлено @ 13:30
Народ, так что ли правильно?
Это сообщение отредактировал(а) FiMa1 - 26.4.2007, 13:31 |
||||||||||||
|
|||||||||||||
Ln78 |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
FiMa1, не так.
Для первого раза можно так
На эту тему есть много хороших книг. Если очень нужно, могу попробовать написать для тебя небольшое пояснение, но только позже Добавлено через 6 минут и 56 секунд Ну вот, и сам ошибся, надо
|
||||
|
|||||
FiMa1 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Название книги в студию, пли-и-и-з. Правда сам не нашел именно про это нигде, уж извините...
Спасибо, буду ждать! |
||||
|
|||||
apook |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Ln78 Это что-то в натуре интересное, подозреваю что ты еще один запутыватель ты не преподавателем работаешь нет... а то похоже Это сообщение отредактировал(а) apook - 26.4.2007, 14:24 -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
||||
|
|||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
FiMa1, Имейте в виду
Вариант Ln78 только для массива, занимающего единый блок памяти (только для статики). Вариант apook универсальный - сработает и на статическом масиве и на динамическом. - Я бы выбрал его. |
|||
|
||||
FiMa1 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Так я, кажется, тоже самое написал в строке:
apook, получается Ln78 меня не правильно поправил? PS: to apook: а как С ПОМОЩЬЮ УКАЗАТЕЛЕЙ динамически разместить данный массив в памяти и, С ПОМОЩЬЮ УКАЗАТЕЛЕЙ, реализовать инициализацию не показал (ну и удаление массива само собой). Просвяти, плз. Заранее спасибо! |
||||||
|
|||||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Кажись, да.
Все, понял, где я недописал... да, тогда действительно была ошибка. |
|||
|
||||
apook |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Дело в том что он не поправил, а привел пример абсолютно не пвносящий ясность в твой вопрос, а где то даже наоборот.
Дело в том что я сам нахожусь в стадии изучения Cи пл пл и поэтому терпеть не могу вопиющие случаи запутывания мозгов интригующе выглядещями примерами, в коих после долгого разбирательства обнаруживается минимум смысла(хорошо если правильного). Но все-же скажу как сделал-бы apook. Пишешь просто на индексах, компелируешь, убираешь баги, любуешся, переделываешь на указатели, смотришь и думаешь нахрена ведь и так работало... Если a[0] это *(a) то a[0][0] это *(*(a)) ну и т.д Короче от простого пляшем, от простого к сложному как сказал кто-то, ведь знал же что говорил.... -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
||||
|
|||||
likehood |
|
|||
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
Он показал, как этот код работает на самом деле. А использование тройного разименования как раз и запутывает мозги. а вот здесь действительно что-то напутано Это сообщение отредактировал(а) likehood - 26.4.2007, 15:24 |
|||
|
||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Так вы определитесь пожалуйста. Чем мой пример вам не подходит? Создание трехмерного массива - есть Присвоение элементам через указатели - есть Удаление - есть А если вы определяете массив статически, то как тогда вы планируете его еще раз создать? И как уничтожить? Если он статический - он уже создан и он сам уничтожется при выходе из программы. |
||||
|
|||||
apook |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
likehood
Компилятор встретив a[1] делает следующее *(a+1) стало быть так этот код работает на самом деле Способ с указателями я привел только потому что Fima1 с самого начала на этом настаивает(читай предыдущие посты) И отнють не говорю что это вносящий ясность способ. -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
|||
|
||||
FiMa1 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Anikmar, Ваш вариант инициализации массива:
Вариант инициализации с разыменованием через указатели: for (i=0;i<Size0;i++) for(j=0;j<Size1;j++) for(k=0;k<Size2;k++) aMas[i][j][k] = *(*(*(a + i) + j) + k);[/code] Разница понятна? По-моему мы разговариваем на разных языках... Но, вообще, по мнению большинства, этот изврат не нужен, и, видимо, пора прикрывать дискуссии... |
||||
|
|||||
likehood |
|
|||
666 ![]() ![]() Профиль Группа: Участник Сообщений: 536 Регистрация: 21.12.2005 Репутация: 8 Всего: 24 |
||||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Указатели вам подсказал apook Как создавать массив и его удаляеть - есть в моем коде Остается поменять индексный доступ на указатели - и все есть На одном языке мы разговариваем. Суть вопроса - поменять синтаксис доступа к элементу с квадратных скобок на указатели. Больше ничего менять не надо, вот я и удивляюсь. |
|||
|
||||
threef |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 375 Регистрация: 27.10.2005 Где: Запорожье Репутация: 9 Всего: 10 |
Посмотрите на постик, там уже есть и динамические массивы , и размышления на тему скорости их создания и обработки. А так же мысли по поводу "изврата" и других выражений людей, не желающих шевелить мозгами
Смотри сюда |
|||
|
||||
apook |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
В догоночку, для ясности
![]()
Ну и че ты это сюда сунул что там о чем то похожем говорили? До фига мозги что-ли включены... Это сообщение отредактировал(а) apook - 26.4.2007, 18:09 -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
||||
|
|||||
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 Какие конкретно действия "наоборот" вас интересуют? |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
Anikmar |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Я такой пример привел, он вас не устроил? Например так:
Добавлено через 5 минут и 52 секунды Или так:
|
||||||
|
|||||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
||||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ну совсем не как int**, ведь если 2 раза разыменовать и в результате получить int еще не означает, что то, что разыменовывается имеет тип int**. Я привел пример когда **ppa выдает int, но ppa не является int** http://forum.vingrad.ru/index.php?showtopi...t&p=1114163 ведь получаемый результат выражения (я имею в виду адрес) a + 1 разный в зависимости от того какого типа a. Ведь если a типа int** , то смещение будет 4*1 байта, а если a[2][2] , то смещение будет sizeof(int[2])*1. и в твоем примере с циклом *a возвращает массив int[4] , а потом к нему применяется смещение 0 и разыменовывание дает int Добавлено через 3 минуты и 9 секунд
мне неизвестны такие примеры, которые компиллировались бы, либо компиллировались и работали бы. Поэтому я и утверждаю, что ни массив int a[2][2] ни его имя не являются int**. Те кто это утверждают, видимо знают такие действия и примеры |
|||
|
||||
Anikmar |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
С такой логикой можно любой пример оспорить. К этому коду это суждение не относится. Разыменовывается без всяких приведений и искусственных преобразований (переопределений) и выдает именно то значение, которое ожидалось.
Если вы считаете, что этот результат случайный так, как размеры int и указателя совпадают попробуем по-другому:
Теперь выдаем 2-ю строку массива (или столбец - как кому удобнее) Что теперь с указательной арифметикой не устроит? Добавлено через 6 минут и 58 секунд
Я привел вам 2 работающих примера, когда имя массива можно использовать в качестве указателя. Я никогда не утверждал, что имя массива является указателем - так как он имеет тип int[3][4] - это легко увидеть использовав typeid(...).name() Я говорил, что имя массива можно использовать в качестве двойного указателя, что я вам и продемонстрировал. А вы говорите, что не увидели ни одного примера - дескать то, что я привел не является двойным указателем. У меня, право, возникло затруднение - я не увидел ни одного аргумента, опровергающего работающие правильно участки кода. Если бы вы не увидели предыдущего текста, как бы вы расценили эту строку: printf("%lf\t",*((*aa+1)+i)); У вас бы спросили какого типа aa? Что бы вы ответили? По выражению - это работа с двойным указателем и никак иначе. Строка одинаково выглядит и если бы aa была бы объявлена как ** и как двойной массив. |
||||||||
|
|||||||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
это выглядит как работа с двойным указателем, но это не является работой с двойным указателем, потому что
|
||||
|
|||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
т.е. согласно вашей логике, указатель на конкретный тип данных и указатель на массив из таких данных отличаются? char *s; - Это указатель именно на переменную типа char (т.е. на 1 символ) или на массив таких символов? Ответьте мне, пожалуйста. Далее: char **s; - Это указатель на указатель на символ или указатель на массив указателей на символ? |
|||
|
||||
apook |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
Это вообще указатель на массив указателей на тип char
и другое дело какие адреса взяты указателями -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
||||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
да. массив и указатель это разные типы. Передай sizeof массив и указатель , который указывает на его первый элемент. Получишь разные результаты. tipeid выдаст разное. Физически - это адрес, но работа с ним и результат зависит от того как объявлено.
это указатель на символ. Массив символов при передаче в функцию передается как char *s. Строковый литерал "11" имеет тип char[3]. Я понимаю, что соблазн представлять массив как указатель достаточно велика, но если следовать логике, что в строке for (i=0;i<4;i++) printf("%d\t",*(*a)+i); a - используется в виде int** , то почему в параметрах функции двумерный массив не преобразуется в int**. Весь фокус не в том насколько велика разница между массивом и указателем, а в том что слишком большая разница между указателем на массив и указателем на указатель. |
||||
|
|||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
||||
|
||||
Fazil6 |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
допустимо только для совместимости со старым кодом. так ведь недопустимо
Добавлено @ 18:10
это указатель на указатель на char или на символ, в данном случае понятно. Это сообщение отредактировал(а) Fazil6 - 27.4.2007, 18:11 |
||||||
|
|||||||
Anikmar |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Потому, что он таковым не является. Тут примерно такая же разница как между адресом функции и адресом метода класса. Если массив определяется статически - то для вычисления смещения необходимо знать размерность этого массива. А в голом указателе такой информации нет. Если вы создаете массив динамически и передаете его в функцию, то что должна знать функция? Это адрес собственно массива и его размерности. Для чего? Чтобы правильно вычислить местоположение конкретного элемента. Когда массив определен явно, он выделяется прямым куском в памяти и размерности его известны. Именно поэтому он получает тип int [3][4], а не int** - т.е. в этот тип уже явно включены размерности. Если он создается динамически, то мы вынуждены создавать его многоступенчато. Сначала создаем массив указателей, потом каждый указатель инициализируем собственно массивом данных конкретного типа. Если мы создадим динамический массив единым куском, то он не будет двухмерным с точки зрения языка Си++ - вы не сможете доступиться к его элементам стандартным оператором [][]. Так как в этом большом куске будут отсутствовать указатели, которые будет искать данный оператор. А когда этот оператор пытается найти искомые указатели в статическом массиве - то ему на вход передается уже другой тип данных, не int**, а int[3][4] - соответственно адрес конкретного элемента вычисляется по-другому. Нельзя передать в функцию статический двухмерный массив как указатель именно из-за разного алгоритма вычисления смещения элемента. Функция, которая получит на вход двойной указатель будет вызывать оператор [][], относящияся именно к двойному указателю, а не к int[3][4]. Именно поэтому, работать с именем массива как с двойным указателем возможно, но он не является двойным указателем сам по себе и передавать его в функцию, преобразовав к двойному указателю будет ошибкой. Собственно также как и двойной указатель бессмыслено передавать в какую-либо функцию предварительно не проинициализировав его. Например:
Нет и еще раз нет. Если мы объявим char *s; - то это всегда указатель char s[30]; - это совсем другой тип, это явно заданный массив и имеет тип char[30] char *s = new char[100]; char *ss; // Это уже динамический массив. Причем и s и ss имеют одинаковый тип. Статически объявленные массивы всегда вносят некоторую долю путаницы, но когда полностью представляешь механизм трансляции компилятором этих типов, особенно в части вычисления адреса конкретного элемента, то в общем то всегда все понятно. Лично для меня массивом является то, с чем можно работать стандартными операторами массивов - это квадратные скобки. Поэтому варианты вычисления адреса в большом блоке я и не приемлю. Добавлено @ 18:32
Естественно недопустимо. В языке не определены константы адреса. И только из-за этого. Инициализировать можно только вещами, которые понимает компилятор. А в языке определены числовые константы, логические, а адресные - нет. Он их просто не знает. Это сообщение отредактировал(а) Anikmar - 27.4.2007, 18:34 |
||||||||
|
|||||||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
||||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Нет, это целое число. Дело в том, что исторически сложилось, что адрес и int имеют одинаковый размер - с точки зрения архитектуры процессора - все понятно. Но адресных констант в языке нет, в ранних версиях я еще встречал описание причины - дескать язык высокого уровня не должен быть зависим от архитектуры машины, в современном стандарте даже упоминаний нет. В разделе константы - там есть целые числа, числа с плавающей точкой, строковые и символьные константы и служебные константы true и false. Больше нет. Да и посудите сами: допустим процессор motorola для видеоприставок. Был еще в конце 80-х годов. На тот момент intel был еще 16 разрядным, а motorola уже имела прямую 32-битную адресацию. Ка должна выглядеть адресная константа? При всем при том, что на Си можно было писать и обработчики прерываний и драйверы. Тогда для семейства x86 она должна выглядеть как-то так: 000CC:000dd - т.е. сегмент + смещение, а для мотороловского процессора уже как 32 битное единое число без сегментации: как-то так. сссааа00 Причем int был все равно 16-разрядным. Так что отсутствие в конструкции языка константы адреса вполне объяснимы и логичны, особенно сейчас - с четким разделением памяти и управление ею операционной системой. Ну откуда программист может знать конкретный адрес на этапе разработки программы? Зачем он нужен? И с появлением 64-разрядных систем в 32 разрядный int указатель уже не запихаешь. А не за горами 128 разрядные. |
|||
|
||||
Daevaorn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2155 Регистрация: 29.11.2004 Где: Москва Репутация: 51 Всего: 70 |
ну тут на самом деле вопрос интерпритации компилятором и процессором некого числа как адреса. хотя, кочнено, согласен что явных адресных констан нет. |
|||
|
||||
Ln78 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
FiMa1, хорошо, что тебе понравилось, наверное в воскресенье-понедельник попробую дописать вторую часть.
К продолжающим споритьЧестно говоря, я уже перестал понимать предмет спора. Может и остальные тоже спорят просто по инерции? Зайди сюда ортодоксальный астматик, он бы долго смеялся: "Я полагал, что между плюсанутыми и аштеэмельщиками разницы особой нет, но не настолько же? Придумали какое-то мифическое чудище, и сами же его и испугались". Вот, допустим, есть у нас структуры, описывающие разные физические сущности: корабль, автомобиль, кухонный стол, кролик, десяток кроликов. И есть ещё один тип: union, элементы которого - объекты перечисленных выше структур. Структуры содержат различные элементы, занимают разный объём памяти. Определена одна переменная, тип её - как раз тот самый union. Я заполняю эту переменную данными, которые описывают автомобиль. Конечно, можно считать фокусом: объявляю указатель на переменную как на автомобиль, потом чудом (просто указанием компилятору понимать его по-другому) рассматриваю это как кухонный стол, потом как кролика, а потом опять как автомобиль, и использую в последнем значении именно как автомобиль. И выдаю это за свои сверхспособности: смотрите какой фокусник. Да нет здесь никаких фокусов, и ловкости рук никакой нет, одно примитивное мошенничество. Что я могу, чтобы находящийся в здравом уме и трезвой памяти использовал в качестве кухонного стола автомобильное колесо с фарой и не заметил разницы? Или считается, что для int* и int** это чем-то принципиально отличается (подумаешь, втихаря нарисую/сотру звёздочку, никто и не заметит)? |
|||
|
||||
Anikmar |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Тут чье-то конкретное мнение уже точно не влияет, вот какие допустимые литеральные константы перечислены в стандарте:
На большее стандартный компилятор не способен. ![]()
Да тут уже спор совсем о другом, чем изначально ![]() Короче спорим помаленьку, пыхтим ![]() |
||||||
|
|||||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Две страницы я благополучно успел пропустить...
И все же спор у нас был о двух вещах: 1. тип "Массив" != тип "Указатель". Это так, теоретические изыскания. 2. Неправильная работа конкретного примера. То есть, что
Пример выведет два разных числа в лучшем случае. В худшем и AV/SegFault может схлопотать. Ln78, а вообще во многом ты прав. По данным двум пунктам мы спорили, спорили... А теперь о чем спорим? |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
||||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
А ничего толком не началось. Корректного примера я так и не увидел. Или я что-то пропустил? Если да, то ткните в цитату или ссылку на этот корректный рабочий пример. Начались опять какие-то разглагольствования. Итак, жду примера. |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Ну уж нет. Привел два работающих кода. Если вам интересно - запустите их и откомпилируйте. Если вы утверждаете, что работа с именем массива отличается от работы с двойным указателем - то аргументируйте и опровергайте. А то получается какое-то барство. Сначала: А потом извольтес-с-с..: У вас в роду дворян не былос-с-с? ![]() |
|||
|
||||
Fazil6 |
|
||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ну не является... Так почему ты считаешь что в строке
показано использование a как int**, если он таковым не является? У меня такое впечатление, что ты либо не читаешь что я пишу тебе вответ, либо не читал обсуждение до этого... Поэтому не совсем понятно кому адресованы твои теоретические выкладки.
Ох... Я просил пример, который доказывает, что массив или имя его можно использовать как int** , а не пример в котором показаны действия с неким массивом и "если бы переменная была int**, то выглядело бы все именно так". что нет?
Я именно так и говорил всегда.
такое впечатление, что ты единственный, кто знает о чем спорят... Я, например, не уверен, что знаю... ![]()
ну принято считать что вот здесь пример демонстрирует http://forum.vingrad.ru/index.php?showtopi...t&p=1114611 и вот тут http://forum.vingrad.ru/index.php?showtopi...t&p=1114678 Добавлено через 9 минут и 47 секунд
ну выглядит одинаково... На этом сходство заканчивается... Весь топик именно об этом, что даже когда работа с двумерным массивом может выглядеть как работа с указателем на указатель, ни массив ни его имя таковым не являются и не приводятся к такому типу и не представляются как такой тип(int**). |
||||||||||||
|
|||||||||||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Встречный вопрос. А как я с ним работаю с точки зрения конструкций языка? Привожу к другому типу? Я работаю с ним как с двойным указателем. Почему не так? С какими стандартными типами данных языка Си++ допустимы такие операции?
Обсуждения до этого хоть я и читал, к теме моего ответа никак не относятся. Я ни скем не спорил. Было предложение привести пример кода, в котром имя двухмерного массива использовылось бы как двойной указатель, причем правильно. Я привел пример доступа к элементу массива, используя его имя в качестве двойного указателя. В чем я спорю, кого я оспорил и что я сделал неправильно? Имя массива использовалось как двойной указатель? ДА. Без каких либо ухищрений! Без приведений типа и т.п. Доступ к элементу массива получили? ДА. Код рабочий? ДА! А потом мне объяснют, что это частный случай, что int и указатель размером одинаковы и т.п. Я всего лишь ответил на пост. Дайте мне рабочий пример. - Дал. Работает - ДА. В чем я не прав, объясните? Теперь получается, нет, он не подходит. Так как нельзя передать в функцию. Не вопрос. Передайте в функцию двойной массив не указывая его размерности? Используя только имя массива. Нельзя. Потому, что статический массив намертво привязан к своим измерениям. Таким образом, предложите мне пример функции, которая в качестве параметра получает статический двухмерный массив любой размерности. Давайте вместе разберем получившийся код. Добавлено через 2 минуты и 24 секунды P.S. Язык си, конечно, допускает вольности. Но все-таки не с точки зрения того, что "выглядит одинаково" Правила семантического разбора предложения четко оговорены. И если я использовал конструкцию со звездачками без искусственного приведения типа, то компилятор для себя не делает варинтов "наверное это похоже на..." он действует четко (слова Богу). Так что эта фраза мне несколько непонятна. |
|||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
Какие операции? Весь смысл примера сводится к тому, что **a даст в итоге значение типа int (если a это двумерный массив int). Я согласен с этим, но я говорю, что этот пример не доказвыает, что a это int**. Я просил пример, который это доказал бы. Поэтому я и говорю, что этот пример меня не устраивает. Поэтому я и вспоминаю передачу в функцию массива.
ну да действует четко и я утверждаю, что когда компиллятор видит **a, действия его будут разными в зависимости от того какого типа a хоть мы и получаем в итоге int. И в твоем примере с конструкцией **а компиллятор работает как с указателем на массив , а не указателем на указатель на int |
||||
|
|||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
??? действия его будут однозначны - получить значение <type> - если a это int **a, то значение будет int. Какие зависимости? Пример:
Будет выведен результат 100 и это однозначно. имя массива использовано как двойной указатель? ДА Ваше требование: Выполнено? ДА! Не понимаю... Какие примеры еще надо привести? |
||||
|
|||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
зависимости от типа a. Компиллятор использует информацию о типе а для получения результата **а Нет. Имя массива использовано как указатель на массив, а не как двойной указатель и компиллятор действует в этом случае не так как если бы это был двойной указатель. Я же писал, что **(a +1) в случае если a типа int** компиллятор выполнит смещение на sizeof(int*)*1, а если int a[2][2], то выполнит sizeof(int[2])*1 sizeof в этих случаях выдает разные результаты и поэтому компилятор никогда не рассматривает двумерный массив как двойной указатель и **a выглядит как работа с двойным указателем , но на самом деле является работой с указателем на массив в твоем примере. Поэтому я и сказал, что меня этот пример не устраивает Это не мое требование. Это смысл твоего примера. мое требование
читай внимательнее, что я пишу |
||||
|
|||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
||||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
А что вы хотели? Мы не получим смещение 4 или 8. Мы получим следующий элемент массива. Для того, чтобы получить следующий элемент массива в случае объявления
int **p; мы должны просто прибавить размер указателя Так как у нас статический массив int a[3][50]; то чтобы получить следующий элемент согласно правилам работы с двойными указателями компилятор высчитывает значение исходя из размерностей - так как статический массив занимает единый блок памяти. И прибавляет к нему 50 * sizeof(int). Где нарущение правил работы с указателями???? Мы получили следующий элемент массива, согласно правилам языка Си. В языке Си ( в стандарте) нет понятия многомерных массивов. Там есть понятие МАССИВ, доступ к элементам которго обозначается квадратными скобками. Если вы попытаетесь найти там операцию [][] - вы ее не найдете, потому, что ее там нет. Там есть понятие только массива. И понятие имени массива, которое приводится к указателя на тип данных массива. Соответственно, если у нас есть объявление: int a[3][12]; то с точки зрения станлдарта мы имеем массив из 3элеинтов, каждый из которых имеет тип int a[12]. Надеюсь с этим утверждением никто не спорит? Далее читаем стандарт. Имя массива приводится к указателю на тип массива. (то же стандарт, а не мое мнение). Значит наш пример показывает, что мы имееем массив из 3элементов типа int[12], и что его имя приводится к указателюю на типа массива - т.е. на int[12]. При увеличении значения указателя на 1 мы должны получить следующий элемент массива. Так как у нас массив из 3элементов, каждый из которых имеет тип int[12] - то мы должны после инкрементирования укзателя получить следующий элемент массива, т.е. очереной int[12] пропуская все предыдущиие. Так как массив объявлен статически, то компилятор переставляет значение указателя так, чтобы он соответствовал правилам языка - т.е. на следующий элемент. Что мы и получаем в результате. Если и эти доводы вас не убедили, тогда уже надо обращаться в артибтраж к Страуструпу - дескать какую-то хрень ты написал... Иллюстрация к моим доводам на примере кода:
Если бы на месте b был бы инициализированный массив на базе двойного указателя, мы бы получили аналогичный результат. Т.е. имя массива и указатель ведут себя одинаково, логично и предсказуемо. Если нужен пример - я его набросаю, просто немного лень стало. А если разницу, в поведении указателей вы усмотрели в различном смещении, то опять направляемся к стандарту: При инкрементировании указателя, он увеличивается на значение, равное типу его хранения. указатель int **P p хранит массив указателей, который размещен в памяти единым блоком. Последний по измерению массив по правилам языка Си всегда размещается единым блоком (стандарт) При увеличении на единицу - он показывает следующий указатель - так как именно указатели он хранит. На какое конкретно число он увеличивается - стандартом не прописано (так как это программиста не касается). Нам гарантировано стандартом одно: при увеличении на 1 указатель устанавливается на следующий элемент (ну можно, конечно, и на 2 и на большее количество) Операция sizeof в таких случаях никого никогда колыхать не должна - у нас есть указатель на конкретный тип данных и его инкрементирование указывает на следующий элемент. При объявлении массива p[3][nnnn] Если мы инкрементируем значение p, то мы должны получить очередной элемент - т.е. указатель - т.к. p - приводится к массиву указателей по стандарту. На сколько пришлось реально инкрементировать (или декрементировать - уже стебусь ![]() В чем разница в поведении? Это сообщение отредактировал(а) Anikmar - 29.4.2007, 03:39 |
|||
|
||||
Mayk |
|
|||
![]() ^аВаТаР^ сообщение>> ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2616 Регистрация: 22.5.2005 Где: за границей разум а Репутация: 45 Всего: 134 |
занудутствую: Наоборот. a - это массив из трёх элементов, каждый из которых является массивом из двенадцати элементов, каждый из которых является int'ом. зы. 6 последних страниц не читал. 2 и 3 тоже. -------------------- Здесь был кролик. Но его убили. Человеки < кроликов, йа считаю. |
|||
|
||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Эх.... Все-таки подсадили. ![]() Как правильно пишется ЗоНУДА и ЗаНУДА? ![]() Фраза из анекдота:
ПРОШУ СЧИТАТЬ ОЧЕПЯТКОЙ ![]() Добавлено @ 01:47 P.S. И ваще - в 2 часа ночи что угодно перепутать можно, а не только порядок измерений. Mayk - абсолютно прав, но смысл от этого никак не меняется P.P.S. Очепятка исправлена. Это сообщение отредактировал(а) Anikmar - 29.4.2007, 03:41 |
||||
|
|||||
Fazil6 |
|
||||||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
вообще-то sizeof(int[50]) потому что элементом, на который указывает указатель а является int[50]. И никаких правил работы с двойными или тройными или еще какими указателями нет. Есть арифметика указателей и важно в ней только на что указывает указатель. Для двойного указателя он указывает на int*, а для массива на int[50]. Вот их размер в байтах и важен
ох.... Я разве сказал, что правила нарушены? Я разве говорил, что пример не работает? Я сразу сказал, что правила по которым этот пример работает разные в случаях двойного указателя и массива.
как солнце из-за туч!!!! Только непонятно что ты читал в топике предыдущие 10 страниц....
доводы чего? того что я тебе первым делом сказал? Теперь ты мне объясняешь как по стандарту... Именно потому что так по стандарту меня твои примеры и не устроили. Я тебе так сразу и сказал.
в том как компиллятор получает этот очередной элемент |
||||||||||||||||
|
|||||||||||||||||
Anikmar |
|
||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
С этого момента по подробнее. Итак имеем арифметику указателей. Имеем char *s; При операции s+1 указатель увеличивается так, чтобы указать на следующий элемент массива. По сути Имеем char * *s; Теперь s указывает на указатель. s+1 прибавляет так же 1 адрес, чтобы указать на следующий элемент Имеем char s[3][30]; При операции s+1 он должен указать на следующий указатель. Именно для того, чтобы имя двухмерного массива соответствовало двойному указателю компилятор прибавляет к значению указателя сразу целую строку. Именно для того, чтобы арифметика указателей была одинаковой в поведении со статическими массивами и двойными указателями. А так как значение адреса статического массива по сути "только для чтения", то компилятор нне рискует тем, что если обратиться к имени массива как к указателю и попытаться что-нибудь ему присвоить, то естественно вылезет ошибка - так как указатели на подмассивы нигде не хранятся, а вычисляются по мере обращения. Это как раз и есть то отличие, почему имя двухмерного массива не является двойным указателем в чистом виде.
Никаких разных! Статический массив инициализирован! Поэтому прибавление к имени массива 1 позволяет сразу указать на след. элемент! char a[3][30]; a - приводится к двойному указателю на 1-й элемент массива. При прибавлении 1 а увеличивается на размер элемента хранения, в данном случае char[30] так как a имеет явный тип 3 указателя на массивы из 30 элементов Вы же не будете спорить, что void *p; - является указателем? Будьте добры, приведите арифметику указателей примениму к типу void? Арифметика указателей обязательно будет работать по-разному в зависимости от типа указателя. Кто с этим спорит? Я утверждаю, что двухмерные массивы С++ приводятся к двойному указателю согласно правилам стандарта.
Я не увидел ни одного вашего встречного примера - как должно быть. Я спокойно взял имя массива, произвел с ним согласно правила языка операции разыменования и доступа к элементу, а вы говорите, что согласно стандарта мои примеры не устроили. Приведите, пожалуйста главу стандарта, согласно которой вас не устроили мои примеры? Откуда такая уверенность? Вы видели как выделилась память? Это указатель на двухмерный динамический массив. Посмотрите на объявление функции. void PrintMas(int**P,int a, int b) Скажите с такой же уверенностью: что храниться в переменной P? Возьмем одномерный массив. char *s; Это указатель или массив? Пока мы непроинициализировали указатель - это неизвестно. В зависимости от того, что мы присвоим это может быть адрес переменной и адрес первого элемента массива.
Т.е. вы говорите, что приведенное мной объявление int **p; приводится к указателю на массив? У нас всего лишь двойной указатель - вы же сами говорили:
К какому массиву указателей? Он может содержать адрес конкретной переменной типа "Указатель на int" или адрес первого элемента массива таких указателей. По аналогии с одномерными массивами, согласно стандарта языка Си. int p; - одиночное значение int int *p; - указатель на int или на массив из таких int-ов int **p - указатель на указатель на int или на массив таких указателей Приведите пример, как вы объявляете динамический массив? Давайте посмотрим и обсудим ваш код.
Разница поведения компилятора - это не разница поведения указателей. Именно для того, чтобы привести имя двухмерного массива к двойному указателю компилятор и ведет себя по-разному. Как же иначе? Зато указатели ведут себя адекватно. |
||||||||||||
|
|||||||||||||
Fazil6 |
|
||||||||||||||||||||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
С чего ты взял, что компиллятор стремится чтобы
???? Ему до лямпочки ваши инсинуации по поводу того как массив или его имя представить как двойной указатель. Ему говорят "прибавь к указателю", он вычисляет размер того на что он указывает и прибавляет нужное количество байт. Он совершенно не стремится , чтобы это было как с двойным указателем. Зачем ему это? Он работает с указателем на массив , а это не указатель на указатель.
хм... она и так везде одинаковая... Повторяю, что компилятор четко разделяет статические массивы и двойными указателями.
Вот я и говорю, какого художника вы утверждаете что **(a + 1) работает с int**, если a + 1 дает смещение не на размер int* , а на размер подмассива? Только не надо говорить , что смещение на размер подмассива для того чтобы соответствовало двойному указателю.
нет. Нет такого правила в стандарте... Есть правило по поводу просто массива, но это правило не рекурсивно и переносить его на многомерные массивы нельзя.
Дискуссия с тобой началась с моих примеров....
ну применил ты разыменовывание, ну получил ты в итоге int. По твоему это доказывет, что тип разыменовываемого int**? Я говорю, что тип того, что ты разымновывал int (*)[n] (указатель на массив из n элементов). Если его имя разыменовать 2 раза получим int. Вот меня и не устраивает твой пример в котором двойным указателем и не пахнет.
я вижу объявление и этого достаточно, чтобы однозначно определить тип. Нет такого типа указатель на двухмерный динамический массив и в арифметике указателей твое p будет использоваться как указатель на int* и никак подругому. Вообще причем здесьэти экскурсы в динамическое выделение. Твой двухмерный динамический массив совершенно подругому расположен в памяти и то, что тут именно двойной указатель я не спорю
как его не инициализируй, но тип его не изменится. Это указатель на char. Даже new[] не сделает из него массива и его арифментика будет основываться на размере char. Мы говорим о нормальных класических статических массивах и динамические массивы идут в сад...
повторяю, динамические массивы нервно курят в саду... Речь не о них.
ну не надо передергивать... было ведь так
|
||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||
Xenon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1529 Регистрация: 12.4.2006 Репутация: 11 Всего: 50 |
Anikmar,
Это что, работать должно? p - не l-value, к нему не может быть применем инкремент. |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
В моем примере p был указан как **p Инкремент я имел саму операцию увеличения указателя на 1 без его изменения в таком смысле: int p[3][4]; *(p+1).... Так мы же можем делать и никто нас не убьет за это Fazil6, Я честно говоря тольо отвечаю на ваши вопросы, никак не получив одного единственного ответа: Каких действий вы ждете от работы с именем массива как с двойным указателем, которые вас не устраивают. Поэтому дальнейшее обсуждение возможно только по приведению вашего кода с двойным указателем, которых вы не можете добиться от имени двойного массива. Если вас интересует именно инкремент в чистом виде, чтобы он прибавлялся именно на 1 - это конечно очень интересно, но как выше уже обсуждалось числовое значение адреса никого особо не трогает - так как не нужно. Я просил вас привести некоторые примеры - вы настойчиво заняли позицию нет это не то. Понимаете, у меня нет цели вам продать какой-либо продукт, а вы как придирчивый покупатель не хотите его покупать. Я прошу вас, показать пример объявления функции, которая получает на вход статический двухмерный массив, размерности которого заранее неизвестны. Если делать это по рекомендациям Страуструпа вы все равно его приведете именно к двойному указателю. Изначально ваш вопрос звучал так: Покажите мне примеры, где с именем массива работают так же как с двойным указателем. Я вам показал рабочие примеры, которые не просто показывали что это работает, но и несли смысловую нагрузку - доступ к строке матрицы и к конкретному элементу. Сейчас я уже начинаю себя ловить на мысли, что мне надо доказать вам, что имя двойного массива ЯВЛЯЕТСЯ двойным указателем. Нет. Двухмерный массвив не является двойным указателем. Его лишь можно так рассматривать по одной причине: В языке Си имя одномерного массива можно рассматривать как указатель на его первый элемент. Т.е. как указатель на тип данных массива: Утверждение 1 <type> Ar[NNN] - т.е. имя такого массива можно рассматривать как тип <type> * Переходим к второму измерению <type>Ar[MMM][NNN] Теперь Ar имеет тип Массив из MMM элементов, каждый из которых является массивоим из NNN элементов типа type. Согласно утверждению 1, имя массива можно рассматривать как указатель на его первый элемент. Т.е. в нашем случае имя массива это указатель на 1-й массив (ну вернее нулевой) из NNN Элементов. Т.е. указатель на <type>[NNN] <type>.[NNN] в первой части нашего утверждения ужы была рссмотрено как <type>*. Значит мы можем рассматривать имя двухмерного массива как указатель на <type>* что является <type>** Если эти же рассуждения перевести к другой логике, то можно рассмотреть ее так: typedef a10 int[10]; a10 a; // Если взять отдельно a, то она может рассматривать как указатель на int и может вести себя именно так. //Имя одномерного массива является указателем на его первый элемент, значит int* a10 aa[10]; // Имя массива является указателем на 1-й элемент. Т.е. имеет тип *int[10]. // Последний в свою очередь может быть рассмотрен как int* Следовательно aa можно рассмотреть как int** Еще раз повторю, фразы : "может быть рассмотрен", "с ним можно работать как" не синонимамы фраз "является" Что собственно я вам показал и доказал примерами своего кода. А варианты, "А покажите мне код где с именем массива работают как с двойным указателем, и чтобы еще его значения соответсвовали двойному указателю" совершенно нелогичны. Вообще, тип *int[40] не является стандартным типом языка C. Это уже инициализированный тип. Поэтому всегда можно сказать, что операции с ними отличаются от опреаций int **. Ну так int [][45] будут отличаться от int [][50]. Это что, тоже разные типы? Или все-таки частные случаи? Общия то базовый подоход операции [][] - это именно двойной указатель. И Именно к этому базовому подходу и подгоняет компилятор свои действия. Конкретно операция [][], применяемая к двойному указателю является аналогом разыменования. В случае со статтическим массив (но это является как раз именно частным случаем общего подхода) арифметика несколько упрощается, но не более. Опять таки пока мы не попробовали передать статический двухмерный массив произвольного размера в функцию. Там экономия на отсутствии реально хранящихся указателей вылиывается в проблему рассчета смещения. За все надо платить. Но общий подход всегда базируется на каком-либо базовом типе, а базовый тип - это двойной указатель, так как нету в языке си типа [][]. |
|||
|
||||
nickless |
|
|||
![]() Гентозавр ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2976 Регистрация: 29.8.2005 Где: Germany Репутация: 19 Всего: 181 |
![]() ![]() Немного статистики для сравнения: "Win vs. Lin": 122 дня, 453 поста = 3,71 поста/день "Собираем поклонников висты": 12 дней, 147 постов = 12,25 поста/день (это при активном участии тролля) Эта тема: 9 дней, 172 поста = 19,11 поста/день ![]() Вывод: религиозные войны отдыхают ![]() ![]() Ладно, больше не буду вам мешать ![]() -------------------- ![]() Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies - Linus Torvalds |
|||
|
||||
Fazil6 |
|
||||||||||||||||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
такие, когда будет видно, что имя используется именно как тип int**. Я тебе уже говорил, что таких примеров мне неведомо ибо двумерный массив никак не связан с двойным указателем. И имя двумерного массива никогда не используется как переменная типа int**. например это
доказывает, что a может использоваться как int**, и если бы такое выражение было корректно в С++ , то этого хватило бы для доказательства моей НЕПРАВОТЫ и безграмотности.
какие еще конкретные примеры??? С чего твои наезды на меня начались??? Посмотри внимательно.... http://forum.vingrad.ru/index.php?showtopi...t&p=1114163 там полно примеров.
Неправда. Вот как он прозвучал.
ты показал как двойной указатель использовать в качестве двумерного массива. Я не это спрашивал.
ну вобщем смысл был таким. Если вы утверждаете что int[2][2] и int** както связаны (имя или еще что-то) то приведите примеры из которых это будет видно.
вот здесь стоило остановиться ибо на этом рассуждения заканчиваются и дальнейшие умозаключения неправильны
ну вот это и неправильно. Это заблуждение. Я уже раз пять повторил!!!! Правило относящееся к одномерному массиву нерекурсивно!!!! Если мы можем рассматривать имя двумерного массива, то приведите мне пример где оно рассматривается компилятором как int**. Не надо хвататься за клаву. Нет таких примеров... Ты говоришь, что в примере **a - это работа с двойным указателем потому что получили int. Я говорю, что это работа с указателем на int[n] , а двойным указателем здесь не пахнет.
конечно это разные типы.
Бред.... Ничего компилятор никуда не подгоняет.
ну договорились... Получается есть в языке си тип "двойной указатель"... |
||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Наконец то из нашего баяна только один пост более мнее выделить можно. Откуда такая уверенность в этом: Правило относящееся к одномерному массиву нерекурсивно!!!! Это вы прочитали в стандарте? Еще раз рассмотрим int[n]. Это массив целых чисел, который может быть приведен к указателю на int. Причем приведен имено по стандарту - без всяких приведений типа. По сути компилятор это делает неявно: int a[45]; int *b=a; Так что имя одномерного массива практически является указателм на тип - так как приводится неявно. И почему это правило должно быть нерекурсивно? И главное где это написано?
Предлагаю остановиться на этом примере: int a[3][4]; int b = **a; |
||||
|
|||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
господа
посмотрите ассемблерный код и все станет понятно ![]() -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
будем ходить по кругу? Нет здесь int** Для наглядности
если а используется как указатель на int* , то выражение (a + 1) должно дать адрес на sizeof(int*) больший чем a, но мы получаем адрес больший на sizeof(int[4]) поэтому делаем вывод, что a здесь используется как указатель на int[4] , который в свою очередь никак не приводится к int** ибо тогда неправильно будет работать арифметика указателей и поэтому правило нерекурсивно. Это сообщение отредактировал(а) Fazil6 - 29.4.2007, 21:23 |
|||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
Никакой такой вывод мы не делаем. А просто вспоминаем, что имя массива не обычный указатель, а особенный, имеющий несколько ограничений, по сравнению с обычным указателем.
Могу перечислить те, что знаю и помню.
И последнее. Оператор sizeof(ar), используя имя массива в качестве аргумента возвращает размер всего массива в байтах, а не размер указателя. То есть в данном примере вернёт 16, а не 4. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Если вам будет легче, то int** является базовым типом для массива. Массив это частный случай поведения, в том числе и рассчета указателя. Еще раз повторю, в связи с тем что массив не является int**, но должен вести себя как int арифметика в нем естественно работает по-другому. Если говорить о нерекурсивности (я вообще не особо понимаю при чем здесь этот термин, но в общем то понятно) то: int a[5]; int *aa = a; Преобразование стандартное, все в порядке, но sizeof(a) и sizeof(aa) также будут отличаться. Однако это ведь вас не смущает? Тем не менее a ведет себя как указатель на int, тогда согласно вашей логике это не так - так как sizeof дают разные результаты? Еще раз повторяю: Я не говорю, что имя двухмерного массива является двойным указателем. Можно сказать, что это производный тип двойного указателя с перегруженной арифметикой. Однако если работать с ним как с двойным указателем он выдает именно тот результат, который ожидается. Этому посвящена отдельная глава стандарта (8.3) Там описана схема преобразования имени массива в указатель |
|||
|
||||
JackYF |
|
||||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Попробую оспорить эту фразу таким кодом:
Если двумерные массива приводятся к двойному указателю, то объясни, почему не компилируется часть 1 моего примера. И почему, если даже сделать reinterpret_cast<int**>, то функция будет работать неверно? |
||||
|
|||||
Fazil6 |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
Что дает разные результаты? при чем здесь sizeof(a) и sizeof(aa) ??? Вы Вместо того чтобы с пеной у рта доказывать что я дурак подумали бы оба что вы пишете и внимательно почитали что я пишу. int a[5]; - а как указатель на int -> в вычислениях указателя a + sizeof(int) int *aa - > в вычислениях aa + sizeof(int) где здесь будет тличие и разный результат????
фантазии.... |
||||||
|
|||||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Мы уже этот вопрос обсуждали.
Нельзя напрямую передать инициализированный массив в функцию. Хоть имя массива и можно передать как двойной указатель, но хранение динамических массивов и статических отличается. Поэтому функции необходимо знать размерности и способ хранения. Если мы хотим создать функцию, которая бы принимала как статический так и динамический массив в качестве параметров придется делать дополнительную работу: так как способ хранения в памяти отличается. Мне кажется это возникло из-за совместимости снизу вверх - в первых версиях Си об этом не подумали, а дальше уже вроде как деваться не было. Когда я начал изучать этот вопрос для меня это тоже было загадкой: зачем два разных механизма сделали для реализации одной и той же вещи. Причем достаточно неудобную. С другой сторону, статические двухмерные массивы переменного размера вещь достаточно редко используемая, для этого существуют динамические массивы.
Тут немного не так звучит моя фраза. Весь наш спор был об использовании имени массива. Не передачи его в функцию. В рамках функции это уже чисто двойной указатель и функция с ним работает уже по правилам двойного указателя (т.е. с базовым классом) и ничего не знает о статическом массиве (производном классе). Если мы хотим сделать функцию, куда мы можем передать как статический массив переменного размера так и динамический - без дополнительной работы не выйдет. Что предлагает Страуструп. Он предлагает преобразовывать статический двухмерный массив в одномерный, передавать в функцию его базовый адрес и размерности, а смещение элемента вычислять динамически по мере надобности. Достаточно странная рекомендация человека, разработавшего этот язык. Если матрица достаточно большая, а элементы нужны не по порядку а вразброс - то это будет накладка по времени и причем серьезная. И внутри функции этот массив уже даже не выглядит массивом - так как нельзя использовать операции извлечения элемента по индексу. Для меня это полная загадка - сделали бы инициализированный массив указателей как сами же написали в стандарте и все было бы замечательно (правда кроме этого спора - его не было бы). Вместо этого этой теме мало того, что посвящают достаточно большую главу в стандарте, еще и в книгах кто как горазд пишет. И ведь действительно, идиотская ситуация: один и тот же логический объект (двухмерный массив) по-разному храниться при статическом и при динамическом варианте создания. По меньшей мере странно. Лично я никогда не пользуюсь статическими двухмерными массивами - они мне видятся достаточно неудобными как раз по причине их передачи в функции. Я для передачи статического массива в универсальную функцию вручную привожу его к двойному указателю, чтобы функция работала как со статическим массивом любого размера так и с динамическим - т.е. для функции по сути это двойной указатель, к которому спокойно применима операция извлечения элемента из массива. Ну это все вода. К сожалению по сути вашего вопроса говорю, что имя двухмерного массива можно использовать как двойной указатель только в рамках блока, в котором он определен. Дальше уже хлопоты - хотите делать функцию, которая работает и со статическими массивами и с динамическими - без накладных расходов не выйдет. Так уж устроен язык. Либо теряем возможность удобной работы через квадратные скобки, либо перед передачей статического массива приводим его полностью через промежуточный массив указателей к двойному указателю. Можно конечно и наоборот сказать, что это двойной указатель ведет себя как статический массив. Но вот тут как раз и есть костяк моего мнения: для того, чтобы сделать работу хотя бы в рамках блока универсальной и перегружена указательная арифметика статического массива. Для чего так было наворачивать я не знаю - было бы все одинаково было бы проще. Всяк жизнь прграммисту наровит испротить ![]() Это сообщение отредактировал(а) Anikmar - 30.4.2007, 09:45 |
|||
|
||||
MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 52 Всего: 207 |
<type> a[N] - массив размерности 1 - есть суть последовательность элементов одного типа
<type> a[N][N] - массив размерности 2 - есть суть последовательность массивов размерности 1 элементов одного типа <type> *a - указатель на элемент определенного типа - есть суть адрес элемента <type> **a - указатель на указатель элемента определенного типа - есть суть адрес элемента, содержащего адрес элемента <type> **a != <type> a[N][N] потому как <type> a[N][N] = {a11, a12, a13, ... ,a1N, a21, ..., a2N, ..., aN1, ..., aNN} если <type> **a содержит адрес элемента <type>* и, предположем, этот элемент первый элемент массива из N элементов <type>*, то <type> **a = <type> *a[N] = {a1*, a2*, ..., aN*}, из этого случая видно, что <type> a[N][N] != <type> **a, но т. к арифметика указателей гласит, что, <N раз *>a = a[0]...[0] (N раз), то получаем, что любой массив вида <type> a[A][B][C]... может быть представлен как int<A * B * C * ... раз *>, обратное (как уже показали) не верно Это сообщение отредактировал(а) MAKCim - 30.4.2007, 09:56 -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
У меня сложилось впечатление, что я всем доказываю, что двухмерный массив является двойным указателем, а со мной спорят. Причем иногда мне самому уже так кажется (что я это доказываю)
![]() Итак подвожу итого: Все участники спора прекрасно понимают как организованы в памяти массивы как статические так и динамические. Это на самом деле главное - никто не наворотит ошибок, связанных с непониманием вопроса. Пролистал ответы и что-то не увидел внятного примера передачи любого массива в функцию - сразу какой-то спор пошел, а тема именно с этого началась. ![]() Я влез в спор по другому поводу именно с примером - как можно имя двухмерного массива использовать как будто это был бы двойной указатель. Приведенные примеры опонента не устроили - и растянулся теоритический баян, когда в процессе спора уже забыли о чем начали. Да и ладно, в общем то. Не устроили и ладно - главное, что мои примеры рабочие, правильные и могут кому-нибудь пригодиться, а как конкретно это назвать - дело десятое. Я назову получение необходимой информации о статическом массиве - и не более. Исходя из этого, я подведу итого - так как окончательно точку в споре может поставить только самый свежий стандарт C++, его я не нашел, нашел только теоретические статьи, где про нашу тему скромно говориться "вопрос в стадии решения". Может где-то что-то и есть - просто я не нашел. Итак ИТОГО, что я собрал из всей темы: 1. Имя двухмерного статического массива двойным указателем не является. 2. Для передачи статически объявленного массива в функцию объявление такого массива в основной программе и в функции должно совпадать. Т.е. статический массив переменной размерности в функцию без дополнительных ухищрений и приведения типа не передать. По сути это означает, что в языке нет типа "двухмерный массив" - так как универсальное описание двухмерного массива переменного размера отсутствует. Это же относится к оличеству измерений больше 2. 3. Для получения информации об указателях на строки (или столбцы) статического двухмерного массива можно использовать его имя и синтаксис, аналогичный применяемому к двойным указателям. 4. Двойной указатель можно представить при надлежащей инициализации двухмерным массивом. 5. Физическая организация многомерного массива при статическом объвлении и динамическом создании отличается как минимум на дополнительный массив указателей для каждого измерения свыше 1. Всем спасибо за участие в споре, как минимум народ вокруг повеселили и ладно. Думаю надо переключаться на более продуктивные вещи. Еще раз всем спасибо. ![]() |
|||
|
||||
Fazil6 |
|
||||||||||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ты сам себе противоречишь. В месте вызова функции массив определен и размерности его известны. То что будет дальше (внутри функции) нас вообще не интересует потому что такой код все равно не компилится. Значит нельзя использовать имя масива как двойной указатель. Ты утверждаешь, что если по стандарту имя int а[2] может использоваться как int* , то продолжая эту аналогию int aa[2][2] можно использовать как int**. У нас (несогласных с этой точкой зрения и считающих, что это заблуждение и необоснованые домыслы) возникает справедливый вопрос : почему тогда это не переносится на примеры кода?
По поводу стандарта. Нет НИГДЕ в стандарте упоминаний того, что имя двумерного массива двойной указатель. Есть пункт 8.3.4.8, который здесь приводили. Есть еще 8.3.4.7
сказано совершенно четко, что имя многомерного массива конвертируется в указатель на массив меньшей размерности. Все! Больше никаких конвертаци дальше нет! Сказано, что если к нему применить *operator , то результат этой операции конвертируется тоже в указатель. Для того чтобы получить этот результат (к примеру для двумерного массива) имя массива используется как уазатель на массив, а не на int*. Т.е. уже все, он уже использовался не просто как указатель , а именно как указатель на массив и дальше разглогольствовать, что дескать там тоже конвертируется в указатель не имеет смысла потому, что к имени двумерного массива это уже отношения не имеет. вчем прав? если
Добавлено через 5 минут и 5 секунд
ох... неправда... я сразу тебе сказал, что это выглядит только так и поэтому меня не устроило... Ладно... Закончили и забыли PS но Dov неправ |
||||||||||||||
|
|||||||||||||||
apook |
|
||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 794 Регистрация: 12.7.2006 Репутация: 9 Всего: 23 |
пошагам
что такое pa[ 0 ], pa[ 1 ], pa[ 2 ]- - это указатели которым надо присвоить адреса(т.к pa это массив из 3-х указателей ) напрашивается
т.е напрямую или косвенно имеется ввиду значок & теперь
абсолютно ненужный (int *) * и & означают ведь разные вещи не пример конечно работает.. Вот и все, а вообще просто было плохое настроение вот я и возмутился на такую совсем мелочь, смысл значил крайне мало, надеюсь не из-за этого так раздулась данная тема -------------------- Мои руки из дуба, голова из свинца ну и пусть ... |
||||||||||
|
|||||||||||
Anikmar |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
ЭТО МОЙ ПОСЛЕДНИЙ ПОСТ В ЭТОЙ ТЕМЕ - иначе мы ее на завершим.
Вот как советует приводить первый элемент двойного массива господин Страуструп:
Там много текста - это конкретно выражение у него используется для получения указателя на первую строку. m - двухмерный массив Самое смешное, в его примерах ничего несказано, что статический двухмерный массив передается в функцию с явным преобразованием к двойному указателю. ИМХО Код Страуструпа сомнителен с точки зрения быстродействия.
Ну не устроило - так не устроило, что я могу сказать. Автора темы - пусть галочку поставит "ТЕМА ЗАКРЫТА" Хоть как тут меня называйте и обзывайте - в этой теме больше нислова не скажу ![]() Это сообщение отредактировал(а) Anikmar - 30.4.2007, 16:07 |
||||
|
|||||
Ln78 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
FiMa1 и все желающие – получите обещанное окончание. Там есть обращение и к apook. Likehood, threef – основное содержание вам вряд ли будет интересно, но последние 2 страницы, возможно, вам понравятся.
Fazil6. У меня недостаточно постов, чтобы поставить тебе +, поэтому скажу здесь - молодец. 10 раз объяснять одно и то же, когда и первое объяснение было простым и понятным, сохраняя при этом вежливость и видимое спокойствие, - я бы, наверное, так не смог. Хотя и у тебя уже динамические массивы начали нервно курить. В одном из соседних топиков обсуждался, в частности, вопрос выхода из вложенных циклов. Не знаю, какой вложенности здешний «цикл» обсуждений, но это – моя 4-я попытка вставить break. Хотел было обратиться к многоуважаемой Earnest с просьбой поставить здесь свой весомый return, да прочитал абзац про ничего не понимающего в массивах Страуструпа и передумал. Да… В общем, береги невры Fazil6, ты нам нужен живым и здоровым ![]() Присоединённый файл ( Кол-во скачиваний: 11 ) ![]() |
|||
|
||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Подведу и я свой мини-итог.
Тип "двойного массива" != тип "двойной указатель". Внутренности двойного массива не тождественны внутренностям двойного указателя. Ни неявное, ни явное преобразования не приводят один тип к другому. То, что объединяет эти два типа - возможность обращения к элементу через двойную индексацию. Надеюсь, от меня в этой теме тоже все. |
|||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
![]() Fazil6, apook, Anikmar, JackYF, что это вы на 13-й странице остановились? Примета плохая, надо еще одну-другую накатать ![]() |
|||
|
||||
FiMa1 |
|
||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Ln78, спасибо тебе огромное! Старался читать с особым пристрастием. Есть вопросы...
Ну с arA[0], допустим, понятно. Это имя переменной, значением которой м.б. только целое число. arA, насколько я понял - имя указателя, т.е, по-сути, тойже переменной, значением которой, однако, может быть только адрес (ну и другие, в данном контексте несущественные, отличия обычной переменной от указателя). Далее выполняем следующие действия:
Действия в обоих строках абсолютно одинаковые? Если да, то вопрос2 - как таки работает приведение, использованное в первой строке? Фактически берем адрес указателя arA, приводим его к указателю.. ну не понятно.. В противном случае, если arA - не указатель, а просто переменная, то почему нельзя записать:
Ну и в догонку - что за тип такой 'int (*__w64 )[10]' ? ДРУЗЬЯ, БОЛЬШАЯ БРОСЬБА В ДАННОМ ТОПИКЕ ДИСКУССИЙ НЕ РАЗВОДИТЬ! РЕЖИМ ВОПРОС-ОТВЕТ ЛИБО РИДОНЛИ ;) СПАСИБО! Это сообщение отредактировал(а) FiMa1 - 3.5.2007, 14:42 |
||||||||||
|
|||||||||||
Ln78 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
FiMa1, как бы тебе ответить, чтобы не спугнуть здешнее затишье? Может, если у тебя ко мне появятся по этой теме ещё вопросы, лучше задавать их в личку? Хотя я на форуме новичок, не знаю, как лучше.
Собственно, ответ на вопрос. Тебе можно считать, что 'int (*__w64 )[10]’ это есть адрес массива из 10 элементов, т.е. собственно то, что написано буквально. Модификатор __w64 это специфическое для VS определение, связанное с вопросами портирования из 32-х в 64-х разрядный компилятор, для тебя, наверное, это неважно. Если его убрать, то получим просто указатель на массив из 10 элементов. Т.е. если мы напишем так: typedef int ArrayInt10[10]; ArrayInt10 *pAr = &arA; то никаких замечаний от компилятора, естественно, не получим. Как я там писал, единственная причина, зачем я написал эту строчку, показав, что и такое сработает: Только для того, чтобы продемонстрировать один нюанс: не следует считать, что для компилятора arA и &arA[0] абсолютно одно и то же. Т.е. здесь к arA мы можем применить операцию взятия адреса, а к &arA[0] – нет. Основное, что ты должен запомнить, когда делаешь явные приведения: существует только память под 10 элементов int, к этой памяти можно адресоваться. И на все три варианта будет получен только один ответ: адрес начального элемента массива. Ничего больше нет. Компилятор не выдумщик, ему просто нечего больше возвращать. Все примеры преобразований, которые я приводил, например, с «превращением» двумерного массива в трёхмерный, рисуя таблички, как оно находится в памяти, я приводил для демонстрации этого факта (ни один бит при этих преобразованиях даже не пошевелился, это просто указание компилятору воспринимать область памяти так или иначе). В примере с тем одномерным массивом: есть массив из 10 чисел. Адрес первого (нулевого) элемента этого массива мы в начале привели чёрт знает к чему (могли привезти к указателю на рыжую корову, это сути не меняет), а потом явно сказали, что это всё-таки указатель на целое число (или несколько чисел), т.е. к тому, как оно есть на самом деле. Ещё раз повторюсь, так как написано в первой строке – никогда не делай. «Просто переменная» может быть чем угодно и указателем, и указателем на указатель, да мало ли ещё чем. Но при присваивании типы операндов должны совпадать (или для них в языке должны быть определены правила преобразования), иначе компилятор выдаст ошибку. Силой компилятор можно заставить считать, что это другой тип, но дальнейшая ответственность на том, кто такое приведение написал. |
|||
|
||||
FiMa1 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Под "привели чёрт знает к чему" ты подразумеваешь то, что мы зачем-то взяли адрес указателя? В то время, как могли бы просто написать int *pArr = (int *)arr; или и подавно int *pArr = arr; вместо:
PS: Ln78, не серчай, если шибко надоедаю, заглядывай периодически в топик, вопросы, имхо, будут... Это сообщение отредактировал(а) FiMa1 - 3.5.2007, 15:04 |
||||
|
|||||
Ln78 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
FiMa1, я совсем "не серчаю", что ты. Мы все не экспертами родились, вопросы задавать нормально. "Черт знает к чему" - не от "серчания", а просто, чтобы было понятнее. Я просто боюсь опять поднять волну в этом многострадальном топике. Именно это я и имел в виду. Единственное, всё-таки, нет там указателя (как такового, для которого компилятор отвёл место, для которого можно писать что-то типа int**), есть имя массива, о чём эти 13 страниц и говорили, и примерно столько же я написал тебе в комментариях.
|
|||
|
||||
FiMa1 |
|
||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Очередной вопрос..
Строку инициализации указателя pArr[0] компилятор приводит к виду *(*(pArr + 0) + 1) = 4; ? Нагло воспользовавшись твоими знаниями попытаюсь удовлетворить свою любознательность..
Почему компилятор MS VS.NET 2003 разрешает создать такую структуру, ведь обратиться к ее члену будет невозможно, т.к. имя создаваемому структурой типу не дано?
Если верить codelord, то не рулит компилятор MS.. ? Это сообщение отредактировал(а) FiMa1 - 3.5.2007, 16:38 |
||||||||
|
|||||||||
codelord |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 777 Регистрация: 7.5.2005 Где: ты моя темноглаза я где?! Репутация: 1 Всего: 39 |
gcc
Это сообщение отредактировал(а) codelord - 3.5.2007, 16:30 |
|||
|
||||
Ln78 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 25.11.2006 Репутация: 13 Всего: 15 |
На первый вопрос - да.
На второй (несколько выходит за тему топика) строгого формального ответа не знаю, но как бы я это объяснил для себя: это объявление сродни описанию неиспользованной переменной: пользы от неё никакой, но и вреда тоже. В случае с константами ситуация другая: если компилятор обработал такое определение переменной, то предполагается, что к ней можно обращаться за значением, а поскольку у неё значения нет - воспринимается как ошибка. Формально правильнее, наверное, можно было бы сказать: синтаксис такой, то нельзя, а это можно. Но, учитывая, что синтаксис создавался предварительно подумав, логика какая-то быть должна. А поскольку не я определял синтаксис, точного объяснения дать не могу. Можешь создать ещё один топик по этой теме, возможно, получишь много интересных вариантов в ответ. |
|||
|
||||
FiMa1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 408 Регистрация: 23.9.2006 Репутация: 5 Всего: 6 |
Имя одномерного массива - это константа, представляющая собой указатель на 0-ой элемент массива. Этот указатель отличается от обычных тем, что его нельзя изменить (установить на другую переменную), поскольку он сам хранится не в переменной, а является просто некоторым постоянным адресом. Андрей Богатырев. Хрестоматия по программированию на Си в Unix
Как таки будет выглядеть определение для МНОГОМЕРНОГО массива? |
|||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
FiMa1, а сам-то ты как думаешь? Намёк: многомерный массив представляет собой одномерный массив массивов. ![]() -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |