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

Поиск:

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


Эксперт
****


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

Репутация: 51
Всего: 70



Цитата(dizzy1984 @  24.4.2007,  14:55 Найти цитируемый пост)
Хранятся ли в массиве char[10][10] указатели можно проверить с помощью окна Memory.

что за окно?
PM MAIL WWW   Вверх
Dov
Дата 24.4.2007, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



М-да. Как горохом об стену...  smile 

bel_nikita, я тебе про ерёму, а ты мне про фому.  smile Я что, возражаю про то, что ты написал.
Нет. Я вроде бы по-русски пишу, а вы не понимаете. Щас напишу большими буквами, что видно было хорошо. Я говорю, что ИМЯ ОДНОМЕРНОГО МАССИВА ЦЕЛЫХ ЧИСЕЛ - ЭТО УКАЗАТЕЛЬ НА ТИП ИНТ( ПОТОМУ ЧТО ХРАНИТ АДРЕС СВОЕГО ПЕРВОГО ЭТЕМЕНТА, КОТОРЫЙ ИМЕЕТ ТИП ИНТ) И ПО ЭТОМУ ИМЕЕТ ТИП ИНТ*(КАК И ВСЕ ОБЫЧНЫЕ УКАЗАТЕЛИ НА ТИП ИНТ). А ИМЯ ДВУМЕРНОГО МАССИВА ЭТО УКАЗАТЕЛЬ НА УКАЗАЗАТЕЛЬ НА ТИП ИНТ(ПОТОМУ ЧТО ХРАНИТ АДРЕС СВОЕГО ПЕРВОГО ЭТЕМЕНТА, КОТОРЫЙ ИМЕЕТ ТИП УКАЗАЗАТЕЛЬ НА ТИП ИНТ) И ПО ЭТОМУ ИМЕЕТ ТИП ИНТ**(КАК И ВСЕ ОБЫЧНЫЕ УКАЗАТЕЛИ НА ТИП ИНТ*).
И не имеет никакого значения, как был объявлен этот массив, так 
Цитата(bel_nikita @  24.4.2007,  12:38 Найти цитируемый пост)
  int a[] = {0,1,2,3,4,5,6,7,8,9};

или так
Цитата(bel_nikita @  24.4.2007,  12:38 Найти цитируемый пост)
int *b = new int[10];
 Оба имени это указатели на тип инт, а по этому имеют тип инт*, не смотря на те разтичия, что есть между ними.
Ладно, у меня такой вопрос. Есть двумерный статический массив 3х3 .И вот есть такой кусок кода. Вопрос очень простой. Какой тип, по вашему,  имеет указатель pAr и как он был объявлен. Если кому не трудно допишите недостающий код в начале main.
Код

int main()
{
          ...
    
    *(int*)pAr = 6;
    *((int*)pAr + 1) = 8;
    
    cout << *((int*)pAr + 1) << endl;
    
    return 0;
}
 




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


666
**


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

Репутация: 8
Всего: 24



Цитата(Dov @  24.4.2007,  15:28 Найти цитируемый пост)
и как он был объявлен

да хоть void *pAr;
PM MAIL   Вверх
Dov
Дата 24.4.2007, 14:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Вообще этот разговор похож на это.

А. -  дважды два равно 4.
Б. - нет. трижды три не равно 4.
А. - так я и не говорю, что трижды три равно 4. я говорю, что дважды два равно 4.
Б. - как оно может быть равно 4, если в таблице умножения не написано, что трижды три равно 4.
А. - да выкинь ты свою таблицу умножения, на пальцах прибавь 2 + 2. Будет 4.
Б. - прибавляй, не прибавляй, всё-равно  трижды три не равно 4.

Вот так мы и разговариваем.  smile

Добавлено через 7 минут и 31 секунду
Цитата(likehood @  24.4.2007,  14:35 Найти цитируемый пост)
да хоть void *pAr;

