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

Поиск:

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


Эксперт
***


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

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



Цитата(Dov @  22.4.2007,  21:50 Найти цитируемый пост)
Я уже говорил, но для тебя ещё раз повторю. ar1 это указатель на первый элемент массива, т.е. на строку(или массив, если хочешь) "qwe". А имя,  "которое можно представлять как указатель" звучит так(ты не поверишь) : ar1[0] или *ar1, как тебе больше нравится. 

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

Цитата(Dov @  22.4.2007,  21:50 Найти цитируемый пост)
Xenon, с тобой я соглашусь, конечно, но только  не сейчас. По той причине, что  ты не попадаешь в контекст текущей полемики. Здесь идёт разговор о типах данных в плане приведения типов...

не работает приведение типов в том виде, в котором ты утверждаешь.

не приведется это 
Код

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

aa = static_cast<int**>(a);

и не приведется именно потому, что твое утверждение по поводу многомерных массивов ошибочно.
Цитата(Dov @  22.4.2007,  02:26 Найти цитируемый пост)
 Абсолютно то же самое можно сказать и про двумерный массив, который, по сути, является одномерным массивом, каждый элемент которого так же является одномерным массивом, и про трёхмерный и т.д.

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

кстати внизу есть ссылки. Вот например и там сразу рассматривается именно этот вопрос
http://forum.vingrad.ru/topic-98636.html



Цитата(Dov @  22.4.2007,  21:50 Найти цитируемый пост)
А я из дискуссии выбываю. Притомился я тут с вами. Всем пока.

а как же  твои слова ???


Цитата(Dov @  21.4.2007,  14:05 Найти цитируемый пост)
1. Обосновать своё утверждение и доказать свою правоту, тогда получишь +1 в репу.
2. Не обосновывать и ничего не доказывать, тогда получишь -1 в репу за необоснованый наезд.
3. Ивиниться за необоснованый наезд, тогда не получишь ничего. 


Цитата(Dov @  21.4.2007,  14:22 Найти цитируемый пост)
Я тебя не пугаю, а учу правилам хорошего тона. Ты должен уметь отвечать за свой базар. Если ты мои слова называешь 'пургой' и 'какой-то лажей', то потрудись, хотя бы это обосновать. 



Это сообщение отредактировал(а) Fazil6 - 22.4.2007, 22:14
PM MAIL   Вверх
apook
Дата 23.4.2007, 04:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

Имя массива - это указатель, хотя и константный, но всё же указатель. Почему? Да хотя бы потому, что содержит адрес, а адреса могут хранить только указатели

Dov Повторяю :указатель это переменная, а имя массива переменной не является(Не по той причине что это константный указатель)
  Есть имя массива a и есть обьект массива с именем a[0], так вот они синонимы, в памяти 
не указывает, а есть начало массива. походу так и рассматривается компилятором.
  Есть указатель pa который являясь указателем выступает в роли имени массива, в памяти
он указывает на начальный элемент массива но сам им не является, он расположен в другом месте.
Код

//блок из 10 последовательных объектов
int a[ 10 ]={ 1, 2, 3, 4, 5, 6, 7, 8, 9 };

//указатель на int
int *pa;
pa=a;
//a=pa не допускается

printf( "%d", *++pa );  //второй элемент массива
printf( "%d", *++a );   //с именем массива a такой номер не пройдет потому-что это не переменная
printf( "%d", *(a+1) ); //хотя так пожалуйста

Все свелось к выяснению разницы между массвами и указателями
и вот еще:
Если имя массива передается функции, то последняя получает в качестве аргумента адрес его начального элемента. Внутри вызываемой функции этот аргумент является локальной переменной,содержащей адрес.
т.е функция действительно всегда имеет дело с указателем.

тогда уж имя массива это массив имен переменных smile


Это сообщение отредактировал(а) apook - 23.4.2007, 04:58


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


Опытный
**


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

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



Dov, зачем споришь, если сам давно понял, что неправ? Помог FiMa1 
разобраться - молодец. Но дальше:
Цитата

