Что такое указатели в программировании — Журнал «Код» программирование без снобизма
В программировании есть понятие указателей — особенно часто о них можно услышать в языках вроде C. Указатели считаются сложной темой, и про тех, кто ими пользуются, ходят легенды. Но на самом деле в указателях нет ничего сложного. Сейчас разберём.
Что такое указатель
Когда мы заводим новую переменную, компьютер выделяет для неё место в оперативной памяти:
Количество этих ячеек зависит от типа данных, который хранится в этой переменной: обычно для целого числа выделяют 2 или 4 байта, для дробного — 8 байт, для строки — столько же, сколько и символов и ещё 1 служебный байт и так далее. Но сколько бы байтов ни выделил компьютер для хранения, он выделяет эти байты подряд, друг за другом, и запоминает два момента:
- Сколько байтов занимает переменная.
- По какому адресу в памяти находится первый байт этой переменной.
Если совсем упростить, то адрес в памяти — это порядковый номер ячейки, где хранится байт. Так вот, в указателях как раз хранятся адреса памяти, где начинаются разные переменные:
Зачем это нужно
Указатели нужны для того, чтобы можно было напрямую работать с оперативной памятью. Например, указатели позволяют экономить выделение памяти: когда в функцию вместо переменной передаётся указатель, компьютер не создаёт её локальную копию, а обращается к ней напрямую.
Второе применение указателей — динамическое управление памятью. Если нам нужно выделить в памяти некоторую область для хранения своих данных, но стандартные переменные нам не подходят, мы можем использовать указатель. В этом случае мы помещаем в него стартовый адрес ячейки и говорим, сколько байтов после него нужно использовать и что в них положить.
Что такое сборщик мусора в программировании
Почему указателями редко пользуются
Если в указатель положить адрес памяти, который выходит за границы, выделенные для этой программы, то мы можем повредить чужие данные. Некоторые языки, например, C++, не всегда перепроверяют то, что делает программист, поэтому там легко сломать не только свою программу, но и весь компьютер.
Дело в том, что компьютеру всё равно, что лежит по адресу, написанному в указателе — данные, переменная или что-то чужое. Всё, что он делает — это идёт по этому адресу и стирает либо записывает туда что-то своё, не задавая лишних вопросов. Это мощная штука, но чтобы ей пользоваться, нужно чётко знать внутреннюю архитектуру памяти и работы компилятора.
В каких языках есть указатели
Самые популярные языки с поддержкой указателей — это всё семейство Си-языков:
А всё потому, что в старые времена оперативной памяти было мало и нужно было использовать её как можно эффективнее. Поэтому иногда было нормально, когда одна и та же область памяти использовалась программистом для хранения разных данных.
Также полноценные указатели есть в некоторых современных языках высокого уровня: Java, Pascal и Go.
Текст:
Михаил Полянин
Редактор:
Максим Ильяхов
Художник:
Алексей Сухов
Корректор:
Ирина Михеева
Вёрстка:
Кирилл Климентьев
Соцсети:
Виталий Вебер
что такое указатель, и что он делает?
Добавлено 27 мая 2019 в 13:41
Данная статья поможет вам понять указатели, которые являются интересным и важным аспектом языка C.
С точки зрения инженера-электронщика, который пишет прошивки для встраиваемых систем, указатели не являются необходимым инструментом. Однако я собираюсь рассказать о них сейчас, а не позже в этой серии статей, потому что они тесно связаны с массивами, которые мы обсуждали в предыдущей статье. Кроме того, указатели помогают укрепить ваше понимание взаимосвязи между кодом и аппаратным обеспечением.
Я написал немало прошивок, и у меня осталось всего несколько случайных воспоминаний об использовании указателей. Однако я рад, что понимаю их, потому что, когда ситуация требует указателей, я бы предпочел использовать их, а не какое-то простое неэффективное решение по умолчанию.
Что такое указатель?
Указатель – это переменная. Как и другие переменные, он имеет тип данных и идентификатор. Однако указатели используются таким образом, которой принципиально отличается от того, как мы используем «нормальные» переменные, и при объявлении мы должны добавить звездочку, чтобы сообщить компилятору, что данная переменная должна рассматриваться как указатель.
char *RxByte_ptr; int *ADCValue_ptr;
Идентификатор не обязательно должен содержать символы, которые помечают переменную как указатель (такие как «ptr«). Тем не менее, я очень рекомендую использовать эту практику. Это поможет вам сохранить ваши мысли более организованными, и если у вас все указатели будут помечены таким образом, другим инженерам будет легче понять ваш код.
Что делает указатель?
Он указывает. Более конкретно, он указывает на данные другой переменной или на данные, которые хранятся в памяти, но не связаны с переменной.
Рисунок 1 – На что указывает указательОбычно мы думаем о переменной как о чем-то, что хранит данные, а под «данным» мы подразумеваем информацию, которая будет использоваться в вычислениях, или отправляться на другое устройство, или загружаться в регистр конфигурации, или использоваться для управления пикселями LCD дисплея. Указатель – это переменная, но она не используется для хранения такого типа данных. Вернее указатель хранит адрес памяти.
Возможно, именно в этот момент некоторые люди начинают немного путаться, и я думаю, что это происходит потому, что легко упустить из виду физическую реальность памяти процессора. Блок памяти представляет собой набор цифровых ячеек памяти, которые организованы в группы. В случае 8-разрядного процессора каждая группа ячеек памяти соответствует одному байту. Единственный способ отличить одну группу от другой – это адрес, а этот адрес – просто число. Указатель – это переменная, в которой хранится число, но это число интерпретируется как адрес, т.е. как значение, указывающее точное местоположение в памяти.
Подкрепим эту концепцию краткой аналогией. Представьте, что я стою в библиотеке, и кто-то подходит ко мне и говорит: «Кто такой Ричард Львиное Сердце?». Если я отвечаю, говоря: «Король Англии с 1189 по 1199 года», я похож на обычную переменную. Я предоставляю информацию, данные, которые хочет получить человек. И напротив, если я отвечаю, указывая на книгу под названием «Монархи средневековой Англии», я действую как указатель. Вместо того чтобы предоставлять нужные данные, я указываю, где именно эти данные можно найти. Я до сих пор храню полезную информацию, но эта информация – это не сам факт, а место, где человек может получить доступ к этому факту.
Понятие типов данных указателей
Как вы могли заметить в приведенных выше примерах, указатели объявляются с типом данных. Возможно, это усугубляет сложность понимания, что такое указатель. Если указатель – это просто число, соответствующее адресу ячейки памяти, то как могут использоваться разные типы данных? Например, если ваш микроконтроллер имеет 4 КБ RAM, как вы можете иметь указатель с типом данных char
? Максимальное значение unsigned char
составляет 255; что произойдет, если этот указатель должен указывать на переменную, расположенную по адресу памяти 3000?
Ключ к пониманию этой проблемы заключается в следующем: тип данных указателя не указывает, сколько байтов используется для хранения его значения. Скорее, число байтов, используемых для хранения значения указателя, соответствует количеству адресов памяти, к которым необходимо получать доступ, независимо от типа данных указателя. Кроме того, размер указателя определяется компилятором и непосредственно не виден программисту.
Рассмотрим следующую диаграмму:
Рисунок 3 – Представления в памяти переменной и указателя на эту переменнуюДопустим, мы используем жалкий микроконтроллер с оперативной памятью всего 11 байтов. Диапазон значений, предлагаемых 8-разрядным числом, составляет от 0 до 255, поэтому один байт памяти более чем достаточен для представления всех возможных областей памяти в этом устройстве.
Диаграмма подчеркивает тот факт, что даже переменная, объявленная как long
, может быть доступна через однобайтовый указатель. Синяя переменная – это указатель, который содержит адрес 32-битной переменной Seconds_Cnt
. Эта переменная использует четыре байта памяти, но адрес переменной (который в этом примере соответствует младшему значащему байту) всегда будет числом, равным или меньшим 0x0A
. Указатель должен быть объявлен с типом данных
long
, потому что он используется вместе с переменными long
, но сам указатель потребляет один байт памяти, а не четыре.
Продолжение следует…
Для такой темы, как указатели, одной статьи просто не хватает. Теперь вы знаете, что такое указатель, и основные возможности, которые он предоставляет в контексте программирования на C. В следующей статье мы сможем узнать, как они действуют, то есть, как на самом деле использовать указатели в ваших проектах встроенного программного обеспечения (прошивок).
Оригинал статьи:
- Robert Keim. Pointers in C Programming: What Is a Pointer and What Does It Do?
Теги
MCUВысокоуровневые языки программированияНазад
Оглавление
Вперед
Понимание указателей Golang.

