Содержит ссылку на объект программу или команду а также дополнительную информацию

Указатели и ссылки в C++

Указатели предназначены для хранения адресов областей памяти, а cсылка представляет собой синоним имени, указанного при инициализации ссылки. Далее подробно рассматриваются эти важные темы.

Указатели

Когда компилятор обрабатывает оператор определения переменной, например, int i=10;, он выделяет память в соответствии с типом (int) и инициализирует ее указанным значением (10). Все обращения в программе к переменной по ее имени (i) заменяются компилятором на адрес области памяти, в которой хранится значение переменной. Программист может определить собственные переменные для хранения адресов областей памяти. Такие переменные называются указателями.

Итак, указатели предназначены для хранения адресов областей памяти. В C++ различают три вида указателей:

  • указатели на объект,
  • указатели на функцию
  • указатели на void,

Они отличаются свойствами и набором допустимых операций. Указатель не является самостоятельным типом, он всегда связан с каким-либо другим конкретным типом.

Указатель на функцию

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

задает указатель с именем fun на функцию, возвращающую значение типа int и имеющую два аргумента типа double.

Указатель на объект

Указатель на объект содержит адрес области памяти, в которой хранятся данные определенного типа (основного или составного). Простейшее объявление указателя на объект (в дальнейшем называемого просто указателем) имеет вид:

где тип может быть любым, кроме ссылки и битового поля, причем тип может быть к этому моменту только объявлен, но еще не определен (следовательно, в структуре, например, может присутствовать указатель на структуру того же типа).

Звездочка относится непосредственно к имени, поэтому для того, чтобы объявить несколько указателей, требуется ставить ее перед именем каждого из них. Например, в операторе

описываются два указателя на целое с именами а и с, а также целая переменная b.

Размер указателя зависит от модели памяти. Можно определить указатель на указатель и т. д.

Указатель на void

Указатель на void применяется в тех случаях, когда конкретный тип объекта, адрес которого требуется хранить, не определен (например, если в одной и той же переменной в разные моменты времени требуется хранить адреса объектов различных типов).

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

Примеры объявления указателей

Указатель может быть константой или переменной, а также указывать на константу или переменную. Рассмотрим примеры:

int i; // целая переменная
const int ci = 1; // целая константа
int * pi; // указатель на целую переменную
const int * pci; // указатель на целую константу
int * const ср = // указатель-константа на целую переменную
const int * const срс = &ci; // указатель-константа на целую константу

