86. Ссылки (REFERENCE TO) — АСУ ТП: сообщество инженеров

86. Ссылки (REFERENCE TO)

О чём видео

Разбор типа данных «ссылка» (REFERENCE TO) в CODESYS 3.5: отличия от указателей, индексный доступ, передача строк без копирования, объявление и инициализация ссылок, проверка через __ISVALIDREF, получение информации оператором VAR_INFO и особенность инициализации ссылки в SFC.

Что разбирается
  1. 00:00 Ссылки как разновидность указателей в CODESYS
  2. 03:42 Передача строк по ссылке и доступ на запись
  3. 09:27 Объявление, инициализация и проверка ссылок
  4. 14:02 Получение информации о ссылке через VAR_INFO
  5. 18:25 Инициализация ссылки в языке SFC
Оборудование и ПО
  • CODESYS
  • CODESYS 3.5
  • ST
  • REFERENCE TO

Кому полезно: Инженерам АСУ ТП, программирующим ПЛК на CODESYS и работающим с указателями и ссылками.

Описание составлено автоматически по расшифровке речи в ролике.

Расшифровка видео

0:00 Добрый день, коллеги, мы продолжаем говорить про Кдесис 3 5 и сегодня разберемся с таким типом данных, как ссылки. 1 Что следует заметить, что ссылки являются разновидностью указателей, если? Вы хотите освежить в памяти, что такое указатели и как с ними работать в КДС? Я рекомендую вам ознакомиться с замечательным видео Сергея Романова. Я оставлю ссылку на него в описании.

0:27 К видео Сергея я хотел бы добавить только 2 комментария, связанных уже непосредственно с особенностями к дефис версии. 3 5 1 Из них это поддержка индексного доступа. Предположим, вы хотите реализовать функцию, которая принимает указатель на массив переменных, например, в переменах типа Рил и число элементов этого массива и возвращает результат сложения всех этих элементов с соответственно. Если бы вы реализовывали эту функцию в КДЧС, 2 3 то вы бы организовали цикл и на каждой итерации цикла вы бы смещали адрес, по которому производите доступ на размер перемены типа Риллах, использую оператор сазов.

1:14 Для того чтобы получить доступ к очередному элементу массива, размещенного под указателем в В КД систре, 5 можно сделать проще вы. Просто обращайтесь к указателю как к массиву и таким образом получаете доступ к его и тому элементу, точнее, к значению размещенному. Точнее, к значению, соответствующему этому и тому элементу. То есть, когда вы используете такой синтаксис, вы получаете нулевой элемент? Массива по год указателем 1 и так далее при этом разминание происходит автоматически. Вам уже не нужно использовать этот оператор. Крышечку соответственно вот этот код и вот этот являются совершенно эквивалентом. Только в КДСистый 5 можно сделать его проще, уместив. Буквально вот в 1 строку из гораздо более меньшим числом операций, и это что касается индексного доступа 2 замечание, которое следует. Сделать если в КДС 2 3 размер указателя всегда 32 бита, то есть обычных их интерпретирует как перемена типа деворт, то в колесистой. 5 Размер указателя зависит от разрядности системы исполнения. Если у вас паука с 30 ты убитая схема исполнения, то размер указателя. Действительно, 32 бита, то есть двор, если у вас полка 64 битная система исполнения, то размер указателя будет соответственно 64 бита, то. Есть Элворт, поэтому если вы пишите кросс, платформенное по то для представления указателей удобно использовать специальный системный. Тип данных, который называется ИКС Ворд и начинается с 2 нижних, подчеркиваний переменная такого типа на 30 двухбитных платформах, интерпретируется как двор, а на 60 четырехбитных, как Элворт. То есть как раз в размер соответствующего указателя и последнее, что? Следует отметить, что даже на 64 битных платформах разность 2 адресов представляет собой 30 двухбитное значение, и это все, что касается. Указателей теперь переходим непосредственно к ссылкам. Я уже говорил, что ссылки являются разновидностью указателей и используется. Примерно для тех же целей, когда вы хотите избежать ресурсоемкого копирования больших объемов данных и вместо этого хотите обратиться непосредственно к адресу в памяти и поработать прям со значением, которое там лежит без каких то дополнительных копирований.

