Реклама
Вне зависимости от того, понимаете вы это или нет, подавляющее большинство программ, которые вы использовали, так или иначе используют указатели. Может быть, вы испытали Исключение нулевого указателя в какой-то момент. Как программист, написанный вами код, скорее всего, будет использовать указатели, даже если вы сами их не реализовали.
Сегодня я покажу вам, как работают указатели, так что вы можете проверить как работают массивы и списки Как работают массивы и списки в PythonМассивы и списки являются одними из наиболее полезных структур данных в программировании, хотя лишь немногие используют их в полной мере. Читать далее для начинающих программирования. Эта статья будет более теоретической, чем обычно, но придерживайтесь ее, указатели очень сложны!
Код компиляции
Прежде чем копаться в указателях, вы должны понять, как код создается и выполняется - возможно, вы уже знаете это. В этом разделе будут довольно общие утверждения - вещи, которые относятся к большинство языков, но не обязательно всех из них.

Давайте вернемся к началу. Каждый компьютер использует бинарный Что такое бинарный? [Технология объяснила]Учитывая, что двоичный файл является настолько фундаментальным для существования компьютеров, кажется странным, что мы никогда раньше не занимались этой темой - поэтому сегодня я подумал, что дам краткий обзор того, что двоичный файл ... Читать далее ряд единиц и нулей, которые составляют современную технологию, как мы ее знаем. Кодировать что-либо в двоичном формате чрезвычайно сложно (файлы могут быть очень запутанными), так как это необработанные инструкции, необходимые центральное процессорное устройство или Процессор для работы Что такое процессор и что он делает?Вычислительные сокращения сбивают с толку. Что такое процессор в любом случае? И нужен ли мне четырехъядерный или двухъядерный процессор? Как насчет AMD или Intel? Мы здесь, чтобы помочь объяснить разницу! Читать далее . Это известно как Машинный код.
Следующий шаг от машинного кода сборочный. Это несколько удобочитаемый формат. Хотя все еще сложно программировать, это возможно. Сборка состоит из серии простых команд для выполнения задач и называется низкий уровень язык программирования. Можно писать сложные программы, но трудно выразить абстрактные понятия и требует большого внимания.
Многие видеоигры и высокопроизводительные приложения имеют некоторую логику, написанную на ассемблере, поскольку некоторые реальные увеличения скорости можно найти, если вы знаете, что делаете. Однако для подавляющего большинства программных проектов вам вообще не нужно знать какую-либо сборку.