Здесь указатель на указатель на int приводится к указателю на int 

это как раз ошибка, такое приведение, будь это так, недопустимо.
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;
PM MAIL   Вверх
dizzy1984
Дата 23.4.2007, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Dov, ты в самом деле не прав [][] и ** это разные типы.
Будет правильно если ты разберешься в теме и тебе, похоже, стоит извениться перед 
Fazil6.
PM MAIL   Вверх
bel_nikita
  Дата 23.4.2007, 11:41 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



дабы прекратить спор раз и навсегд читаем: тут (А разве char a[] не эквивалентно char* a ?)

Это сообщение отредактировал(а) bel_nikita - 24.4.2007, 09:44


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


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Dov @  22.4.2007,  21:50 Найти цитируемый пост)
Оставлю без комментария, хотя этому перлу прямая дорога на башорг, имхо.

обоснования?

Цитата(Dov @  22.4.2007,  21:50 Найти цитируемый пост)
правильно? Что не работает?  smile

А ты запусти и узнаешь.

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
Цитата(Dov @  22.4.2007,  21:50 Найти цитируемый пост)
А я из дискуссии выбываю. Притомился я тут с вами. Всем пока.

а как же  твои слова ???


Цитата(Dov @  21.4.2007,  14:05 Найти цитируемый пост)
1. Обосновать своё утверждение и доказать свою правоту, тогда получишь +1 в репу.
2. Не обосновывать и ничего не доказывать, тогда получишь -1 в репу за необоснованый наезд.
3. Ивиниться за необоснованый наезд, тогда не получишь ничего. 


Цитата(Dov @  21.4.2007,  14:22 Найти цитируемый пост)
Я тебя не пугаю, а учу правилам хорошего тона. Ты должен уметь отвечать за свой базар. Если ты мои слова называешь 'пургой' и 'какой-то лажей', то потрудись, хотя бы это обосновать. 


+1, поддерживаю.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Xenon
Дата 23.4.2007, 18:26 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 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