3:42 Простой пример, который используется в системных библиотеках. Например, вам надо, в какую то функцию или функциональный блок передать В. Строку это может быть длинная строка, она может содержать, например, путь к файлу или доменное имя или имя пользователя визуализации. И так далее, если вы просто объявите вход типа стринг, то при вызове функции у вас будет произведено копирование строки из вашей программы на вход вашей функции и соответственно зависимости от размера строки. Если это длинные строки, то это может быть довольно. Ресурсоемкой операции вместо этого вы можете объявить вход типа ссылка референс Ту Сринк. И в данном случае у вас уже не будет приходить копирование. Вы просто положите, получите значение, которое лежит по заранее известному адресу в памяти, более того, для. Пользователя, который будет применять вашу функцию, совершенно ничего не изменится, точнее, не совсем так, почти ничего не изменится. Давайте вот я организую в программе вызов своей функции. Чек Юзерная, она не содержит кода и в рамках примера это не особо интересно, но.

4:50 Вот так я бы вызвал эту функцию, и копирование не произошло, просто функция бы получил значение по адресу, которая находится в моей переменной С. Фародиным могла бы его как то обработать. Кроме того, как и в случае указателей с помощью ссылок вы получаете доступ не только на чтение, но и на. Запись, поэтому, как как это ни странно, может звучать, но значение входной переменной вы можете изменить в коде, но, собственно, с использованием. Указателем с использованием указателя вы могли бы делать то же самое. Вы могли бы из кода функции изменить значение, адрес которого передаете функцию?

5:28 Я вот раз комментирую свой вот этот странный код, в котором я присваиваю значение своему входу, который имеет тип ссылка. И сейчас мы увидим, что в моей программе значение переменной, которая я передаю функцию, она после вызова изменится. То есть из функции произошел доступ на запись? Совершенно не обязательно использовать такой эффект, но, наверно, стоит понимать, что он есть. Что если вы передаете значения по ссылке, то изнутри в это значение тоже можете изменить?

5:58 Еще 1 интересный эффект, если я попробую какую то константу здесь точнее литирал. Если попробую поставить какой, то литирал, то я получу ошибку компиляции. Вот мы видим такая вот ошибка, что строка переменная слишком коротка для ВАР и на Аут параметра. Это, кстати, довольно интересное сообщение и про ВАР, и на вот параметры мы тоже сейчас поговорим. Но надо иметь ввиду, что вот такой эффект есть. При этом, если бы вы. Сделали, например, вот так.

6:43 Есть попытались бы указать. Попытались бы указать. Длину строки ровно такой, которую вы собираетесь передавать, то ошибки бы уже не было. Но мы понимаем, что это предупреждение бы осталось, но мы понимаем, что это довольно неудобно, вы. Заранее не знаете, там сколько символов занимает путь файлу и указать. Вот у ссылки на строку конкретное число элементов строки вы просто не сможете, так что это в общем то не панацея вот.

7:13 В этом, конечно, есть некоторые неудобства с другой стороны. Вы можете вот как вам компилятор намекает использовать, использовать вар и на аутопеременные. У меня есть функциональный блок, в котором я объявила перемены в. области вход, выход в ВАР и наут, и смотрите, какой интересный эффект. Возможно, вы его раньше замечали, если работали с переменными типа вход, выход, а возможно, и нет. Если вы в режиме отладки посмотрите на то, как выглядит ваш? Функциональный блок, то вы увидите, что ваши переменные области входа выхода они как раз отбрали за С. Есть фактически, когда вы объявляете перемены в области вора и на вот она интерпретируется как ссылка и Варанаут в квисистре. 5 Реализована через ссылки, а вот версий 2 3 они были реализованы через указатели. Ну потому что ссылок версий 2 3 соответственно не было, и тут еще есть интересный момент. Если вы используете варнаут, вот смотрите вот это, то.

8:14 И вот это, то есть вход типа, ссылка на строку и варенаута типа стринга, они эквивалентны. Но если вы добавите ключевое слово, Констант, то вы во 1 уже не сможете изменять это значение изнутри нашего полу, а во 2 вы сможете. Передавать уже при вызове литералы, то есть, например, поставить путь к файлу уже какой то конкретный и не будет ошибки компиляции, которая была, когда я пытался это сделать. При использовании ссылки в качестве входной переменной.

8:49 Если вы используете локальные переменные и хотите поработать со ссылками внутри вашего кода, то используется специфический. Но довольно простой индекс из добавили. Давайте я объявлю в своей программе некий массив данных, но. Например, массив переменных типа Ворд. И ссылку на него. Обратите внимание, что ссылки имеет некоторые ограничения, например, нельзя объявить ссылку на ссылку, ссылку на указатель, массив ссылок, ссылку, набит и так далее в справке Кодечис в статье про ссылки.

