4868

Указатели. Адресная арифметика. Ссылки

Лекция

Информатика, кибернетика и программирование

Указатели. Адресная арифметика. Ссылки. Указатели – особый тип данных. Указатель хранит адрес, по которому в памяти располагается некоторый объект (переменная, массив, функция). Можно упрощенно представить память компьютера в виде массива после...

Русский

2012-11-28

41 KB

8 чел.

Указатели. Адресная арифметика. Ссылки.

Указатели – особый тип данных. Указатель хранит адрес, по которому в памяти располагается некоторый объект (переменная, массив, функция). Можно упрощенно представить память компьютера в виде массива последовательно пронумерованных (адресованных) ячеек (байт). Любой переменной соответствует определенный участок памяти, представляющий собой непрерывную «цепочку» байт необходимого размера. Размер зависит от типа переменной. Например, переменная типа char всегда занимает ровно 1 байт, а переменная типа int может занимать 2 и больше байта (в зависимости от архитектуры компьютера и используемого компилятора). Соответственно, зная адрес начала участка памяти, выделенного для некоторой переменной, а также её тип, можно обеспечить чтение и запись этой переменной косвенным образом, через её адрес. Возможность такой косвенной работы с переменными (а также с массивами и функциями) осуществляется с помощью указателей.

Объявления указателя на переменную выглядит так:

 тип_переменной * имя_указателя;

Адрес переменной можно получить с помощью оператора &, в следующем примере указатель p инициализируется адресом переменной i:

int i = 10; 

int * p = & i;

Указателю любого типа можно присвоить значение 0, что означает, что указатель не адресует никакой переменной.

Косвенное обращение к переменной, адрес которой хранит указатель, осуществляется с помощью оператора разыменовывания (dereferencing) *, в приведенном ниже примере значение переменной d изменяется косвенным образом через указатель pd:

double d = 10;

 double * pd = & d;

*pd = 20;

std::cout << "d: " << d << std::endl;

Попытка косвенного обращения через указатель, имеющий нулевое значение, приведет к ошибке времени выполнения (run-time).

Указатели одного типа можно присваивать друг другу, при этом оба указателя будут ссылаться на один и тот же объект:

 

 float f = 1.0;

 float * pf1 = & f; // pf1 хранит адрес переменной f

 float * pf2 = pf1; // pf2 тоже хранит адрес переменной f

* pf2 = 2.0;       // теперь f == 2.0

 float g = * pf1;   // теперь g == f (2.0)

Указатель не может адресовать объект другого типа. Такие операции запрещены, потому что интерпретация компилятором объектов, адресуемых указателем, зависит от типа указателя:

 

 int i = 10;

   float * pf = & i; // ошибка

Иногда возникают ситуации, когда нужно только само значение адреса, а не объект, на который он указывает (например, нужно сравнить адрес с каким-то другим). Для этого существует специальный указатель void, который может адресовать любой тип данных. Однако, поскольку тип объекта, адресуемого таким указателем, неизвестен, никакие манипуляции с объектом через этот указатель не допустимы. Все, что можно сделать – присвоить его значение другому указателю или сравнить его с какой-либо адресной величиной.

  int i = 10;

  float f = 5.0;

  void * pv = & i; // допустимо

  pv = & f; // допустимо

  *p v = 1; // ошибка!

Применение оператора взятия адреса & к объекту типа int возвращает результат типа int*. Если ту же операцию применить к объекту типа int * (указатель на int), получим указатель на указатель на int, т.е. int**. int** – это адрес переменной, которая содержит адрес переменной типа int. В следующем примере, разыменовав ppi, мы получим переменную типа int*, содержащую адрес переменной i. Чтобы получить значение переменной i, операцию разыменовывания к ppi надо применить дважды:

 

      int i = 10;

  int * pi1 = & i; // pi1 получает адрес i

  int ** ppi = & pi1; // ppi получает адрес pi1

  int * pi2 = * ppi;  // pi2 получает значение pi1 косвенно,

                      // через указатель ppi. Фактически,

                      // теперь pi2 тоже содержит адрес i

  

  int j = **ppi; // j получает значение i косвенно,

                 // используя двойную адресацию

Адресная арифметика.

 Указатели могут быть использованы в арифметических выражениях. К указателю можно прибавлять или вычитать целое значение. Прибавление к указателю 1 увеличивает хранящееся в нем значение адреса на размер области памяти, используемый переменной соответствующего типа. Это позволяет использовать указатели при работе с массивами: поскольку в массивах все элементы располагаются в памяти последовательно, прибавление к указателю 1 означает «перевод» его на следующий элемент массива:

      int A[10];

  int * it = & A[0]; // Указатель на начало массива

  int * end = & A[10]; // Указатель на конец массива,

                       // фактически, это адрес участка памяти,

                       // расположенного сразу после последнего

                       // элемента массива

  while ( it != end ) // пока не дошли до конца массива

  {

     *it = rand(); // записываем в текущий элемент случайное число

     ++it; // увеличиваем указатель на 1,

           // т.е. переходим к следующему элементу массива

  }

 Ссылки.