--------------------
user posted image  
PM MAIL   Вверх
Dov
Дата 23.4.2007, 23:01 (ссылка) |   (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
как всетаки сильно желание выдать желаемое за действительное...
Ничего не нужно выдавать. Нужно всего лишь написать одну строку:
Код
cout << *ar1;
и посмотреть, и убедиться, что выведется именно строка "qwe", так как она является первым элементом массива ar1.

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
Я и код привел тебе, на который компиллятор упорно твердит, что int [][] это не int**
Компилятор может и твердит, только я то здесь причём. Если я говорил, что int [][] это int**, то попрошу мою цитату в студию. Я говорил, и буду говорить, что имя массива(в данном случае двумерного массива целых чисел) имеет тип, который по русски называется указатель на указатель на инт, и обозначается так:  int**, подобно тому, как тип целых чисел имеет обозначение(в С/С++) int, а указатель на целое - int*. По этому я могу написать так:
Код
 int** pp = (int**)ar;

 А если ты утверждаешь, что имя массива или же сам массив имеет тип int [][], то покажи мне, как нужно написать. Так, что ли, или как то иначе:
Код
int** pp = (int [][])ar;
 

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
 и никто с тобой не соглашается,
Это да, хотя никто не говорит в чём имеено. Вернее,  не соглашаются в том, чего  я  не говорил. 

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
Почему не компиллируется всетаки мой пример?
А я откуда знаю, это ты должен знать. Мои примеры все компиллируются.

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
не работает приведение типов в том виде, в котором ты утверждаешь.не приведется это код 
Код

int a[3][3] = {{0,1,2}, {3,4,5}, {6,7,8}};
int **aa;
aa = static_cast<int**>(a);
и не приведется именно потому, что твое утверждение по поводу многомерных массивов ошибочно.
Где я давал этот код? Цитату в студию. Это твой код, а не мой. И я не обязан отвечать за то, что ты пишешь. 

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
имя многомерного массива можно использовать как указатель на его первый элемент
Ну-у-уу, наконец-то дошло.  Я рад.   smile   

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
но 1-м элементом многомерного массива является массив
Если рассматривать его, как одномерный массив массивов(например массив строк), то да. А если просто, как двумерный(например, двумерный массив одиночных символов), то нет. В этом случае 1-м элементом многомерного массива будет элемент с индексом[0][0], т.е. первый одиночный символ этого массива. 

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
,а не имя массива
Имя массива(например, целочисленного, в данном случае), не может быть не только первым, но и вообще никаким элементом массива, по одной простой причине. Имя массива это адрес певого элемена массива, т.е. указатель, а не целое число. Сколько раз я ещё должен это повторять, что бы до вас дошло?  smile 

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
и рассматривать его в свою очередь указателем вкорне неправильно.
 Ур-ра, дошло.  smile Если кто не понял, эта фраза относится к слову 'массив', а не к слову 'имя массива'. 
Совершенно верно, массив это не указатель. Указателем является только адрес первого элемента массива, т.е. его(массива) имя.
Fazil6, как-то полосами до тебя доходит, имхо.  smile 

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
 Ты ведь сам просил не путать массив с его именем
 smile  Вот видишь, я был прав, когда говорил тебе книжки почитать, а ты ещё обижался на меня за это. Ну, ладно, я не в обиде.  smile  

Цитата(Fazil6 @  22.4.2007,  22:13 Найти цитируемый пост)
а как же  твои слова ???
Так это ж я не тебе говорил, а apook`у. Или ты хочешь, что бы я это к тебе применил?  smile  
Кстати, прошу всех обратить внимание на то, что apook  после этого стал намного культурнее в общении, вот посмотрите на его посты до этого и после. Это две большие разницы. 
apook, ты молодец. Стало намного приятнее читать твои посты. Честно.  smile 

Цитата(apook @  23.4.2007,  04:30 Найти цитируемый пост)
Dov Повторяю :указатель это переменная, а имя массива переменной не является(Не по той причине что это константный указатель)
А по поводу этого я скажу тебе так. Указатель, он указатель не потому, что он переменная или константа, или ещё что-то, а потому, что его значением является адрес, понимаешь? адрес той переменной или константы, или ещё чего-нибудь, на которую он указывает. Имя массива это, конечно, не полноценный указатель, у него есть некоторые ограничения, но он хранит адрес и поэтому можно считать его указателем, во всяком случае компилятор именно так и делает.  

Цитата(Ln78 @  23.4.2007,  08:50 Найти цитируемый пост)
Dov, зачем споришь, если сам давно понял, что неправ?
Читай выше.  smile 

Цитата(Ln78 @  23.4.2007,  08:50 Найти цитируемый пост)
это как раз ошибка, такое приведение, будь это так, недопустимо.
Ну, что тут можно сказать? Читай книжки. Пока всё. 

Цитата(Ln78 @  23.4.2007,  08:50 Найти цитируемый пост)
Своим спором ты, с одной стороны, теряешь репутацию у тех, кому очевидна твоя неправота, с другой, что хуже, запутываешь начинающих. И зачем оно тебе надо?
Улыбнуло, даже слов нет.  smile 

Цитата(dizzy1984 @  23.4.2007,  10:30 Найти цитируемый пост)
Dov, ты в самом деле не прав [][] и ** это разные типы.


dizzy1984, читай выше или ткни меня носом, где я говорил, что это одно и то же. Про такой тип int[][], я только в этой теме узнал, что он вобще существует. И до сих пор не могу понять, как можно его, или к нему что-либо привести. 
 
Цитата(dizzy1984 @  23.4.2007,  10:30 Найти цитируемый пост)
Будет правильно если ты разберешься в теме
Лады, постараюсь.  smile 

Цитата(dizzy1984 @  23.4.2007,  10:30 Найти цитируемый пост)
и тебе, похоже, стоит извениться перед Fazil6.
Не вопрос, скажи только в чём я виноват.

Цитата(JackYF @  23.4.2007,  18:12 Найти цитируемый пост)
обоснования?
 JackYF, это моё мнение и я не должен его обосновывать или что-то доказывать, я его просто высказываю. Это не значит, что я хочу тебя чем-то обидеть, боже упаси. Просто, мне это показалось смешным. 

Цитата(JackYF @  23.4.2007,  18:12 Найти цитируемый пост)
А ты запусти и узнаешь
Я то запущу, конечно, но перед этим мне хотелось бы, что бы ты сказал, что твой код должен делать по твоему разумению, но, гадюка такая, не делает. 

Если кому-то не ответил, извините. Вас много, а я один тут за всех отбиваюсь.  smile 
Всем удачи. 

  



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


Эксперт
***


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

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



Dov, Твое высокомерие переходит всякие границы...

Цитата(Dov @  23.4.2007,  23:01 Найти цитируемый пост)
Ничего не нужно выдавать. Нужно всего лишь написать одну строку:
Код

cout << *ar1;

и посмотреть, и убедиться, что выведется именно строка "qwe", так как она является первым элементом массива ar1.

возможно, ты сильно удивишься, но строка "qwe" имеет тип char[4] - и никакой другой (совсем не char*)

Цитата(Dov @  23.4.2007,  23:01 Найти цитируемый пост)
Я говорил, и буду говорить, что имя массива(в данном случае двумерного массива целых чисел) имеет тип, который по русски называется указатель на указатель на инт, и обозначается так:  int**, подобно тому, как тип целых чисел имеет обозначение(в С/С++) int, а указатель на целое - int*. По этому я могу написать так


Бред... Ахинея... Приведи мне выдержку из стандарта или цитату из любой книги, где так будет написано (про двумерный массив и его имя и что его имя это указатель на указатель). Это указатель на первый элемент.  А  массив int a[3][3] является одномерным массивом массивов int[3], поэтому первым элементом будет массив и имя а является указателем на int[3] , а это не указатель и поэтому a не является указателем на указатель. 


Цитата(Dov @  23.4.2007,  23:01 Найти цитируемый пост)
Это да, хотя никто не говорит в чём имеено. Вернее,  не соглашаются в том, чего  я  не говорил. 

вот это кто говорил? 
Цитата(Dov @  21.4.2007,  13:49 Найти цитируемый пост)
Имя массива а[][] имеет тип int**, т.е. указатель на указатель на int

Именно с этим не соглашаются.


Цитата(Dov @  23.4.2007,  23:01 Найти цитируемый пост)
А я откуда знаю, это ты должен знать. Мои примеры все компиллируются.

Ну ты же все знаешь.... Не можешь простейшие ошибки найти в пяти строках?
не компилится именно потому, что имя двумерного массива int не является указателем на указатель int (int**). Именно об этом говорит компилятор. Не надо только приводить доводы, что reinterpret_cast поможет. Если бы твои домыслы были верны, то пример обязан был компилироваться. 

Цитата(Dov @  23.4.2007,  23:01 Найти цитируемый пост)

Код

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

Где я давал этот код? Цитату в студию. Это твой код, а не мой. И я не обязан отвечать за то, что ты пишешь. 

Это мой код. Ты отвечай за себя. Скомпилится Это? a здесь имя массива. По твоему это int**, получается , что одному int** присваивается другой int**,что мешает здесь скомпилироваться? 


Цитата(Dov @  23.4.2007,  23:01 Найти цитируемый пост)
Ну-у-уу, наконец-то дошло.  Я рад.


Цитата(Dov @  23.4.2007,  23:01 Найти цитируемый пост)
 Ур-ра, дошло.   Если кто не понял, эта фраза относится к слову 'массив', а не к слову 'имя массива'. Совершенно верно, массив это не указатель. Указателем является только адрес первого элемента массива, т.е. его(массива) имя.Fazil6, как-то полосами до тебя доходит, имхо.   

Вот только не надо строить из себя дядю наставляющего молодежь. После будешь выглядеть очень смешно...



Цитата(Dov @  23.4.2007,  23:01 Найти цитируемый пост)
Так это ж я не тебе говорил, а apook`у. Или ты хочешь, что бы я это к тебе применил? 

Я хочу чтобы ты их к себе применил, раз уж берешь на себя ответственность делать замечания, то начни с себя.




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


Эксперт
***


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

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



вот еще примерчик
Код

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 то получим вообще чпок



Добавлено @ 01:03
Цитата

2.10    Мой компилятор ругается, когда я передаю двумерный массив функции,
    ожидающей указатель на указатель.

О:      Правило, по которому массивы превращаются в указатели не может
        применяться рекурсивно. Массив массивов (т.е. двумерный массив в С)
    превращается в указатель на массив, а не в указатель на    указатель.
    Указатели на массивы могут вводить в заблуждение и применять их    нужно
        с осторожностью. (Путаница еще более усугубляется тем, что существуют
        некорректные компиляторы, включая некоторые версии pcc и полученные
        на основе pcc программы lint, которые неверно вопринимают присваивание
        многоуровневым указателям многомерных массивов.) Если вы передаете
        двумерный массив функции:

  int array[NROWS][NCOLUMNS];
  f(array);

    описание функции должно    соответствовать

   f(int a[][NCOLUMNS]) {...}
    или

                 f(int (*ap)[NCOLUMNS]) {...}   /* ap - указатель на массив */

        В случае, когда используется первое описание, компилятор неявно
        осуществляет обычное преобразование  "массива массивов" в "указатель
        на массив"; во втором случае указатель на массив задается явно.
        Так как вызываемая функция не выделяет место для массива, нет
        необходимости знать  его размер, так что количество "строк" NROWS
        может быть опущено.  "Форма" массива по-прежнему важна, так что
        размер "столбца" NCOLUMNS должен быть включен (а для массивов
        размерности 3 и больше, все промежуточные размеры).

    Если формальный    параметр функции описан    как указатель на указатель,
        то передача функции в качестве параметра двумерного массива будет,
        видимо, некорректной.

        Смотри: K&R I Разд.5.10 c. 110; K&R II Разд.5.9 c. 113.

полный тест http://faqs.org.ru/progr/c_cpp/cfaqrus2.htm



Это сообщение отредактировал(а) Fazil6 - 24.4.2007, 01:04
PM MAIL   Вверх
vinter
Дата 24.4.2007, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



 smile Fazil6, по моему это бесполезно, не трать ты нервы


--------------------
Мой блог
PM MAIL WWW   Вверх
Dov
Дата 24.4.2007, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Fazil6 @  24.4.2007,  00:13 Найти цитируемый пост)
Dov, Твое высокомерие переходит всякие границы...
Причём здесь высокомерие?
Fazil6, послушай меня. Вот ты не злись, когда читаешь, то, что я написал, а вдумывайся и старайся понять смысл написанного. Выкинь ты из головы эти стандарты, как будто нет их, ведь для того, что бы понять принцып работы они не нужны. Цитаты из книги я могу тебе дать, но книга написана на иврите. Если ты хочешь, я могу тебе дать цитаты с переводом на русский язык. Книгу написал Йоав Натив, израильский специалист.  Он автор многих книг по программированию, в частности по С/С++, системный аналитик, имеет научную степень. Кстати, это к твоему вопросу о том, кто мне сказал. И вобще, не важно, что кто где сказал. Важно понять, как это всё работает. 