9:41 Все это расписано и ссылку на статью про ссылки я тоже приложу в описании к видео. Вот и теперь теперь у нас есть ссылка, но пока что мы не используем в коде, она является, она по. Умолчанию равна 0 и является не инициализированной, чтобы инициализировать ссылку. Мы используем вот такой специальный синтепсис, мы вводим реф, сокращение от референс и ставим знак равно.

10:08 И поставляем объект того же типа, на который должна указывать ссылка. И теперь, когда мы будем производить какие то действия с переменой ревдата. Ну, например, изменять ее значения или производить над ним какие то операции, то. Все эти изменения будут точно так же сразу отображаться на объекте. Вы дата, потому что Ревдата это только ссылка на вот этот объект, то есть как, по сути, это просто вот некий такой специальным образом типизированный указатель.

10:39 Если вы хотите в коде проверить вашу ссылку, инициализирована она или нет. Например, если вы используете вот ссылку как вход, функции и вы хотите проверить, что пользователь вам что то передал на этот вход, то опять таки нужно использовать специальный оператор. Который я сейчас покажу. Это оператор. Из Вали Древ, он опять начинается с 2 нижних подчеркиваний, поскольку является системным. Вы передаете в качестве аргумента ссылку, и он возвращает значение ТРУ. Если эта ссылка инициализирована, то есть. Если ей передан какой то объект, если она указывает, на какой то объект, давайте проверим. У меня соответственно оператор должен вернуть значение труб, потому что я уже свою ссылку проинициализировал.

11:38 Как ожидалось, если же мы теперь вот эту строку закомментируем? И опять запустим мою программу. То мы увидим, что оператор имеет значение, Фолс. Ссылка является не не инициализированной, и более того, вот если мы раскроем наш массив, мы видим, что здесь написано разменование не валидного указателя. В некоторых случаях при нулевой ссылке, например, если бы у вас там был. Функциональный блок библиотеки у вас бы, напротив, значения в поле значения отобрался бы. Например, 0 это все не сильно важно после. Просто надо понимать, что перед использованием ссылку надо инициализировать каким то объектом.

12:32 И еще 1 момент, про который стоит рассказать это про размер ссылки, давайте мы объем переменную типа де Ворд. И к нашей ссылке используем оператор Сальс ОФ. Запустим наш проект и посмотрим, что же он нам вернет. Мы видим, что это 512 байт, то есть полный размер нашего массива, который здесь 56 вордов. Ну, соответственно, Кали вор 2 Байта, и вы можете подумать, что ссылка занимает в памяти контроллера столько же памяти, сколько и объект. На который указывает и таким образом складывается впечатление, что с точки зрения использования памяти она гораздо менее гораздо менее эффективно, чем указатель. Потому что размер указателя, как мы уже сказали всего. Всего 4 Байта на 30 двухбитных платформах или 8 на 60 четырехбитных, но это обманчивый эффект. На самом деле, когда мы используем оператор Сальзов к ссылке, мы фактически получаем значения нашего объекта, который лежит по. Ссылке, как я уже говорил, когда мы работаем ссылкой, мы всегда попадаем в наш объект ссылка. Как бы пускай постоянно от нас ускользает, мы никак не можем в явном виде с ней поработать. Это как раз обеспечит ее безопасность.

14:02 Поэтому, чтобы определить реальный размер ссылки, точнее убедиться, что он совпадает с размером указателя, надо сделать следующее объем еще 1 системную структуру, это структура. Из системного пространства имен систем с 2 нижними подчеркиваниями она называется ВАР Инфо. И в коде мы используем оператор, который так и называется ВАР Инфо. Чтобы получить полную информацию о нашем объекте, так я не правильно написал. Тут не должно быть не не подчеркивание, вот так от оператора выглядит.

14:48 После вызова этого оператора мы заполним нашу структуру данными о нашем объекте, и в данном случае мы уже обращаемся не к объекту, который лежит по ссылке из за особенности реализации оператора. Мы обращаемся к самой ссылке. И вот мы видим. Что размер в битах нашей ссылки это 32 бита, то есть 4 Байта, и это все совпадает с размером указателя на 32 видных платформах. Ну и + остальную информацию, то есть о типе, а и вымени нашей ссылки мы можем здесь получить.