Ссылочный тип служит для задания переменной дополнительного имени (синонима). Ссылка позволяет косвенно манипулировать переменной, аналогично указателю. Чаще всего ссылки используются в качестве формальных параметров функций. Ссылочный тип описывается указанием оператора взятия адреса & перед именем переменной. Ссылка обязательно должна быть инициализирована. Определив ссылку, невозможно изменить её так, чтобы работать с другим объектом.

  int i = 10 , j = 5;

  int & ri = i; // ri - синоним переменной i

  int & ri2; // Ошибка - ссылка не инициализирована

Все операции со ссылкой относятся к адресуемой ей переменной, в том числе присваивание и взятие адреса:

  ri = j; // i получает значение j через ссылку ri

  ri++; // i увеличивается на 1 через ссылку ri

     int * pi = & ri; // указатель pi получает значение

                   // адреса i через ссылку ri


 

А также другие работы, которые могут Вас заинтересовать

22388. Сжатые и растянутые элементы. Конструктивные особенности. Расчет прочности центрально И Внецентренно растянутых элементов. Расчет внецентренно сжатых элементов таврового и двутаврового сечений 1.23 MB
  Расчет прочности центрально И Внецентренно растянутых элементов. Расчет внецентренно сжатых элементов таврового и двутаврового сечений. НАПРЯЖЕННОЕ СОСТОЯНИЕ РАСТЯНУТЫХ И СЖАТЫХ ЖЕЛЕЗОБЕТОННЫХ ЭЛЕМЕНТОВ Сжатые элементы. Конструктивные особенности сжатых элементов К центральносжатым элементам условно относят: промежуточные колонны в зданиях и сооружениях; верхние пояса ферм загруженных по узлам; восходящие раскосы и стойки ферменной решетки.
22389. ТРЕЩИНОСТОЙКОСТЬ И ПЕРЕМЕЩЕНИЯ ЖЕЛЕЗОБЕТОННЫХ ЭЛЕМЕНТОВ. СОПРОТИВЛЕНИЕ ОБРАЗОВАНИЮ ТРЕЩИН ЦЕНТРАЛЬНО РАСТЯНУТЫХ, ИЗГИБАЕМЫХ, ВНЕЦЕНТРЕННО СЖАТЫХ И РАСТЯНУТЫХ ЭЛЕМЕНТОВ. ТРЕЩИНОСТОЙКОСТЬ И ПЕРЕМЕЩЕНИЯ ЖЕЛЕЗОБЕТОННЫХ ЭЛЕМЕНТОВ 101.52 KB
  ТРЕЩИНОСТОЙКОСТЬ И ПЕРЕМЕЩЕНИЯ ЖЕЛЕЗОБЕТОННЫХ ЭЛЕМЕНТОВ. СОПРОТИВЛЕНИЕ ОБРАЗОВАНИЮ ТРЕЩИН ЦЕНТРАЛЬНО РАСТЯНУТЫХ ИЗГИБАЕМЫХ ВНЕЦЕНТРЕННО СЖАТЫХ И РАСТЯНУТЫХ ЭЛЕМЕНТОВ. ТРЕЩИНОСТОЙКОСТЬ И ПЕРЕМЕЩЕНИЯ ЖЕЛЕЗОБЕТОННЫХ ЭЛЕМЕНТОВ. Общие положения Трещиностойкость элементов как условлено ранее это сопротивление образованию трещин в стадии I или сопротивление раскрытию трещин в стадии II.
22390. РАСЧЕТ ПО ОБРАЗОВАНИЮ ТРЕЩИН, НОРМАЛЬНЫХ И НАКЛОННЫХ К ПРОДОЛЬНОЙ ОСИ ЭЛЕМЕНТА. СОПРОТИВЛЕНИЕ РАСКРЫТИЮ ТРЕЩИН. ОПРЕДЕЛЕНИЕ РАССТОЯНИЯ МЕЖДУ ТРЕЩИНАМИ 235.22 KB
  РАСЧЕТ ПО ОБРАЗОВАНИЮ ТРЕЩИН НОРМАЛЬНЫХ И НАКЛОННЫХ К ПРОДОЛЬНОЙ ОСИ ЭЛЕМЕНТА. СОПРОТИВЛЕНИЕ РАСКРЫТИЮ ТРЕЩИН. ОПРЕДЕЛЕНИЕ РАССТОЯНИЯ МЕЖДУ ТРЕЩИНАМИ. Расчет по образованию трещин нормальных к продольной оси элемента Этот расчет заключается в проверке условия что трещины в сечениях нормальных к продольной оси элемента не образуются если момент внешних сил М не превосходит момента внутренних усилий в сечении перед образованием трещин Мcrcт.