Цитата(Fazil6 @  24.4.2007,  00:13 Найти цитируемый пост)
возможно, ты сильно удивишься, но строка "qwe" имеет тип char[4] - и никакой другой (совсем не char*)

Я понимаю, что компилятор тебе написал  char[4], но ты пойми, он это сделал для того, что бы ты увидел и понял к чему он придрался. Иначе, как он тебе это объяснит? Но сам он воспринимает эту строку именно, как  char*. 

Цитата(Fazil6 @  24.4.2007,  00:13 Найти цитируемый пост)
Это указатель на первый элемент.  А  массив int a[3][3] является одномерным массивом массивов int[3], поэтому первым элементом будет массив и имя а является указателем на int[3] , а это не указатель и поэтому a не является указателем на указатель. 
Fazil6, говоришь ты всё правильно, но понимаешь не верно. Буду думать, как бы получше объяснить... Прийдётся чуть ли не каждом слове останавливаться, ну да ладно, попробую.
Цитата
 А  массив int a[3][3] является одномерным массивом массивов int[3]
Вот этот int[3] тебя и путает, как видно. Давай пока я так скажу.  Массив int a[3][3] можно представить, как  одномерный массив, состоящий из 3 элементов(какого типа эти элементы поговорим ниже, но уж точно не  int[3]), каждый из которых является одномерным массивов, сосоящим из 3 элементов типа  int, т.е. из целых чисел. Стало быть, массив а имеет 3 подмассива(назовём их так, что бы не путаться в тетминах): a[0], a[1], a[2].
Рассмотрим подробнее подмассив а[0]. Это массив из 3 целых чисел типа int. Если а это имя для всего двумерного массива, то а[0] это имя только для этого подмассива. Ко всем трём элементам этого подмассива можно обращаться, указывая его имя а[0] и добавляя к нему индекс элемента. Что бы обратиться, например к последнему элементу, нужно написать a[0][2]. 
Поскольку этот подмассив, по-существу, является обычным  массивом, то его имя а[0] является указателем  на первый элемент а[0][0] и содержит его адрес. В этом легко убедиться. 
Код

 cout << a[0]  << endl;// значение указателя aq[0], хранящее адрес первого элемента подмассива
 cout << &a[0][0] << endl; // адрес первого элемента подмассива