15:23 Таким образом, с точки зрения использования памяти контроллера между ссылками и указателями нет разницы и более того, даже с точки. зрения производительности разница между ссылками и указателями, и указателями минимально. То есть не стоит это воспринимать с такой? Точки зрения ссылка не работает быстрее или медленный указатели и не занимает в памяти больше или меньше места. Разница между ссылками и указателями в том, что ссылка является, скажем так, безопасной, то есть, используя указатель, вы можете обратиться, например, К. Какому то полю структуры по смещению или просто к произвольному значению по адресу, то есть, как мы уже говорили, можно использовать. Адресную арифметику, смещая значение адреса. Вот буквально там по Байтово ссылка такой вольности уже не позволяет, вы всегда попадаете. Вот в объект заранее известного типа, вот ссылка напрямую. Вы не можете с ней работать, вы не можете там прибавить, не 1 чтобы сместить. Ее на 1 Байт и так далее вы всегда работаете уже с неким объектом, тип которого соответствует вот тому типу, который вы ожидаете.

16:30 У указателей соответственно такого нет, и с 1 стороны это, конечно, не безопасно. Вы можете, случайно используя указатели, выйти вообще за пределы памяти, в которой размещен ваш объект, например, случайно ошибиться и сместить там размер? Ада и к адресу там прибавить не 10, например, там, а 10.00 и случайно выйти вообще за пределы памяти, в которой размещен ваш объект. С другой стороны, это позволяет определенную гибкость. Вы можете вот в рамках объекта обратиться вообще. К любому его Байту независимо от типа объекта, например, у вас есть структуры. Вы говорите, я хочу обратиться там к этому Байту, и вы можете это сделать. Это более гибко, но менее безопасно. Ну и, конечно, есть отличие в синтаксисе, то. Есть при работе с указателем, вам приходится использовать оператор АДР, оператор разменования в случае ссылки ссылкой вам приходится вот использовать только оператор присвоения ссылки и инициализации ссылки вот этот РФ равно и.

17:26 И соответственно, если еще требуется использовать вот этот оператор из валит рев, а при использовании, то. Входных параметров типа ссылка, как вот своей функции, мы как в полном начало из начала видео. Даже никакие специальные операторы не должны использовать, то есть для нас как будто бы у нас вход тип стринг. То есть, казалось, ну считается, что очень таки с польная ссылка несколько проще, но опять таки это вкусовщина. На самом деле, что там, что там нужно просто запомнить? Набор небольшой набор ключевых слов в принципе и при работе с указателями при работе ссылки не ход. По сути, там, 3 то есть Пойнтер, референс Адр или реф. Равно и ну да, указатель еще есть оператор разменования. У ссылки такого нет, но зато есть дополнительные операторы вот из валитров специальные, которые используются. Для проверки валидности ссылки в принципе в контексте указателей. Это то же самое, что если вы бы проверяли указатель на равенство 0 примерно то же самое.

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

18:47 Давайте. Объявим. Какую нибудь ссылку в моей программе на языке Си Эф Си? Ну и перемены соответствующего типа. Смотрите, если вы попробуйте вот просто в лоб использовать. Оператор Рэф, равно который прекрасно работает в ст. И который я вам вот совсем недавно показывал. То у вас возникнет, ну не то, что даже возникнет ошибка компиляции, вы видите что? Не получается сделать так, чтобы у него был вход и выход. То есть, ну как казалось бы, непонятно вообще, как тогда ссылку все все проинициализировать?

19:40 Так неправильно сделал. Для того чтобы инициализировать ссылку в языке Си Эф Си, нужно сделать следующее. Вы проводите линию связи между вашей переменной и ссылкой нажимаете на правую кнопку мыши и используете во вкладке сетрезать вот такую. Специальную штуку граф равно вот она специальным образом над линией связи начинает отображаться. И это как раз все все является оператором инициализации ссылки, то есть вот таким специфическим образом он устанавливается.

20:21 Собственно, все, что я хотел рассказать про ссылки, я рассказал. Если вы уже работали с указателями, то я думаю, все вышесказанное вам вполне понятно. И вы понимаете разницу в синтаксисе и и понимаете? Главное, что выбор между ссылкой и указателем это вопрос, что с точки зрения синтаксиса вам удобнее использовать с точки зрения производительности и использования памяти разницы никакой нет.

20:47 Спасибо вам за внимание и увидимся в следующих видео.

Расшифровка сделана автоматически (Yandex SpeechKit) и может содержать ошибки в терминах.

Видео Сергея Романова об указателях:
https://youtu.be/OxC8_HwU8Dw

Статья про ссылки из справки CODESYS:
https://content.helpme-codesys.com/en/CODESYS%20Development%20System/_cds_datatype_reference.html

Оставьте комментарий

Войти

Зарегистрироваться

Сбросить пароль

Пожалуйста, введите ваше имя пользователя или эл. адрес, вы получите письмо со ссылкой для сброса пароля.

Прокрутить вверх