Ну, я в основном понимаю, как использовать указатели, но не то, как лучше всего их использовать для лучшего программирования.
Какие хорошие проекты или проблемы нужно решить, используя указатели, чтобы я мог лучше их понять?
learning
c++
personal-projects
pointers
dysoco
источник
источник
Ответы:
Манипулирование большими объемами данных в памяти - вот где действительно светятся указатели.
Передача большого объекта по ссылке равносильна передаче простого старого числа. Вы можете напрямую манипулировать необходимыми деталями, а не копировать объект, изменять его, а затем возвращать копию, которая будет помещена на место оригинала.
источник
Концепция указателя позволяет ссылаться на данные по адресу без дублирования хранилища данных. Этот подход позволяет писать эффективные алгоритмы, такие как:
Сортировка
При перемещении данных в алгоритме сортировки вы можете перемещать указатель вместо самих данных - подумайте о сортировке миллионов строк в строке из 100 символов; Вы сохраняете много ненужных перемещений данных.
Связанные списки
Вы можете хранить следующее и / или предыдущее местоположение элемента, а не все данные, связанные с записью.
Передача параметров
В этом случае вы передаете адрес данных вместо самих данных. Опять же, подумайте об алгоритме сжатия имен, который работает на миллионах строк.
Эта концепция может быть расширена до структур данных, таких как реляционные базы данных, где указатель похож на внешний ключ . Некоторые языки не поощряют использование указателей, таких как C # и COBOL.
Примеры можно найти во многих местах, таких как:
Следующий пост может быть уместным в некотором роде:
источник
Я удивлен, что ни один другой ответ не упомянул это: указатели позволяют вам создавать несмежные и нелинейные структуры данных, в которых элемент может быть связан со многими другими сложными способами.
Связанные списки (одиночные, двойные и циклически связанные), деревья (красно-черные, AVL, три, двоичные, пространственное разбиение ...) и графы - все это примеры структур, которые могут быть построены наиболее естественно с точки зрения ссылок, а не просто значений. ,
источник
Один простой способ в полиморфизме. Полиморфизм работает только с указателями.
Кроме того, вы используете указатели в любое время, когда вам нужно динамическое распределение памяти. В Си это обычно происходит, когда вам нужно сохранить данные в массив, но вы не знаете размер во время компиляции. Затем вы вызываете malloc для выделения памяти и указатель для доступа к ней. Кроме того, знаете ли вы это или нет, когда вы используете массив, вы используете указатели.
является эквивалентом
Это знание позволяет вам делать действительно классные вещи, такие как копирование всего массива в одну строку:
В c ++ вы используете new для выделения памяти для объекта и сохранения его в указателе. Вы делаете это в любое время, когда вам нужно создать объект во время выполнения, а не во время компиляции (т. Е. Метод создает новый объект и сохраняет его в списке).
Чтобы лучше понять указатели:
Найдите несколько проектов, которые используют наследование.
Вот проект, на котором я порезался:
Считайте из файла две матрицы nxn, выполните с ними основные операции векторного пространства и распечатайте их результат на экране.
Для этого вы должны использовать динамические массивы и ссылаться на свои массивы по указателям, поскольку у вас будет два массива (многомерных динамических массива). После того, как вы закончите этот проект, у вас будет довольно хорошая идея, как использовать указатели.
источник
Чтобы по-настоящему понять, почему указатели важны, вам нужно понять разницу между распределением кучи и выделением стека.
Ниже приведен пример выделения стека:
Объекты, размещенные в стеке, существуют только на время выполнения текущей функции. Когда вызов
foo
выходит из области видимости, то и переменная тожеf
.Один из случаев, когда это становится проблемой, - это когда вам нужно вернуть что-то, кроме целочисленного типа, из функции (например, структуру Foo из примера выше).
Например, следующая функция может привести к так называемому «неопределенному поведению».
Если вы хотите вернуть что-то вроде
struct Foo *
функции, то вам действительно нужно выделить кучу:Функция
malloc
размещает объект в куче и возвращает указатель на этот объект. Обратите внимание, что термин «объект» используется здесь свободно, что означает «что-то», а не объект в смысле объектно-ориентированного программирования.Время жизни объектов, размещенных в куче, контролируется программистом. Память для этого объекта будет зарезервирована до тех пор, пока программист не освободит его, то есть, вызвав
free()
или пока программа не закроется.Изменить : я не заметил, что этот вопрос помечен как вопрос C ++. Операторы C ++
new
иnew[]
выполняют ту же функцию, что иmalloc
. Операторыdelete
иdelete[]
аналогичныfree
. Хотяnew
иdelete
должно использоваться исключительно для выделения и освобождения объектов C ++, использованиеmalloc
иfree
совершенно допустимо в коде C ++.источник
Напишите любой нетривиальный проект на C, и вам придется выяснить, как / когда использовать указатели. В C ++ вы будете в основном использовать объекты с поддержкой RAII, которые управляют указателями внутри, но в C необработанные указатели играют гораздо более важную роль. Что касается проекта, который вы должны сделать, это может быть что угодно:
Я рекомендую последний.
источник
Почти все проблемы программирования, которые могут быть решены с помощью указателей, могут быть решены с помощью других более безопасных типов ссылок (не относящихся к ссылкам на C ++ , но общая концепция CS о наличии переменной относится к значению данных, хранящихся в другом месте).
Указатели , являющиеся специфической низкоуровневой реализацией ссылок, где вы можете напрямую манипулировать адресами памяти, очень мощны, но могут быть немного опасны в использовании (например, указывают на области памяти вне программы).
Преимущество непосредственного использования указателей состоит в том, что они будут немного быстрее без необходимости выполнять какие-либо проверки безопасности. Такие языки, как Java, которые непосредственно не реализуют указатели в стиле C, будут испытывать незначительное снижение производительности, но уменьшат многие типы трудных для отладки ситуаций.
Что касается того, почему вам нужна косвенность, список довольно длинный, но, по сути, две ключевые идеи:
selected_object
которая является ссылкой на один из объектов, гораздо эффективнее, чем копирование значения текущего объекта в новую переменную.источник
Использование указателей на пиксельном уровне почти всегда проще и быстрее. Иногда это возможно только с помощью указателей.
источник
Указатели используются во многих языках программирования под поверхностью, без ошибок пользователя. C / C ++ просто дает вам доступ к ним.
Когда их использовать: как можно чаще, потому что копирование данных неэффективно. Когда их не использовать: когда вы хотите две копии, которые могут быть изменены по отдельности. (Что в итоге приведет к копированию содержимого object_1 в другое место в памяти и возвращению указателя - на этот раз указывая на object_2)
источник
Указатели являются неотъемлемой частью любой реализации структуры данных в C, а структуры данных - неотъемлемой частью любой нетривиальной программы.
Если вы хотите узнать, почему указатели так важны, я бы посоветовал узнать, что такое связанный список, и попытаться написать его, не используя указатели. Я не ставил перед вами невыполнимую задачу (СОВЕТ: указатели используются для ссылки на места в памяти, как вы ссылаетесь на вещи в массивах?).
источник
В качестве примера из реальной жизни, создание книги предельных заказов.
например, канал ITCH 4.1 имеет концепцию «заменяющих» заказов, где цены (и, следовательно, приоритет) могут изменяться. Вы хотите иметь возможность принимать заказы и перемещать их в другое место. Реализация двусторонней очереди с указателями делает операцию очень простой.
источник
Просматривая различные сайты StackExchange, я понимаю, что довольно модно задавать вопрос, подобный этому. На риск критики и отрицательных голосов, я буду честен. Это не для того, чтобы троллить или поджигать, я лишь хочу помочь, дав честную оценку вопроса.
И эта оценка такова: это очень странный вопрос для программиста на Си. Практически все, что говорит: «Я не знаю C.» Если я проанализирую немного дальше и более цинично, то получу продолжение этого «вопроса»: «Есть ли какой-нибудь способ, которым я могу воспользоваться, чтобы быстро и внезапно получить знания опытного программиста на C, не тратя время? для самостоятельного изучения? Любой «ответ», который кто-то может дать, не может заменить работу и понимание основной концепции и ее использования.
Я чувствую, что более конструктивно лучше изучать язык C из первых рук, чем заходить в Интернет и спрашивать людей об этом. Когда вы хорошо знаете C, вы не будете задавать подобные вопросы, это все равно что спрашивать: «Какие проблемы лучше всего решить с помощью зубной щетки?»
источник
Несмотря на то, что указатели действительно работают при работе с большими объектами памяти, все еще есть способ сделать то же самое без них.
Указатель абсолютно необходим для так называемого динамического программирования , это когда вы не знаете, сколько памяти вам понадобится для выполнения вашей программы. В динамическом программировании вы можете запрашивать фрагменты памяти во время выполнения и помещать в них свои собственные данные - поэтому вам нужны указатели или ссылки (здесь разница не важна), чтобы иметь возможность работать с этими фрагментами данных.
Пока вы можете требовать определенную память во время выполнения и помещать свои данные во вновь полученную память, вы можете делать следующее:
Вы можете иметь самораспространяющиеся структуры данных. Это структуры, которые могут расширяться, требуя дополнительной памяти, пока их емкость исчерпана. Ключевым свойством каждой самораспространяющейся структуры является то, что она состоит из небольших блоков памяти (называемых узлами, элементами списка и т. Д. В зависимости от структуры), и каждый блок содержит ссылки на другие блоки. Эти «связанные» структуры строят большинство современных типов данных: графики, деревья, списки и т. Д.
Вы можете программировать, используя парадигму ООП (объектно-ориентированного программирования). Вся ООП основана на использовании не прямых переменных, а ссылок на экземпляры классов (называемых объектами) и манипулирования ими. Ни один экземпляр не может существовать без указателей (даже если можно использовать статические классы, даже без указателей, это скорее исключение).
источник
Забавно, я только что ответил на вопрос о C ++ и поговорил об указателях.
Короче говоря, вы НИКОГДА не нуждаетесь в указателях, кроме случаев, когда: 1) библиотека, которую вы используете, заставляет вас 2) вам нужна ссылка на Nullable.
Если вам нужен массив, список, строка и т. Д., Просто поместите его в стек и используйте объект stl. Возврат или передача объектов stl выполняются быстро (факт не проверен), потому что они имеют внутренний код, который копирует указатель вместо объекта и будет копировать данные, только если вы пишете в него. Это обычный C ++, даже не новый C ++ 11, который облегчит работу с авторами библиотек.
Ваш вопрос может быть дан ответ в этой части
Если вы используете указатель, убедитесь, что он находится в одном из этих двух условий. 1) Вы передаете ввод, который может быть обнуляемым. Примером является необязательное имя файла. 2) Если вы хотите передать право собственности. Например, если вы передадите или вернете указатель, у вас не останется ЛЮБЫХ копий и не используйте указатель, который вы отдаете.
Но я не использовал указатели или умные указатели в течение очень долгого времени, и я профилировал свое приложение. Работает очень быстро.
ДОПОЛНИТЕЛЬНОЕ ПРИМЕЧАНИЕ: я замечаю, что пишу свои собственные структуры и раздаю их. Так как мне сделать это без использования указателей? Это не контейнер STL, поэтому передача по ссылке идет медленно. Я всегда загружаю свой список данных / deques / maps и тому подобное. Я не помню, чтобы возвращались какие-либо объекты, если это не был какой-то список / карта. Даже не строка. Я посмотрел на код для отдельных объектов, и я заметил, что я делаю что-то вроде этого,
{ MyStruct v; func(v, someinput); ... } void func(MyStruct&v, const D&someinput) { fillV; }
поэтому я в значительной степени возвращаю объекты (несколько) или предварительно распределяю / передаю ссылку для заполнения (один).Теперь, если вы писали свою собственную карту, карту и т. Д., Вам нужно использовать указатели. Но вам не нужно. Пусть STL и, возможно, повысить беспокойство об этом. Вам просто нужно написать данные и решения. Не контейнеры для их хранения;)
Я надеюсь, что вы теперь никогда не используете указатели: D. Удачи в общении с библиотекарями, которые заставляют вас
источник
Указатели очень полезны для работы с отображенными в память устройствами. Вы можете определить структуру, которая отражает (скажем) управляющий регистр, затем назначить ее адресу фактического управляющего регистра в памяти и напрямую управлять им. Вы также можете напрямую указать буфер передачи на карте или чипе, если MMU отобразил его в системной памяти.
источник
Я вижу указатели как указательный палец, который мы используем для нескольких вещей:
пожалуйста, прости этот плохой ответ
источник
Поскольку ваш вопрос помечен C ++, я отвечу на ваш вопрос для этого языка.
В C ++ существует различие между указателями и ссылками, поэтому существует два сценария, в которых указатели (или умные указатели) необходимы для облегчения определенного поведения. Они могут использоваться в других обстоятельствах, однако вы спрашиваете, как «лучше их использовать», и во всех других обстоятельствах есть лучшие альтернативы.
1. Полиморфизм
Указатель базового класса позволяет вам вызывать виртуальный метод, который зависит от типа объекта, на который указывает указатель.
2. Создание постоянных объектов
Указатели необходимы при динамическом создании объекта (в куче, а не в стеке). Это необходимо, когда вы хотите, чтобы время жизни объекта было больше, чем область, в которой он создан.
С точки зрения «хороших проектов или проблем, которые необходимо решить», как уже говорили другие, в любом нетривиальном проекте будут использоваться указатели.
источник