Как видно из примеров, модификатор const, находящийся между именем указателя и звездочкой, относится к самому указателю и запрещает его изменение, а const слева от звездочки задает постоянство значения, на которое он указывает. Для инициализации указателей использована операция получения адреса // целая переменная
int* р = //в указатель записывается адрес а
int* р ( // то же самое другим способом

  • с помощью значения другого инициализированного указателя:
    int* r = р;
  • с помощью имени массива или функции, которые трактуются как адрес:
    int b[10]; // массив
    int* t = b; // присваивание адреса начала массива

    void f(int а ) %x

    на IBM РС-совместимом компьютере выведет на экран строку ():

    Значения указателей pint и pchar одинаковы, но разадресация pchar дает в результате один младший байт по этому адресу, а pint — два младших байта.

    В приведенном выше примере при инициализации указателей были использованы операции приведения типов. Синтаксис операции явного приведения типа прост: перед именем переменной в скобках указывается тип, к которому ее требуется преобразовать. При этом не гарантируется сохранение информации, поэтому в общем случае явных преобразований типа следует избегать.

    При смешивании в выражении указателей разных типов явное преобразование типов требуется для всех указателей, кроме void*. Указатель может неявно преобразовываться в значение тина booд (например, в выражении условного оператора), при этом ненулевой указатель преобразуется в true, а нулевой в false.

    Читайте также:
    Идеи для программ для школы

    Присваивание без явного приведения типов допускается в двух случаях:

    • указателям типа void*:
    • если тип указателей справа и слева от операции присваивания один и тот же.
    • Таким образом, неявное преобразование выполняется только к типу void*. Значение 0 неявно преобразуется к указателю на любой тип. Присваивание указателей на объекты указателям на функции (и наоборот) недопустимо. Запрещено и присваивать значения указателям-константам, впрочем, как и константам любого типа (присваивать значения указателям на константу и переменным, на которые ссылается указатель-константа, допускается).

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

      Инкремент перемещает указатель к следующему элементу массива, декремент — к предыдущему. Фактически значение указателя изменяется на величину sizeof (тип). Если указатель на определенный тип увеличивается или уменьшается на константу, его значение изменяется на величину этой константы, умноженную на размер объекта данного типа, например:

      short * р = new short [5];
      p++; // значение р увеличивается на 2
      long * q = new long [5];
      q++; // значение q увеличивается на 4

      Разность двух указателей — это разность их значений, деленная на размер типа в байтах (в применении к массивам разность указателей, например, на третий и шестой элементы равна 3). Суммирование двух указателей не допускается.

      При записи выражений с указателями следует обращать внимание на приоритеты операций. В качестве примера рассмотрим последовательность действий, заданную в операторе

      Операции разадресации и инкремента имеют одинаковый приоритет и выполняются справа налево, но, поскольку инкремент постфиксный, он выполняется после выполнения операции присваивания. Таким образом, сначала по адресу, записанному в указателе р, будет записано значение 10, а затем указатель будет увеличен на количество байт, соответствующее его типу. То же самое можно записать подробнее:

      Выражение (*р)++. напротив, инкрементирует значение, на которое ссылается указатель.

      Унарная операция получения адреса — оператор ссылки, означающий, что следующее за ним имя является именем переменной ссылочного типа, например:

      int коl;
      int // ссылка pal — альтернативное имя для коl
      const char // ссылка на константу

      Запомните следующие правила.

      • Переменная-ссылка должна явно инициализироваться при ее описании, кроме случаев, когда она является параметром функции, описана как extern или ссылается на поле данных класса.
      • После инициализации ссылке не может быть присвоена другая переменная.
      • Тип ссылки должен совпадать с типом величины, на которую она ссылается.
      • Не разрешается определять указатели на ссылки, создавать массивы ссылок и ссылки на ссылки.

      Ссылки применяются чаще всего в качестве параметров функций и типов возвращаемых функциями значений. Ссылки позволяют использовать в функциях переменные, передаваемые по адресу, без операции разадресации, что улучшает читаемость программы.

      Ссылка, в отличие от указателя, не занимает дополнительного пространства в памяти и является просто другим именем величины. Операция над ссылкой приводит к изменению величины, на которую она ссылается.

      По материалам книги Т.А. Павловской «CC++. Программирование на языке высокого уровня».

      Источник: itandlife.ru

      Обработчики событий при записи объектов. Зачем и что за чем?

      Распечатать

      Программисту, имеющего немного опыта на платформе 1С 8.2, бывает сложно разобраться: ПередЗаписью, ПриЗаписи, ПослеЗаписи, на сервере, на клиенте, в модуле формы, в модуле объекта, а-а-а-а-аааа.
      Именно такое сложное чувство непонимания было поначалу и у меня. В процессе обучения и реального опыта была создана эта шпаргалка, целью которой было «разложить всё по полочкам», чтобы было четкое понимание в каком случае какой обработчик нужно использовать и в какой последовательности они запускаются при записи объектов.

      Для чего нам вообще нужны эти обработчики?
      Очень часто программисту требуется переопределить стандартное поведение системы во время записи объектов, а именно: отменить запись, в случае каких-то условий; запросить дополнительную информацию у пользователя; дозаполнить реквизиты; что-то ещё записать в базу данных на основании этой записи; что-то изменить на форме после записи и т.д. и т.п. Каждый программист рано или поздно сталкивается с подобными задачами, потому знать назначение и последовательность запуска этих событий программисту, работающему на платформе 1С 8.2, необходимо.

      В модуле формы или в модуле объекта?
      Сначала надо определиться нужны ли нам данные формы? Будет ли запись записываться программным способом или только интерактивно? Будем ли вести диалог с пользователем?
      Дело в том, что часть событий выполняется на уровне модуля формы и это значит, что они выполняются только при интерактивной записи, а также в этих событиях мы можем обращаться к данным формы, вести диалог с пользователем.
      Другая часть событий выполняется на уровне модуля объекта, как при интерактивной, так и при программной записи.
      Потому можно сразу определиться с обработчиком модуля формы или модуля объекта будем работать.

      Модуль формы: на клиенте или на сервере?
      Далее, если выбран модуль формы, то надо определиться какой обработчик потребуется: исполняемый на клиенте, или исполняемый на сервере. Если потребуется диалог с пользователем, то на клиенте, в противном случае на сервере. Их можно отличить по имени директивы компиляции или по имени обработчика (когда на сервере, это пишется в имени, например ПередЗаписьюНаСервере()).

      Читайте также:
      Архивация файлов цель архивации виды программ архиваторов основные функции и возможности архиваторов

      Как выбрать конкретный обработчик?
      Выбор зависит от поставленной задачи. Что конкретно можно делать в каждом обработчике опишу ниже, а пока пример.

      title

      Пример выбора обработчиков событий записи объекта:
      Бывают задачи, когда потребуется использовать несколько обработчиков для решения одной задачи. Например, надо запросить информацию у пользователя во время записи: «Будем создавать новый документ на основании этой записи?» и, если пользователь ответит утвердительно, то надо создать новый документ с ссылкой на записываемый объект. Причем запись нового документа надо выполнять в транзакции, т.к. если текущая запись по каким то причинам будет отменена, то и уже созданный и записанный документ не должен остаться в базе данных.
      Для решения этой задачи потребуется использовать обработчики события модуля формы по двум причинам:
      1) Диалог с пользователем возможен только на клиенте, а клиентеские обработчики есть только в модуле формы. Для диалога будем использовать клиентскую процедуру модуля формы ПередЗаписью(), и сохраним ответ пользователя в параметре этой процедуры «ПараметрыЗаписи».
      2) А в процедуре ПриЗаписиНаСервере() модуля формы примем этот параметр и в зависимости от него будем создавать документ или нет. Почему именно эта процедура? Ссылка будет получена только после записи, но поскольку нам нужно записывать в транзакции, то нужно использовать процедуры ДО завершения транзакции, но уже имеющие ссылку на записываемый объект. ПередЗаписью() не подходит , так как ещё нет ссылки, а ПослеЗаписи() не подходит, так как транзакция уже завершена. Остаётся ПриЗаписи(), но перед нами встаёт выбор: модуля формы или модуля объекта? Поскольку обработчик события ПриЗаписи() модуля объекта не содержит параметр, содержащий ответ пользователя, а событие ПриЗаписиНаСервере() модуля формы содержит, то ответ очевиден-используем это событие ПриЗаписиНаСервере() модуля формы потому что:
      1) Это событие выполняется в транзакции 2) Содержит параметр «ПараметрыЗаписи», в котором уже содержится ответ пользователя, который передался из процедуры ПередЗаписью() 3) Ссылка уже создана и можно создавать новый документ, используя эту ссылку.

      Ну и теперь последовательность запуска событий (в том порядке, в каком они перечислены) и небольшие подробности :
      Во многих обработчиках есть параметр «Отказ». Там, где этот параметр присутствует означает, что в этом обработчике ещё можно отказаться от записи, присвоив параметру «Отказ» значение Истина, и тогда запись произведена не будет.
      1) Модуль формы ПередЗаписью(Отказ, ПараметрыЗаписи)
      Выполняется на клиенте!
      Этот обработчик следует использовать, если необходимо организовать диалог с пользователем перед тем, как записать объект. Запросить дополнительную информацию, предупредить о чём-либо, дать возможность отказаться и т.п.
      Второй параметр этого обработчика «ПараметрыЗаписи» имеет тип «Структура». У документов эти параметры заполняются системой предопределенными параметрами РежимЗаписи, РежимПроведения. Можно добавить свои.
      Эти параметры передаются между событиями формы ПередЗаписьюНаСервере, ПриЗаписиНаСервере, ПослеЗаписиНаСервере, где их можно благополучно использовать. Например, при записи регистра сведений, надо сделать запись в другой регистр сведений старое значение ресурса. Можно передать старое значение в эти самые параметры и уже в ПриЗаписиНаСервере сделать запись в другой регистр.
      2) Модуль формы ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
      3) Модуль объекта ОбработкаПроверкиЗаполнения (Отказ, ПроверяемыеРеквизиты)
      Эти два обработчика проверки заполнения реализуются через параметр «ПроверяемыеРеквизиты» типа Массив, содержащий реквизиты, которые надо проверять (т.е. которым установлено свойство проверки заполнения «Выдавать ошибку»)
      И если из этого массива убрать реквизит, то проверяться он не будет, если добавить, то будет выполняться проверка заполнения.
      Таким образом, можно сказать, что эти два обработчика событий предназначены :
      Для включения в проверку заполнения тех реквизитов, у которых в свойствах «ПроверкаЗаполнения» указано «Не проверять». Для этого надо добавить этот реквизит в массив параметр «ПроверяемыеРеквизиты»
      Для того, чтобы исключить из автоматической проверки реквизиты, у которых установлено свойство проверки заполнения «Выдавать ошибку» в зависимости от каких-то условий. Для этого надо удалить этот реквизит из массива параметра «ПроверяемыеРеквизиты»
      Имеется несколько особенностей, которые необходимо учитывать:
      Если у формы из которой записывается объект в свойствах не установлено «ПроверятьЗаполнениеАвтоматически», то тогда эти обработчики проверки заполнения не вызываются и проверки не происходят!
      Вызываются только при интерактивной записи! При программной записи не вызываются. Для проверки нужно использовать метод объекта ПроверитьЗаполнение(), который инициирует запуск этих событий.
      Для документов, имеющих возможность проведения , эти события проверки заполнения вызываются только при проведении!
      Оба эти события выполняются на сервере, отличие в том, что ОбработкаПроверкиЗаполненияНаСервере() это событие модуля формы и, следовательно, есть доступ к данным формы. А ОбработкаПроверкиЗаполнения() — событие модуля объекта.
      4) Модуль формы ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
      В этом обработчике можно дозаполнять реквизиты объекта или провести дополнительные проверки. Есть доступ к данным формы. Есть параметр ТекущийОбъект.
      Параметр ТекущийОбъект имеет тип класса «объект» в зависимости от типа записываемого объекта (СправочникОбъект,ДокументОбъект и т.д). Т.е. экземпляр класса объект создан, и можно обратиться к его свойствам и методам, но в базу данных ещё не записан.
      Начало транзакции
      5) Модуль объекта ПередЗаписью(Отказ)
      В этом обработчике можно дозаполнять реквизиты объекта или провести дополнительные проверки.
      Для документов в параметры данного обработчика добавляются ещё два параметра:РежимЗаписи, РежимПроведения.
      Запись
      6) Модуль объекта ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
      Возникает в момент, когда выполняется установка номера нового документа, задачи или бизнес-процесса.
      Или ПриУстановкеНовогоКода(СтандартнаяОбработка,Префикс)
      Возникает в момент, когда выполняется установка нового кода элемента справочника, узла плана обмена или кода плана видов характеристик.
      Эти событии вызываются для объектов у которых указано свойство «Автонумерация» и только для новых объектов.
      Если установить параметру СтандартнаяОбработка значение Ложь, то новый номер генерироваться не будет и можно программно задать код объекта в данном обработчике.
      7) Модуль объекта ПриЗаписи(Отказ)
      Вызывается после записи объекта в базу данных, но до окончания транзакции записи.
      Ссылка уже есть и можно записать в базу данных дополнительные данные на основании текущего объекта, используя эту ссылку.
      Например, при записи создавать другой документ, содержащий реквизит ссылку на записываемый.
      8) Модуль формы ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
      Вызывается после записи объекта в базу данных, но до окончания транзакции записи. Есть доступ к данным формы. Есть последний шанс отказаться от записи.
      Параметр ТекущийОбъект имеет тип класса «объект» в зависимости от типа записываемого объекта (СправочникОбъект,ДокументОбъект и т.д). Можно обратиться к его свойствам и методам.
      Завершение транзакции
      9) Модуль формы ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
      Выполняется на сервере.
      Можно использовать для того, чтобы визуально что-то отобразить на форме.
      10) Модуль формы ПослеЗаписи(ПараметрыЗаписи)
      Выполняется на клиенте!
      Можно использовать для того, чтобы визуально что-то отобразить на форме или выдать предупреждение пользователю.

      Читайте также:
      Программа через которую смотрят фильмы

      Источник: http://infostart.ru/public/153748/

      Разместил: E_Migachev Версии: | 8.x | 8.2 УП | Дата: 14.10.2012 Прочитано: 90480

      Распечатать

      Возможно, вас также заинтересует

      Похожие FAQ

      Как заполнить табличную часть формы программно? 8
      Нужно по кнопке Заполнить — сформировать данные для заполнения табличных частей и заполнить их. Форма имеет вид: Рядом с кнопкой Записать и закрыть добавлена кнопка Заполнить документ , код ее команды: // Код заполнения ТЧ НаСервере П 17 правил для составления оптимального ЗАПРОСа к данным базы 1С 50
      Для формирования и выполнения запросов к таблицам базы данных в платформе 1С используется специальный объект языка программирования Запрос . Создается этот объект вызовом конструкции Новый Запрос . Запрос удобно использовать, когда требуется получ 1C и Google Maps 21
      была поставлена задача отображения на географической карте медицинских учреждений. После обзора предлагаемых решений был выбран сервис google. Но так же подобного рода подход будет работать и с картами сервиса yandex. Во время решения задачи было реш 1C: Enterprise Development Tools 51
      И вот случилось долгожданное: Вышел 1C: Enterprise Development Tools — это среда для разработки конфигурации в IDE Eclipse. С сайта 1С: « 1C:Enterprise Development Tools » – это инструмент нового поколения для разработчиков бизнес-приложений систем 1С Предприятие что это? 12
      Что такое 1С? 1С — это фирма , у которой одно из направлений деятельности — разработка программного обеспечения для автоматизации бизнес-процессов предприятий. « 1С:Предприятие » — конкретный продукт, который выпускает компания 1С . Что такое Посмотреть все результаты поиска похожих

      Еще в этой же категории

      Полнотекстовый поиск в 1С (что это и пример использования) 27
      Полнотекстовый поиск — позволит найти текстовую информацию, размещенную практически в любом месте используемой конфигурации. При этом искать нужные данные можно либо по всей конфигурации в целом, либо сузив область поиска до нескольких объектов Формат, функция форматирования значений 21
      //Функция формирует удобное для чтения представление значений. // Примеры форматирования чисел ЗначФормат = Формат(123456.789, » ЧЦ=10; ЧДЦ=2″ ); // ЗначФормат = » 123 456,79″ ЗначФормат = Формат(123456.789, » ЧГ=0; ЧДЦ=2″ ); // Знач УстановитьСсылкуНового 12
      Установить ссылку нового это специальный механизм программиста, который позволяет присваивать новому объекту нужную ссылку. В основном это задача обмена, во многих типовых обменах используется синхронизация по UID объекта. Рассмотрим этот метод на к МоментВремени, получение остатков до и после проведения 11
      » Момент времени» — виртуальное поле, не хранится в базе данных. Содержит объект МоментВремени (который включает в себя дату и ССЫЛКУ НА ДОКУМЕНТ) В 7.7 было понятие ПозицияДокумента, а в 8.x Момент времени Для получения Остатков, Движений: М Как получить уникальный идентификатор объекта, GUID? 10
      GUID (Globally Unique Identifier) — статистически уникальный 128-битный идентификатор. Его главная особенность — уникальность, которая позволяет создавать расширяемые сервисы и приложения без опасения конфликтов, вызванных совпадением идентификатор Посмотреть все в категории Встроенные Функции

      Источник: helpf.pro

      Рейтинг
      ( Пока оценок нет )
      Загрузка ...
      EFT-Soft.ru