Выведется один и тот же адрес. Делаем вывод, что имя подмассива a[0] является указателем на первый элемент, так как хранит его адрес, поэтому имеет тип указатель на инт, т.е. int*. Это понятно?  
Цитата
поэтому первым элементом будет массив
 Это правильно.
Цитата
и имя а является указателем на int[3]
 Похоже это то место, где ты путаешься. Имя а является указателем не на int[3], а на первый элемент, т.е. на а[0] и содержит его адрес. Это тоже легко проверить. Это то же самое значение, что и в тех двух строчках, которые я привёл выше, т.е. адрес а[0][0], который хренится в указателе а[0].
Код
 cout << a << endl; // значение указателя а, хранящее адрес первого элемента массива
 
Разыменуй его:
Код
 cout << *a << endl;
 И ты увидишь значение указателя а, т.е. адрес, который хранится в указателе а[0]. Это всё тот же адрес элемента с индексом а[0][0].
 Отсюда следует, что имя массива а, указывая на первый элемент т. е. на а[0], является указателем на указатель на инт, потому что, как мы выяснили выше, имя подмассива а[0] это указатель на инт. А поскольку имя массива а это указатель на указатель на инт, то он имеет тип int**. 

Все эти объяснения даны, как бы, с точки зрения компилятора, а не с точки зрения того, кто смотрит на экран монитора и видит там надпись int[][], а что это такое и как его применить он не знает.

