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

Поиск:

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


Опытный
**


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

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



Привет всем!

Читаю "Программирование на языке Си" Афанасьева, появился вопрос... Автор пишет: "Следующие объявления переменных"
Код

int a[3][3] = { { 11,12,13 },
                    { 21,22,23 },
                    { 31,32,33 }  };

int *pa[3] = { a, a[1], a[2] };
int *p = a[0];

реализуют определенную схему размещения указателей на двумерный массив.
Согласно этой схеме доступ к элементу 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 *'.

Помогите, пожалуйста, разобраться...
PM   Вверх
Anikmar
Дата 21.4.2007, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Вот на это ругается:
Цитата(FiMa1 @  21.4.2007,  10:51 Найти цитируемый пост)

int *pa[3] = { a, a[1], a[2] };


У вас pa имеет тип *[3], т.е. в каждом элементе указатель на int
А при инициализации вы первому элементу присваиваете a, который имеет тип [3][3];

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


Опытный
**


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

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



Цитата(Anikmar @ 21.4.2007,  10:57)
Вот на это ругается:
Цитата(FiMa1 @  21.4.2007,  10:51 Найти цитируемый пост)

int *pa[3] = { a, a[1], a[2] };


У вас pa имеет тип *[3], т.е. в каждом элементе указатель на int
А при инициализации вы первому элементу присваиваете a, который имеет тип [3][3];

Спасибо, но мне изначально было понятно, что в выражении int *pa[3] = { a, a[1], a[2] }; пытаются проинициализировать массив указателей целыми значениями.. Хорошо немного переформулирую вопрос.
Есть следующие объявления переменных:
Код

int a[]  = { 10, 11, 12 };
int *p[] = { a, a+1, a+2 }; //p - массив указателей на int
int **pp = p; //pp - указатель на массив указателей на int

В данном случае, инициализация массива p указателями на элементы ОДНОМЕРНОГО массива a представлена второй строчкой кода.
Теперь есть объявление МНОГОМЕРНОГО массива:
Код

int a[3][3] = { { 11,12,13 },
                       { 21,22,23 },
                       { 31,32,33 }  };

Как правильно проинициализировать массив указателей int *pa[3] элементами a[0][0],  a[1][0] и a[2][0] ?

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


Эксперт
****


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

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



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

p[0] = a[0];
p[1] = a[1];
p[2] = a[2];


А инициализация {....} на сколько я помню допускается только константами (могу ошибаться - не помню, всегда инициализировал только константами, поэтому вопроса не возникало)
PM MAIL ICQ   Вверх
Dov
Дата 21.4.2007, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(FiMa1 @  21.4.2007,  10:51 Найти цитируемый пост)
int *pa[3] = { a, a[1], a[2] };

FiMa1, выбирай:
Код

int *pa[3] = { a[0], a[1], a[2] };
int *pa[3] = { (int*)a, a[1], a[2] };
int *pa[3] = { *a, a[1], a[2] };
int *pa[3] = { &a[0][0], a[1], a[2] };



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


Опытный
**


Профиль
Группа: Участник
Сообщений: 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
PM   Вверх
Anikmar
Дата 21.4.2007, 13:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(FiMa1 @  21.4.2007,  13:17 Найти цитируемый пост)
Anikmar, а что Вас смутило? Где используются НЕ константы?


Смутило, что a[...] может быть не константный. Но я не уверен - поэтому и написал, что точно не уверен.
Хотя если массив объявлен статическим - то наверное константы...
Просто ни разу так не делал - поэтому и засомневался.
PM MAIL ICQ   Вверх
apook
Дата 21.4.2007, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

int *pa[3] = { (int*)a, a[1], a[2] };

Это ни кчемный вариант просто лажа какая-то
Вот самый правильный вариант
Код

int *pa[ 3 ] = { &a[ 0 ][ 0 ], &a[ 1 ][ 0 ], &a[ 2 ][ 0 ] };



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


Опытный
**


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

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



Насколько я знаю инициализатором переменной в си и си++ выступает любое выражение.
Т.е вы можете, например, использовать вызов функции.
Код

int * arr = malloc(100);
free (arr);

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


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


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

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



Цитата(FiMa1 @  21.4.2007,  13:17 Найти цитируемый пост)
а вот вариант int *pa[3] = { (int*)a, a[1], a[2] };  мне непонятен ...

Цитата(FiMa1 @  21.4.2007,  13:17 Найти цитируемый пост)
Здесь что указатель приводится к указателю на int? Не понимаю как это работает, поясните плз..

Здесь указатель на указатель на int приводится к указателю на int
Имя массива а[][] имеет тип int**, т.е. указатель на указатель на int. Мы его приводим к типу int*, т.е. указатель на int. Почему? Потому, что каждый элемент массива pa[3] имеет тип int*, т.е. указатель на int.



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


Опытный
**


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

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



Цитата(apook @ 21.4.2007,  13:43)
Код

int *pa[3] = { (int*)a, a[1], a[2] };

Это никчемный вариант просто лажа какая-то
Вот самый правильный вариант
Код

int *pa[ 3 ] = { &a[ 0 ][ 0 ], &a[ 1 ][ 0 ], &a[ 2 ][ 0 ] };

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
PM   Вверх
apook
Дата 21.4.2007, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



 FiMa1  Да ты че не врубаешся в такую ерунду
int a[ 3 ] Dov привел к int *a это сущей воды пурга,
Цитата

*pa[3] = { a[0], a[1], a[2] }; это абсолютно тоже самое тому

если знаешь че тогда спрашиваещ smile


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


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


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

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



Цитата(apook @  21.4.2007,  13:43 Найти цитируемый пост)
Это ни кчемный вариант просто лажа какая-то

Ну, что же, apook, у тебя есть 3 варианта.
1. Обосновать своё утверждение и доказать свою правоту, тогда получишь +1 в репу.
2. Не обосновывать и ничего не доказывать, тогда получишь -1 в репу за необоснованый наезд.
3. Ивиниться за необоснованый наезд, тогда не получишь ничего. 

Желаю удачи.  smile 


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


Опытный
**


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

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



зачем вносить путанницу вот этим
Код

int *pa[3] = { (int*)a, a[1], a[2] };
 
вариантом.
он вообще тогда не доделан надо так
Код

int *pa[3] = { (int*)a[0], (int*)a[1], (int*)a[2] };

Не надо мугать меня минусами тебе во всякой ерунде наезды чудятся



--------------------
Мои руки из дуба, голова из свинца ну и пусть ...
PM MAIL   Вверх
Dov
Дата 21.4.2007, 14:22 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(apook @  21.4.2007,  14:12 Найти цитируемый пост)
Не надо мугать меня минусами тебе во всякой ерунде наезды чудятся

Я тебя не пугаю, а учу правилам хорошего тона. Ты должен уметь отвечать за свой базар. Если ты мои слова называешь 'пургой' и 'какой-то лажей', то потрудись, хотя бы это обосновать. 
 


--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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