Можно и так, конечно, но давайте пока в рамках int`а, что бы не путаться.  smile 
И как по-русски назвать его тип?

Добавлено через 10 минут и 29 секунд
Вот я, например писал так:
int* это указатель на целое число.
int**  это указатель на указатель на целое число. И т.д.

А вы как назовёте?

Это сообщение отредактировал(а) Dov - 24.4.2007, 14:41


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


Эксперт
***


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

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



Цитата(Dov @  24.4.2007,  14:28 Найти цитируемый пост)
Нет. Я вроде бы по-русски пишу, а вы не понимаете. Щас напишу большими буквами, что видно было хорошо. Я говорю, что ИМЯ ОДНОМЕРНОГО МАССИВА ЦЕЛЫХ ЧИСЕЛ - ЭТО УКАЗАТЕЛЬ НА ТИП ИНТ( ПОТОМУ ЧТО ХРАНИТ АДРЕС СВОЕГО ПЕРВОГО ЭТЕМЕНТА, КОТОРЫЙ ИМЕЕТ ТИП ИНТ) И ПО ЭТОМУ ИМЕЕТ ТИП ИНТ*(КАК И ВСЕ ОБЫЧНЫЕ УКАЗАТЕЛИ НА ТИП ИНТ). А ИМЯ ДВУМЕРНОГО МАССИВА ЭТО УКАЗАТЕЛЬ НА УКАЗАЗАТЕЛЬ НА ТИП ИНТ(ПОТОМУ ЧТО ХРАНИТ АДРЕС СВОЕГО ПЕРВОГО ЭТЕМЕНТА, КОТОРЫЙ ИМЕЕТ ТИП УКАЗАЗАТЕЛЬ НА ТИП ИНТ) И ПО ЭТОМУ ИМЕЕТ ТИП ИНТ**(КАК И ВСЕ ОБЫЧНЫЕ УКАЗАТЕЛИ НА ТИП ИНТ*).

а мы все тебе говорим, что НЕТ, НЕ ТАК. ЭТО ТВОЕ ЗАБЛУЖДЕНИЕ.
Цитата(Dov @  24.4.2007,  14:28 Найти цитируемый пост)

Код

int a[] = {0,1,2,3,4,5,6,7,8,9};

Код

int *b = new int[10];


Оба имени это указатели на тип инт, а по этому имеют тип инт*, не смотря на те разтичия, что есть между ними.

Еще раз повторю, в первом случае имя может использоваться КАК указатель, а тип у него int[10] и правило по поводу имени массива нерекурсивно и имя многомерного массива не может использоваться как указатель на указатель и т.д. А все приемы типа явного приведения 
Код

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

std::cout << *a   << "\n";  
std::cout << *aa  << "\n";  // фигня выводится и если эту фигню еще вот так  попросить вывестись **aa то получим вообще чпок

это обман компилятора и ни к чему это привести не может. В этом примере, например, выведется совершенно разный результат. Твои примеры с строками просто неграмотные и ничего не доказывают просто из-за того что массивы char интерпретируются в соответтвующих операторах. Мой пример с шаблонами показывает что компилятор рассматривает именно как массивы, а для представления как указатель ему требуется выполнять приведение массива (или его имени как тебе будет удобнее).

Добавлено через 31 секунду
Цитата(Dov @  24.4.2007,  14:40 Найти цитируемый пост)
Вот я, например писал так:int* это указатель на целое число.int**  это указатель на указатель на целое число. И т.д.А вы как назовёте?

и при чем здесь массивы?
PM MAIL   Вверх
Dov
Дата 24.4.2007, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Fazil6 @  24.4.2007,  14:52 Найти цитируемый пост)
и при чем здесь массивы?

Я про pAr спрашиваю.

Добавлено через 3 минуты и 51 секунду
Цитата(Fazil6 @  24.4.2007,  14:52 Найти цитируемый пост)
В этом примере, например, выведется совершенно разный результат.


Fazil6, в предыдущем своём посте я тебе показал, как нужно делать. Или в предпредыдущем.


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


Эксперт
***


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

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



Код

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

    cout << *((int*)pAr + 1) << endl;
    return 0;
}


ну вот  так будет работать видимо как ты хотел показать. pAr здесь типа int[3][3], использовать можно как указатель на int[3].
Не совсем понимаю что ты хотел продемонстрировать.
Код

*(int*)pAr = 6;

правое выражение вполне нормально интерпретируется как значение инта по какому-то адресу... Ну продемонстрировал ты что элемент массива можно проинициализировать через одно место... Ну и что? Работает это потому же почему
Код

cout << pAr << endl;
cout << *pAr << endl;

выдаст абсолютно одно и тоже именно потому, что pAr массив

Добавлено через 7 минут и 21 секунду
Цитата(Dov @  24.4.2007,  14:58 Найти цитируемый пост)
Fazil6, в предыдущем своём посте я тебе показал, как нужно делать. Или в предпредыдущем.

то чтоли?
Код

std::cout << *(int*)aa  << "\n";

и где здесь указатель на указатель?
тут сказано, что значение в aa считать указателем на инт и вывести значение по этому адресу.  И что? Ну обманул ты компилятор...  Разве это что-то доказывает?


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


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


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

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



Fazil6, совершенно верно, именно это я и хотел увидеть. Что бы показать ещё и такой код:
Код
int main()
{
    int p[3][3];
    int** pAr = (int**)p; 
    
    *(int*)pAr = 6;
    *((int*)pAr + 1) = 8;
    
    cout << *((int*)pAr + 1) << endl;
    
    return 0;
}


Теперь ты воочию можешь убедиться, что для компилятора без разницы, как был объявлен pAr. Главное это как его воспринимает компилятор. А для него это тип  int**. 



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


Эксперт
***


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

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



Цитата(Dov @  24.4.2007,  15:29 Найти цитируемый пост)
Теперь ты воочию можешь убедиться, что для компилятора без разницы, как был объявлен pAr. Главное это как его воспринимает компилятор. А для него это тип  int**. 

ха-ха... Зачем же ты его везде приводишь к int* ? Действительно для компилятора без разницы. Ты ведь заткнул ему рот явными приведениями совершенно к другому типу. И он его воспринимает именно как int* везде кроме объявления pAr
Код

int** pAr = (int**)p;  // тут ты заставил pAr и p указывать на одну область памяти


cout << *pAr << endl; // удивись что выведется
cout << **pAr << endl; // чпок !!!



PM MAIL   Вверх
likehood
Дата 24.4.2007, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


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

Репутация: 8
Всего: 24



Кстати, так тоже работает:
Код

int main()
{
    int p[3][3];
    double*** pAr = (double***)p; 
    
    *(int*)pAr = 6;
    *((int*)pAr + 1) = 8;
    
    cout << *((int*)pAr + 1) << endl;
    
    return 0;
}

PM MAIL   Вверх
Fazil6
Дата 24.4.2007, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



это как раз и доказывает, что int p[3][3]; никаким способом в int** не превратить
PM MAIL   Вверх
bel_nikita
Дата 24.4.2007, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Dov,
Цитата(Dov @ 24.4.2007,  13:28)
Я говорю, что ИМЯ ОДНОМЕРНОГО МАССИВА ЦЕЛЫХ ЧИСЕЛ - ЭТО УКАЗАТЕЛЬ НА ТИП ИНТ( ПОТОМУ ЧТО ХРАНИТ АДРЕС СВОЕГО ПЕРВОГО ЭТЕМЕНТА, КОТОРЫЙ ИМЕЕТ ТИП ИНТ) И ПО ЭТОМУ ИМЕЕТ ТИП ИНТ*(КАК И ВСЕ ОБЫЧНЫЕ УКАЗАТЕЛИ НА ТИП ИНТ). 

Повторюсь еще раз, 
Код
int a[3]; // эквивалент указателя
int *b; // указатель

Но если по-твоему int a[3] это обычный указатель int*, тогда объясни всему миру почему не прокатывает: 
Код
  int a[10] = {0,1,2,3,4,5,6,7,8,9};
  int *b = new int[10];
  a = b;


Цитата(Dov @ 24.4.2007,  13:28)

совершенно верно, именно это я и хотел увидеть. Что бы показать ещё и такой код:
Код
int main()
{
    int p[3][3];
    int** pAr = (int**)p; 
    *(int*)pAr = 6;
    *((int*)pAr + 1) = 8;
    cout << *((int*)pAr + 1) << endl;
    return 0;
}


Зашибись! Напиши pAr[1][1] = 1; и удивись smile 


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Dov
Дата 24.4.2007, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Fazil6 @  24.4.2007,  15:42 Найти цитируемый пост)
это как раз и доказывает, что int p[3][3]; никаким способом в int** не превратить

Хорошо, тогда скажи мне, что тебя может убедить в том, что имя двумерного массива это указатель на указатель? 



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


666
**


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

Репутация: 8
Всего: 24



Цитата(Dov @  24.4.2007,  16:57 Найти цитируемый пост)
Хорошо, тогда скажи мне, что тебя может убедить в том, что имя двумерного массива это указатель на указатель? 

Если бы его можно было присвоить указателю на указатель и потом работать с этим указателем как с обычным двумерным массивом.
PM MAIL   Вверх
Dov
Дата 24.4.2007, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



bel_nikita, ну ёлы-палы, ну сколько можно?
Цитата(bel_nikita @  24.4.2007,  15:55 Найти цитируемый пост)
Но если по-твоему int a[3] это обычный указатель int*, тогда объясни всему миру почему не прокатывает: 


Цитату в студию, где я такое говорил? Только перед тем, как её постить, посмотри, что там написано, я тебя очень прошу.  


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

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

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

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

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


 




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


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

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