Всё, на этом пока остановимся. Если кто не понимает моих объяснений, я не виноват. Я ни кому не навязываю своё мнение. Если кто-то считает, что int[3] или int[333] или int[3][3] это какой-то тип,  к которому можно хоть что-то привести, то ради бога, я не возражаю. Хотелось бы только взглянуть на это приведение.  smile 

Ну, вот. Написал несколько строчек, а потратил на это несколько часов.  smile 

Всем пока.


Извиняюсь, забыл про пример.
Если ты внимательно прочтёшь то, что я написал, то поймёшь, что нужно было бы, хотя бы, написать так:
Код
std::cout << *(int*)aa  << "\n";

А почему, я уже устал объяснять. 
Удачи. 



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


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


Эксперт
****


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

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



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

Смотрим через дизасм: 
Код
;aval = a[3];
mov ecx, dword ptr[ebp-28h]
mov dword ptr[ebp-3Ch], ecx

;bval = b[3];
mov edx, dword ptr[ebp-38h]
mov eax, dword ptr[edx+0Ch]
mov dword ptr[ebp-40h], ecx

Из этого всего видно, что a[3] и b[3] компилятор получает по-разному. 
Когда встречается а[3]: компилятор генерирует код, чтобы считать с позиции a[3]:
1) перемещается на три символа вперед
2) читает требуемый символ.