22391. КРИВИЗНА ОСИ ПРИ ИЗГИБЕ, ЖЕСТКОСТЬ И ПЕРЕМЕЩЕНИЯ ЖЕЛЕЗОБЕТОННЫХ ЭЛЕМЕНТОВ. ОБЩИЕ ПОЛОЖЕНИЯ РАСЧЕТА 161.5 KB
  КРИВИЗНА ОСИ ПРИ ИЗГИБЕ ЖЕСТКОСТЬ И ПЕРЕМЕЩЕНИЯ ЖЕЛЕЗОБЕТОННЫХ ЭЛЕМЕНТОВ. ОБЩИЕ ПОЛОЖЕНИЯ РАСЧЕТА Расчет перемещений железобетонных элементов прогибов и углов поворота связан с определением кривизны оси при изгибе или с определением жесткости элементов. Считается что элементы или участки элементов не имеют трещин в растянутой зоне если при действии постоянных длительных и кратковременных нагрузок с коэффициентом надежности по нагрузке γf= 1 трещины не образуются. Кривизна оси при изгибе и жесткость железобетонных элементов на участках...
22392. БЕТОН. СТРУКТУРА БЕТОНА. ПРОЧНОСТЬ И ДЕФОРМАТИВНОСТЬ. КЛАССЫ И МАРКИ БЕТОНА. АРМАТУРА. НАЗНАЧЕНИЕ И КЛАССИФИКАЦИЯ. МЕХАНИЧЕСКИЕ СВОЙСТВА. АРМАТУРНЫЕ СВАРНЫЕ ИЗДЕЛИЯ 130.03 KB
  СТРУКТУРА БЕТОНА. КЛАССЫ И МАРКИ БЕТОНА. В связи с этим в бетоне со временем прочность нарастает несколько изменяется объем в зависимости от соотношения состава бетона и химического состава цемента происходит усадка или при использовании специальных цементов расширение. По этим полостям и частично капиллярам возможно перемещение влаги и газа в толще бетона.
22393. ЖЕЛЕЗОБЕТОН. ОСОБЕННОСТИ ЗАВОДСКОГО ПРОИЗВОДСТВА. ПРЕДВАРИТЕЛЬНО-НАПРЯЖЕННЫЙ ЖЕЛЕЗОБЕТОН. АНКЕРОВКА АРМАТУРЫ В БЕТОНЕ. СЦЕПЛЕНИЕ АРМАТУРЫ С БЕТОНОМ. УСАДКА И ПОЛЗУЧЕСТЬ ЖЕЛЕЗОБЕТОНА 435.32 KB
  УСАДКА И ПОЛЗУЧЕСТЬ ЖЕЛЕЗОБЕТОНА. СПЕЦИАЛЬНЫЕ ВИДЫ ЖЕЛЕЗОБЕТОНА. Железобетон состоит из бетона и стальной арматуры. В изгибаемых элементах высокое сопротивление бетона сжатию используется в сжатой зоне а высокое сопротивление арматуры растяжению в растянутой зоне где бетон слабо сопротивляется растяжению и в нем образуются трещины рисунок 2.
22394. КЛАССИФИКАЦИЯ ЗДАНИЙ И СООРУЖЕНИЙ. КОНСТРУКТИВНЫЕ ЭЛЕМЕНТЫ НАДЗЕМНОЙ ЧАСТИ ПРОМЫШЛЕННЫХ ЗДАНИЙ 213.84 KB
  Различные строительные объекты здания и сооружения в зависимости от их назначения можно подразделить на четыре основные группы: жилые и общественные здания которые объединяются общим названием гражданские здания; к общественным зданиям относятся общежития клубы больницы школы.различные административные здания учебные театральнозрелищные торговые здания и т.; промышленные здания здания фабрик заводов и других производственных помещений здания гаражей электростанций котельных и т. сельскохозяйственные здания здания...
22395. Системный (структурный) уровень компьютерного проектирования сложных объектов 230 KB
  Системный подход к задаче автоматизированного проектирования технологического процесса; 2. Системный анализ сложных процессов 3 Этапы проектирования сложных систем 1. Системный подход к задаче автоматизированного проектирования технологического процесса Системный подход к задачам автоматизированного проектирования требует реализации совместного проектирования технологического процесса ТП и автоматизированной системы управления этим процессом АСУТП.
22396. Системный уровень компьютерного проектирования сложных объектов 110.5 KB
  Системный подход направление методологии научного познания и социальной практики в основе которого лежит рассмотрение объектов как системы; ориентирует исследователя на раскрытие целостности объекта на выявление многообразных типов связей в нем и сведения их в единую теоретическую картину. Основная процедура – построение обобщающей модели отражающие взаимосвязи реальной ситуации; техническая основа системного анализа – ЭВМ и информационные системы. Основной общий принцип системного подхода заключается в рассмотрении частей явления или...