Итак, если машинный код слишком сложен для написания, а сборка слишком сложна для программирования, с чем вы пишете код? Вот где высокий уровень языки входят. Языки высокого уровня облегчают написание программ. Вы можете программировать что-то, что напоминает ваш родной язык, и это легко выразить сложные алгоритмы. Возможно, вы слышали о многих языках высокого уровня (и вы наверняка использовали программу, написанную на них):
- Бейсик
- C ++
- шепелявость
Эти языки очень старые, и многие из них были разработаны в начале 1950-х! Почти каждый современный язык программирования является языком высокого уровня, включая PHP и Python. Каждый день изобретается все больше языков (хотя их, вероятно, достаточно), но как именно ваш код по-прежнему работает должным образом, если компьютеры требуют машинного кода?
Здесь начинается компиляция. Компилятор - это программа, которая преобразует ваш код высокого уровня в форму, которая может быть выполнена. Это может быть другой язык высокого уровня, но обычно это ассемблер. Некоторые языки (например, Python или Java) преобразуют ваш код в промежуточный этап, называемый байткодом. Это потребует повторной компиляции позднее, что обычно делается по требованию, например, при запуске программы. Это известно как вовремя сборник, и он довольно популярен.
Управление памятью
Теперь, когда вы знаете, как работают языки программирования, давайте рассмотрим управление памятью на языках высокого уровня. В этих примерах я буду использовать псевдокод - код написан не на каком-либо конкретном языке, но используется для отображения концепций, а не точного синтаксиса. Сегодня это будет в основном напоминать C ++, поскольку это лучший язык высокого уровня (на мой взгляд).
Для этого раздела будет полезно, если у вас есть понимание как работает RAM Краткое и грязное руководство по оперативной памяти: что нужно знатьОперативная память является ключевым компонентом каждого компьютера, но это может сбивать с толку. Мы разберем это в простых для понимания терминах, которые вы поймете. Читать далее .
У большинства языков есть переменные - контейнеры, в которых хранятся некоторые данные. Вы должны явно определить тип данных. Некоторые динамически типизированные языки, такие как Python или PHP, обрабатывают это для вас, но они все еще должны это делать.
Скажем, у вас есть переменная:
int myNumber;
Этот код объявляет переменную мой номери дает ему тип данных целое число. После компиляции компьютер интерпретирует эту команду как:
«Найдите пустую память и зарезервируйте место, достаточно большое для хранения целого числа»
После выполнения этой команды этот бит памяти не может использоваться другой программой. Он еще не содержит никаких данных, но зарезервирован для вашей переменной myNumber.
Теперь присвойте значение вашей переменной:
myNumber = 10;
Для выполнения этой задачи ваш компьютер обращается к зарезервированной ячейке памяти и изменяет любое сохраненное там значение на это новое значение.
Теперь, это все хорошо, но как места памяти становятся незарезервированными? Если бы программы зарезервировали всю память, которая им нравится, ОЗУ немедленно заполнилось бы - это сделало бы очень медленная система.

Чтобы избежать этой потенциальной проблемы, многие языки реализуют уборщик мусора, используемый для уничтожения переменных (и, следовательно, освобождения зарезервированных областей памяти), которые прошли выходит за рамки.
Вам может быть интересно, что такое сфера и почему это так важно. Область действия определяет пределы и продолжительность жизни переменных или любой памяти, используемой программой. Переменная находится вне области видимости, когда к ней больше не может получить доступ какой-либо код (то есть, когда вступает сборщик мусора). Вот пример:
function maths () {int firstNumber = 1; } int secondNumber = 2; печать (firstNumber + secondNumber); // не будет работать
Этот пример не скомпилируется. Переменная firstNumber находится в пределах математика функция, так что это его сфера. К нему нельзя получить доступ извне функции, в которой он был объявлен. Это важная концепция программированияи понимание этого крайне важно для работы с указателями.
Этот способ обработки памяти называется стек. Так работает подавляющее большинство программ. Вам не нужно понимать указатели, чтобы использовать его, и он довольно хорошо структурирован. Недостатком стека является скорость. Поскольку компьютеру приходится выделять память, отслеживать переменные и запускать сборку мусора, возникают небольшие накладные расходы. Это хорошо для небольших программ, но как насчет высокопроизводительных задач или приложений с большими объемами данных?
Введите: указатели.
указатели
На первый взгляд, указатели звучат просто. Они ссылаются (указать на) место в памяти. Может показаться, что это не отличается от «обычных» переменных в стеке, но, поверьте мне, есть огромная разница. Указатели хранятся на куча. Это противоположность стека - он менее организован, но намного быстрее.
Давайте посмотрим, как переменные назначаются в стеке:
int numberOne = 1; int numberTwo = numberOne;
Это простой синтаксис; Переменная номер два содержит номер один Это значение копируется во время назначения из номер один переменная.
Если вы хотите получить адрес памяти переменной вместо значения необходимо использовать знак амперсанда (&). Это называется адрес оператор, и является неотъемлемой частью вашего инструментария указателя.
int numberOne = 1; int numberTwo = & numberOne;
Сейчас номер два переменная точки в ячейку памяти, а не копировать номер один в свою новую, новую ячейку памяти. Если бы вы вывели эту переменную, она не была бы номером один (даже если она хранится в ячейке памяти). Это вывело бы место в памяти (вероятно, что-то вроде 2167, хотя это зависит от системы и доступной оперативной памяти). Чтобы получить доступ к значению, хранящемуся в указателе, вместо места в памяти, вы должны разыменовать указатель Это напрямую обращается к значению, которое в данном случае будет номером один. Вот как вы разыменовываете указатель:
int numberTwo = * numberOne;
оператор разыменования это звездочка (*).
Это может быть трудной для понимания концепции, поэтому давайте рассмотрим ее еще раз:
- адрес Оператор (&) сохраняет адрес памяти.
- оператор разыменования (*) получает доступ к значению.
Синтаксис немного меняется при объявлении указателей:
int * myPointer;
Тип данных ИНТ здесь относится к типу данных указатель точки а не тип самого указателя.
Теперь, когда вы знаете, что такое указатели, вы можете делать с ними действительно аккуратные трюки! Когда используется память, ваша операционная система запускается последовательно. Вы можете думать о RAM как о голубиных дырах. Много отверстий для хранения чего-либо, только одна может быть использована одновременно. Разница здесь в том, что эти отверстия для голубей пронумерованы. При выделении памяти ваша операционная система запускается с наименьшего числа и работает. Он никогда не будет прыгать между случайными числами.

