Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.12.2010, 15:43   #1
Valter
Пользователь
 
Регистрация: 29.03.2008
Сообщений: 51
По умолчанию Адресация многомерных массивов

Приветствую!

Интересует вопрос: непосредственно какие объекты создаются в памяти при определении, скажем, двухмерного массива?

Суть вот в чем: ни у K&R, ни у Шилдта, ни у еще много кого этот вопрос детально не оговаривается. У Ю.Ю.Громова, С.И.Татаренко (ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ СИ) в книжке я много косяков нашел, но у них как раз дается вот какое пояснение:

Цитата:
Указатели на многомерные массивы в языке СИ - это массивы массивов, т.е. такие массивы, элементами которых являются массивы. При объявлении таких массивов в памяти компьютера создается несколько различных объектов. Например при выполнении объявления двумерного массива int arr2[4][3] в памяти выделяется участок для хранения значения переменной arr, которая является указателем на массив из четырех указателей. Для этого массива из четырех указателей тоже выделяется память. Каждый из этих четырех указателей содержит адрес массива из трех элементов типа int, и, следовательно, в памяти компьютера выделяется четыре участка для хранения четырех массивов чисел типа int, каждый из которых состоит из трех элементов...

Таким образом, объявление arr2[4][3] порождает в программе три разных объекта: указатель с идентификатором arr, безымянный массив из четырех указателей и безымянный массив из двенадцати чисел типа int.
В других источниках, в том числе у K&R про создание промежуточных массивов не говорится.

Я для ясности написал программу для вывода адресов элементов обычного двухмерного массива. Вот, к примеру, исходный массив:

Код:
    int ar2[][3] = {
        {0, 1, 2},
        {3, 4, 5},
        {6, 7, 8}
    };
Следующая инструкция выдает полностью одинаковые результаты:
Код:
cout << (ar2 + 1) << ' ' << *(ar2 + 1);
Вопрос - почему?
Ведь если дополнительно создается промежуточный массив указателей, то у его элементов должны быть свои адреса. (ar2+1) - это адрес первого (начиная с нулевого) элемента промежуточного массива указателей, а *(ar2+1) - его значение, то есть адрес нулевого элемента первой строки (начиная с нулевой) в массиве int.

Почему они равны?

Ко всему прочему в ar2 хранится адрес первого элемента двухмерного массива, то есть ar2 = &ar2[0][0]. Но как так может быть, что при этом ar2 еще и указывает на начало другого массива - массива указателей???

Ведь если ar2 - это указатель на создаваемый промежуточный массив указателей на int, то (ar2+1) не должен равняться *(ar2+1), области памяти -то разные используются.

Или вся это катавасия с промежуточными массивами изначально неверна?

PS: уже весь мозг себе сломал на этом деле, но хочется разобраться до конца. Господа профессионалы, разъясните, пожалуйста.

Последний раз редактировалось Valter; 14.12.2010 в 15:52.
Valter вне форума Ответить с цитированием
Старый 14.12.2010, 16:07   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2Valter
вот честно, я столько раз расписывал, что нужно читать peter van der linden. deep c secrets, что аж тошнит отвечать на твой вопрос. но народ проигнорил. эта тема там раскрыта чуть более, чем полностью

Цитата:
У Ю.Ю.Громова, С.И.Татаренко (ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ СИ)
хорошая книжка. если ты в нее селедку заворачиваешь


http://www.bookshunt.ru/b10348

книжка настолько шикарна, что я заказал ее на ебее за бешенное бабло. но не жалею ни капли
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 14.12.2010, 16:14   #3
V0id
Пользователь
 
Регистрация: 12.12.2010
Сообщений: 30
По умолчанию

Я не профессионал, поэтому просто рискну предположить, что, вероятно, сейчас это зависит от компилятора... Некоторые могут создавать промежуточный массив указателей, а некоторые нет: то есть массив многомерен лишь для программиста, а на деле же для доступа к данным всегда используется указатель на начало блока данных, реальное смещение вдоль которого рассчитывается на этапе компиляции.
V0id вне форума Ответить с цитированием
Старый 14.12.2010, 16:23   #4
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

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

в цитате, что привел автор, у автора книги что то там переклинило, и он попутал динамические массивы (да, массив указателей на массивы) со статическими
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 14.12.2010, 20:18   #5
Valter
Пользователь
 
Регистрация: 29.03.2008
Сообщений: 51
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
2Valter
вот честно, я столько раз расписывал, что нужно читать peter van der linden. deep c secrets, что аж тошнит отвечать на твой вопрос. но народ проигнорил.
Я не проигнорил, просто я здесь на форуме бываю редко и не слежу за тем, кто кому что советует. Поэтому благодарю за наводку, буду копать эту книгу.

Цитата:
в цитате, что привел автор, у автора книги что то там переклинило, и он попутал динамические массивы (да, массив указателей на массивы) со статическими
Согласен, но тем не менее трудно было поверить в столь грубую ошибку авторов книги. Они там ничего не опечатались или еще что, если об этом речь. Приведенное мной выше описание - это их принципиальная позиция. Да ладно, там и еще ошибок тьма тьмущая, в основном именно на указателях.
Valter вне форума Ответить с цитированием
Старый 16.12.2010, 01:20   #6
deviart
 
Регистрация: 08.08.2010
Сообщений: 8
По умолчанию

cout << (ar2 + 1) << ' ' << *(ar2 + 1);

ar2 - массив массивов интов. В rvalue контекстах (а здесь именно таковой) автоматически приводится к указателю на свой первый элемент (этот элемент является одномерным массивом). Ты к нему прибавляешь единицу - получается указатель на второй элемент двумерного массива (то есть на второй одномерный массив). Этот адрес выводится.

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

То есть в первом случае выводишь адрес одномерного массива, во втором - адрес его первого элемента. Эти адреса численно совпадают.

Никаких указателей, естественно, не создаётся.
deviart вне форума Ответить с цитированием
Старый 17.12.2010, 12:59   #7
Valter
Пользователь
 
Регистрация: 29.03.2008
Сообщений: 51
По умолчанию

По книге ван дер Линдена с сабжем разобрался.

Всем спасибо за ответы!
Valter вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
DelphiПаскаль.обработка многомерных массивов.сложные циклы kate-27 Помощь студентам 15 23.04.2010 22:03
Обработки многомерных массивов с использованием циклов. DanielDefo Паскаль, Turbo Pascal, PascalABC.NET 3 01.04.2010 16:18
Чтение многомерных массивов из Фортрана в C++ Скарам Помощь студентам 2 08.09.2009 15:06
адресация в формулах andrewx Microsoft Office Excel 2 29.06.2009 17:44
Сортировка многомерных массивов С++ Perfect.Enemy Общие вопросы C/C++ 5 12.04.2008 16:39