|
5 / 5 / 2
Регистрация: 02.03.2011
Сообщений: 40
|
|
Понять указатели:)10.03.2011, 13:35. Показов 11484. Ответов 55
Метки нет (Все метки)
Добрый день!
Совсем недавно начал изучать С++, в основном по методичке, выданной в ВУЗе и по нескольким книгам (Страуструп Б., Стефан Дэвис) и плюс то, что нахожу в интернете. Практически, всё это привязано к ряду лабораторных и контрольных, которые необходимо сделать. Дошел до указателей....О_о. Проблема вот в чем: те практические примеры, которые показывают использование указателей, не отвечают на вопрос - зачем? То есть, все что сделано в этих примерах с помощью указателей, можно сделать и без них, и нельзя сказать, что это будет сложнее. Из-за этого очень трудно понять смысл указателей и они для меня пока что пустая абстракция . Есть ли какие-нибудь простые практические примеры, показывающие... почему без указателей не обойтись? Например, очень легко практически объяснить суть цикла или там функции.
0
|
|
| 10.03.2011, 13:35 | |
|
Ответы с готовыми решениями:
55
Указатели не могу понять Не могу понять зачем нужны указатели? Строки (массив char), указатели. Не могу понять логику! Help! |
|
40 / 38 / 5
Регистрация: 22.01.2011
Сообщений: 670
|
|||||||||||
| 10.03.2011, 19:00 | |||||||||||
|
так же дополню
![]()
Реальные переменные a,b из main соприкасаются с функцией в момент вызова функции image_swap(a, b); при этом создаётся копия значений a,b , и в функции уже совсем другие переменные, которые уничтожатся при выходе из функции, а про реальные переменные эта функция и не знает, где они находятся. Поэтому и не может их изменить.
0
|
|||||||||||
|
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
| 10.03.2011, 19:06 | |
|
dimon1984, перечитайте пятое и вторую половину двенадцатого сообщения в этой теме, и тогда, возможно, перестанете повторять то, что уже не один раз было разжёвано и на что ТС отозвался вполне удовлетворительным ответом "вроде понял".
1
|
|
|
|
|||||||||||||||||||||
| 10.03.2011, 19:19 | |||||||||||||||||||||
Сообщение было отмечено как решение
Решение
Svid, попробую вербализовать некоторые аспекты в менее гуманитарной манере
Для начала - думайте об указателях, как об адресах памяти. То есть:
Теперь о практике: представьте себе, что вам нужно написать функцию, которая выводит массив int, но вы заранее не знаете, массив какого размера ей передадут. Это могут быть 2 int'а, а может быть десь-тыщ. В этом случае проще сделать так:
00 AF 14 28 A8 76 42 00 00 00 01 00 00 00 02 00 00 04 A1 00 00 A7 70 21 17 86 61 0A При синтаксисе var[5] берётся адрес начала массива var и к нему прибавляется ( размер_элемента_массива_var * 5 ). То есть нулевой элемент массива int будет равен ( адрес_начала + (4 * 0) = адрес_начала ), первый - ( адрес_начала + (4 * 1) = адрес_начала + 4 ) и так далее. Вы в любом случае работаете с адресами, указатели просто позволяют это делать более просто. Теперь на счёт ссылки. По сути, ссылка - это константный указатель на неконстантные данные, то есть вы можете изменить данные по ссылке, но не можете изменить адрес, на который она указывает. Теперь на счёт синтаксиса printf():
Другой пример: вам нужно передать функции структуру, которая занимает в памяти 1 килобайт (ну, жирная такая структура). Вы можете либо это запихать целиком и подавиться, а можете вместо 1 килобайта записать 4 байта адреса этой структуры и на этом успокоиться. Что проще будет? ![]() Если что - спрашивайте. Добавлено через 1 минуту Не по теме: О, пока я писал, тема развилась... Если что - простите за повторения, ещё не ознакомился :)
4
|
|||||||||||||||||||||
|
5 / 5 / 2
Регистрация: 02.03.2011
Сообщений: 40
|
||
| 10.03.2011, 19:24 [ТС] | ||
|
Да нет, я не
Как объяснить, начинаешь изучать С++ - все понятно и последовательно, переменные,циклы, функции - есть какая-то задача, которая реализовывается с помощью цикла и т.д. А с указателями, такое впечатление, что их понятие вводится намного раньше того, когда их использование становится необходимым.
0
|
||
|
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
| 10.03.2011, 19:32 | |
|
Циклы и функции - это понятия, которые позволяют решать задачи (условный переход, как мы помним, совершил революцию в развитии вычислительной техники). Указатели - инструмент, который помогает их решать. Во многих языках нету указателей, поскольку там это не так необходимо. Поэтому указатели можно, по сути, вводить в любом месте материала, и везде они на первых парах будут одинаково непонятны.
0
|
|
|
5 / 5 / 2
Регистрация: 02.03.2011
Сообщений: 40
|
|
| 10.03.2011, 19:46 [ТС] | |
|
Спасибо, talis!
Стало намного понятней, особенно с функцией вывода массива. Я еще усвою, что Вы написали по поводу того, как выглядит массив в памяти, и думаю, все встанет на свои места. В методичке, блин, всего этого нет - там указатели появляются как сама собой разумеющаяся вещь
0
|
|
|
|
||||||
| 10.03.2011, 20:08 | ||||||
|
Не за что, Svid. Главное запомните: указатели - это точно такие же переменные, как и char, int, float, double и технически от них не отличаются ровно ничем. Более того, это самые обычные числа, то есть их можно (хотя и не нужно) складывать и вычитать. Иногда даже для перехода на следующий элемент массива используется инкремент указателя - это не всегда хорошая идея, но иногда так делают, и ничего плохого в этом нет, разве что тут выше риск сделать первоклассную утечку памяти. Единственный нюанс - тут значение указателя увеличивается не на 1, а на ( 1 * размер_элемента_массива ), то есть, в случае с int - сразу на 4.
0
|
||||||
|
9 / 9 / 4
Регистрация: 04.03.2010
Сообщений: 40
|
|
| 11.03.2011, 07:34 | |
|
talis, спасибо за развернутый ответ. Теперь еще понятнее стало
Я так понял, что при создании объекта без использования new, объект помещается в кучу, а в стек только указатель на адрес в куче. В таком случае, какие плюсы создания объекта без new? Получается, что структуры, объекты классов лучше создавать в динамической памяти. А тогда почему в книжках ( по Qt например ) создаются часть экземпляров класса без new, а часть с new?Например, GUI элементы, объект приложения ( QAplication ) в книге создаются без new.
0
|
|
|
122 / 85 / 16
Регистрация: 14.02.2011
Сообщений: 340
|
|
| 11.03.2011, 17:21 | |
|
хоть тему я не открывал, но благодаря Вам всем. я тоже усек что такое указатели и как их использовать
. спс удачи всем!п.с. поставил закладку..если что еще раз прочту
0
|
|
|
|
|||||||||||
| 12.03.2011, 13:03 | |||||||||||
Сообщение было отмечено как решение
Решение
Feax, для ответа на ваш вопрос нужно объяснить, что такое пространство имён.
Запустите этот пример:
Теперь давайте всё назовём своими именами. Часть кода между операторными скобками называется пространством имён. Подумайте над названием, оно вам многое скажет. У функции main() есть своё пространство имён (тело функции), в нём есть вложенные пространства имён - у оператора if и отдельно стоящее на строчках 24 и 30. int var, объявленная внутри пространств имён if и на строчке 24, перекрывает int var функции main(), но не удаляет её. Они существуют только внутри своих пространств имён и уничтожаются при выходе из них. Теперь посмотрите на пространство имён строчки 30. В нём не объявлена своя int var, поэтому берётся int var из родительского пространства имён, если такая существует. Если нет - просматривается пространство имён ещё более высокого уровня, и так, пока мы не дойдём до глобального. Разумеется, это делается на этапе компиляции и никак не влияет на производительность программы. Теперь на счёт вашего вопроса. Если вы хотите, чтобы объект существовал после выхода из пространства имён, в котором он создан, создавайте его динамически (new (C++) или malloc (C), или аналогичные). То есть на этапе выполнения программы, память выделяется из кучи (heap). Если он вам нужен только внутри этого пространства имён, и не требуется после него, создавайте его как обычно. Вот пример:
1) Всегда удаляйте динамически выделенную память сами, за вас это никто не сделает. Иначе будут утечки памяти. Вспомните патч к вашей любимой игрушке, где сказано "увеличена производительность за счёт исправления множественных утечек памяти", после которого игрушка стала жрать на 300 метров оперативки меньше. Вот это оно. 2) Если вы случайно удалите указатель (например, при выходе из его пространства имён), вы потеряете буфер. Вы уже никогда не узнаете, в каком участке памяти лежит ваша драгоценная информация. Ну и, опять же, сделаете утечку памяти. 3) Если память не выделена, предназначенный для неё указатель ВСЕГДА должен быть равен нулю. Во-первых, так вы всегда сможете сказать, выделили ли вы память под что-то или нет. Во-вторых, в случае ошибки, операционка отстрелит вашу программу (Инструкция по адресу "0x0022ff77" обратилась к памяти по адресу "0x00000000". Память не может быть read. Ну или written. Помните? ). Подобная ошибка происходит, когда вы пытаетесь обратиться к участку памяти, не доступному вашей программе. Если в указателе будет адрес, который доступен вашей программе, вы можете затереть свою собственную память. Нулевой адрес никогда вам доступен не будет.
4
|
|||||||||||
|
9 / 9 / 4
Регистрация: 04.03.2010
Сообщений: 40
|
|
| 12.03.2011, 13:24 | |
|
talis, большое спасибо за разъяснение. Очень понятно объясняешь
С пространством имен был знаком до этого, но возможность использования фигурных скобок для создания нового пространства имен, для меня новость. За это отдельное спасибо ![]() Не понятно только, почему в книжках не говорят про эту особенность указателей.Про замечания очень интересно, также как и интересно все, чего не знал раньше ![]() С++ мне с каждым днем все больше нравится, особенно в сравнении с Delphi. P.S.: думаю тема скоро перерастет из "Понять указатели" в "Понять С++"
0
|
|
|
137 / 137 / 25
Регистрация: 30.09.2010
Сообщений: 333
|
||
| 12.03.2011, 21:57 | ||
0
|
||
|
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
| 12.03.2011, 21:59 | |
|
Temirlan90, типа система не будет знать, что память приложению уже не нужна и что её теперь можно отдать под более актуальные нужды.
1
|
|
|
137 / 137 / 25
Регистрация: 30.09.2010
Сообщений: 333
|
|
| 12.03.2011, 22:04 | |
|
И еще вопрос, в Java и C# это вроде делается на автомате? Я про удаления динамической памяти.
Добавлено через 2 минуты silent_1991, и в Вашем примере вы показали, что в функцию копируются лишние данные?
0
|
|
|
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
| 12.03.2011, 22:08 | |
|
Вряд-ли вы имеете ввиду мой пример, примеры в основном тут показывал tails.
И да, в Яве и шарпе мусор собирается автоматически.
0
|
|
|
137 / 137 / 25
Регистрация: 30.09.2010
Сообщений: 333
|
||
| 12.03.2011, 22:13 | ||
|
silent_1991, Я про Real_swap и Image_swap это ведь ваш пример =) В этом исходнике как Я понял, там копируются не нужные данные в функции Image_swap?
0
|
||
|
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
||
| 12.03.2011, 22:16 | ||
|
Нет, там вообще никакой речи об утечке памяти нету. Там просто было показано, как могут быть использованы указатели.
Добавлено через 2 минуты
1
|
||
|
137 / 137 / 25
Регистрация: 30.09.2010
Сообщений: 333
|
||
| 12.03.2011, 22:18 | ||
0
|
||
|
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
| 12.03.2011, 22:21 | |
|
С чего вы взяли? Что в этой функции, что в real_swap, создаются три переменные, только в данном случае это переменные типа int (a, b, temp), а в случае real_swap - два указателя на int и одна int (тоже a, b (указатели) и temp).
0
|
|
| 12.03.2011, 22:21 | |
|
Помогаю со студенческими работами здесь
40
Не могу понять, как "живут" файловые указатели Указатели и указатели на указатели, а также типы данных Через указатели на указатели посчитать сумму двух чисел и записать в третье Почему Лафоре использует указатели на указатели, вместо обмена значениями указателей? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2.
Задача: реализовать контроль корректности заполнения дат назначения. . .
|
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html
Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
|
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2.
Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
|
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях.
Задача: при копировании документа очищать определенные реквизиты и табличную. . .
|
|
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git
main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели
8ATzM_2aurI
|
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2.
Задача: запретить редактирование документа, если он открыт у другого пользователя.
/ / . . .
|
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои.
А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
|
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20%
kYBz3eJf3jQ
|