В случае b[3] компилятор генерирует код, чтобы начать с позиции b:
1) считывает значение указателя
2) прибавляет к указателю 3
3) читает символ, на который указывает указатель.

Т.е. int a[] != int *b.


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


Эксперт
***


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

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



Цитата(Dov @  24.4.2007,  11:59 Найти цитируемый пост)
Я понимаю, что компилятор тебе написал  char[4], но ты пойми, он это сделал для того, что бы ты увидел и понял к чему он придрался. Иначе, как он тебе это объяснит? Но сам он воспринимает эту строку именно, как  char*. 

очень смешно... Сам придумал? Когда-то строки определялись char*, но это было когда-то  и 
Код

char *p = "бла-бла"; // это допустимо сейчас для коректности старого кода


Страуструп. Язык программирования С++. Специальное издание.
стр. 84 
Цитата

3.5.1. С-строки

С-строки  - это массивы символов, ограниченные нулем ($ 5.2.2)....

там же
стр.130
Цитата

5.2.2. Строковые литералы

Строковым литералом называется последовательность символов, заключенная в кавычки:
"Это строка"
.....
Типом строкового литерала есть "массив с надлежащим количеством константных символов"; таким образом "Бор" принадлежит типу const char[4].


Цитата(Dov @  24.4.2007,  11:59 Найти цитируемый пост)
Но сам он воспринимает эту строку именно, как  char*.

нифига подобного. Он воспринимает тип char[n]

вот довольно простой пример
Код

template 
<class T> void f(T &a, T &b)
{
    std::cout << a << "  &  " << b << "   template\n";
}

void f(char *a, char *b)
{
    std::cout << a << "  &  " << b << "   not template\n";    
}

int main()
{
    f("PREVED", "MEDVED");
    f("PREVED", "PREVED111");
    
    return 0;

}

скомпилируй в 7-й или 8-й студии и удивись тому какая вызовется функция в каком варианте и подумай почему имеется именно такая картина. 


Цитата(Dov @  24.4.2007,  11:59 Найти цитируемый пост)
Похоже это то место, где ты путаешься. Имя а является указателем не на int[3], а на первый элемент, т.е. на а[0] и содержит его адрес. Это тоже легко проверить. Это то же самое значение, что и в тех двух строчках, которые я привёл выше, т.е. адрес а[0][0], который хренится в указателе а[0].

ничего я не путаю. Это ты путаешь.
Цитата

5.3 Указатели на масивы
В С++ указатели и массивы тесно связаны. Имя массива можно использовать в качестве указателя на его первый элемент ....

именно можно использовать, но не является. И по поводу первого элемента многомерного масива - это массив ибо Многомерный массив - это массив массивов.

Все мои примеры абсурдности твоих умозаключений ты игнорируешь.
 

Цитата(Dov @  24.4.2007,  11:59 Найти цитируемый пост)
Отсюда следует, что имя массива а, указывая на первый элемент т. е. на а[0], является указателем на указатель на инт, потому что, как мы выяснили выше, имя подмассива а[0] это указатель на инт. А поскольку имя массива а это указатель на указатель на инт, то он имеет тип int**. 

ничего из этого не следует кроме того, что указатель и массив - это разные типы.

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


Опытный
**


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

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



Хранятся ли в массиве char[10][10] указатели можно проверить с помощью окна Memory.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0787 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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