При разработке на языке программирования Go понимание указателей является фундаментальной концепцией.
Фото AltumCode на UnsplashВ этой статье я объясню указатели Golang, как они работают и почему они необходимы в программировании на Go.
Проще говоря, указатель — это переменная, в которой хранится адрес памяти другой переменной. Указывает на расположение другого значения в памяти. Таким образом, он позволяет косвенно получать доступ к базовым данным и манипулировать ими.
В Go мы используем символ звездочки * для определения указателя. Синтаксис объявления указателя показан ниже:
var ptr *int
Здесь оператор объявляет переменную ptr
как указатель на целое число в памяти. Указатель может быть присвоен любому целочисленному значению, объявленному позже в программе.
Если у вас есть переменная, объявленная с начальным значением, вы можете объявить указатель и указать на значение с помощью оператора & (амперсанд). Фрагмент примера кода ниже демонстрирует концепцию:
package mainimport "fmt"
func main() {
number := 10 // переменнаяptr := &number // указатель ссылки на адрес памяти переменной number
fmt.Println(" Значение числа:", число)
fmt.Println("Адрес памяти числа:", &число)
fmt.Println("Значение указателя:", *ptr)
}
Вывод:
Значение числа: 10
Адрес памяти числа: 0x1050012f8
Значение указателя: 10
В приведенном выше коде мы объявили переменную с именем number, равную 10. Затем мы определили указатель с именем ptr
, чтобы указать на адрес памяти числа, используя и
перед имя переменной.
Мы напечатали начальное значение числа, адрес памяти числа и значение ptr
адреса памяти. Примечательно, что для получения значения того, на что указывает указатель, используйте оператор *
.
При запуске блок кода возвращает вывод, показанный выше. Как и ожидалось, переменная
число
имеет значение десять, и адрес памяти переменной отличается, но указатель отображает то же значение, что и число
при разыменовании, что означает, что значение указателя представляет значение памяти .
Указатели являются жизненно важными инструментами при работе с большими объемами данных или при передаче элементов между функциями в Go. Они позволяют косвенно ссылаться на часть данных, что упрощает манипулирование самими фактическими данными 9.0008 .
Более того, указатели значительно улучшают вашу способность работать с памятью и структурами данных, такими как массивы, связанные списки, карты и т. д., которые могут стать сложными без использования указателей.
Работа с указателями на первый взгляд может показаться сложной, но после освоения они становятся мощным инструментом программирования.
В Go они помогают уменьшить объем потребляемой памяти и упростить сложные манипуляции с кодом. Таким образом, хорошее понимание указателей в Go является важным шагом на пути к тому, чтобы стать опытным разработчиком Go.
Надеюсь, эта статья оказалась вам полезной!
Спасибо, что являетесь частью нашего сообщества! Прежде чем идти:
- 👏 Хлопайте в ладоши, чтобы узнать историю, и следите за автором 👉
- 📰 Смотрите больше контента в публикации Level Up Coding
- 💰 Бесплатный курс собеседования по программированию ⇒ Просмотреть курс
- 🔔 Следуйте за нами: Twitter | Линкедин | Информационный бюллетень
🚀👉 Присоединяйтесь к коллективу талантов Level Up и найдите прекрасную работу
Программирование на C: указатели и управление памятью
Доступна одна сессия:
25 607 уже зачислено!
Я хочу получать электронные письма от DartmouthX, IMTx и узнавать о других предложениях, связанных с программированием на C: указатели и управление памятью.
Об этом курсе
Что вы выучите
Преподаватели
Способы для прохождения этого курса
EDX для бизнеса
5 недель
2–4 часа в неделю
собственная скорость
Бесплатно
Доступно дополнительное обновление
Доступен один сеанс:
Я хотел бы получать электронные письма от DartmouthX, IMTx и узнавать о других предложениях, связанных с программированием на C: указатели и управление памятью.
Программирование на C: указатели и управление памятью
В этом курсе мы рассмотрим ключевую концепцию, лежащую в основе любого языка программирования: использование памяти.
Этот курс основывается на базовой концепции указателей, описанной в разделе Программирование на C: модульное программирование и управление памятью, и знакомит с более продвинутым использованием указателей и арифметикой указателей. Адресуются массивы указателей и многомерные массивы, и вы узнаете, как выделять память для ваших собственных данных во время выполнения программы. Это называется динамическим выделением памяти во время выполнения с использованием указателей.
Через несколько минут вы будете программировать в новом инструменте браузера, разработанном для этого курса, и получать мгновенную обратную связь о своем коде. Не нужно ничего устанавливать!
В этом курсе вы приобретете опыт работы с концепциями программирования, лежащими в основе любого языка программирования.