При работе с указателями, если вы присвоили массив, вы можете легко перейти к следующему элементу, просто увеличив указатель.
Вот где это становится интересным. Когда вы передаете значения в функцию (используя переменные, хранящиеся в стеке), эти значения копируются в вашу функцию. Если это большие переменные, ваша программа теперь сохраняет их дважды. Когда ваша функция завершена, вам может понадобиться способ вернуть эти значения. Обычно функции могут возвращать только одну вещь - что если вы хотите вернуть две, три или четыре вещи?

Если вы передаете указатель на вашу функцию, копируется только адрес памяти (который крошечный). Это экономит ваш процессор много работы! Возможно, ваш указатель указывает на огромный массив изображений - не только ваша функция может работать точно так же данные хранятся в том же месте памяти, но как только это будет сделано, нет необходимости возвращать что-нибудь. Ухоженная!
Вы должны быть очень осторожны, хотя. Указатели все еще могут выходить за рамки видимости и собираться сборщиком мусора. Однако значения, хранящиеся в памяти, не собираются. Это называется утечкой памяти. Вы больше не можете получить доступ к данным (так как указатели были уничтожены), но они все еще используют память. Это общая причина сбоя многих программ, и она может неожиданно провалиться, если имеется большой объем данных. В большинстве случаев ваша операционная система убивает вашу программу, если у вас большая утечка (при использовании большего объема ОЗУ, чем у системы), но это нежелательно.

Указатели отладки могут быть кошмаром, особенно если вы работаете с большими объемами данных или работаете в циклах. Их недостатки и сложность для понимания действительно стоят того компромисса, который вы получаете от производительности. Хотя помните, они не всегда могут быть необходимы.
Вот и все на сегодня. Я надеюсь, что вы узнали что-то полезное о сложной теме. Конечно, мы не охватили все, что нужно знать - это очень сложная тема. Если вы заинтересованы в получении дополнительной информации, я настоятельно рекомендую С ++ за 24 часа.
Если это было немного сложно, взгляните на наш путеводитель по самым простым языкам программирования 6 самых простых языков программирования для начинающихОбучение программированию - это поиск правильного языка так же, как и процесс назидания. Вот шесть самых простых языков программирования для начинающих. Читать далее .
Вы узнали, как работают указатели сегодня? Есть ли у вас какие-либо советы и приемы, которыми вы хотите поделиться с другими программистами? Перейти в комментарии и поделиться своими мыслями ниже!
Джо - выпускник факультета компьютерных наук Университета Линкольна, Великобритания. Он профессиональный разработчик программного обеспечения, и когда он не летает на дронах и не пишет музыку, его часто можно встретить, фотографируя или снимая видео.