PDA

Просмотр полной версии : Указатели (POINTER)



ibx
18.05.2014, 22:10
Взял из примеров весьма нужную функцию - two_word_to_real
Великолепно работает, но сам код не понял. Если можно поподробней разъясните пожалуйста.

FUNCTION two_word_to_real : REAL
VAR_INPUT
IN_Data: POINTER TO ARRAY[0..1] OF WORD; (*Указатель на массив регистров для Float*)
END_VAR
VAR
p1: POINTER TO BYTE;
p2: POINTER TO BYTE;
END_VAR

p1:=ADR(two_word_to_real);
p2:=ADR(IN_Data^[1]);
p1^:=p2^;
p1:=p1+1;
p2:=p2+1;
p1^:=p2^;
p1:=p1+1;
p2:=ADR(IN_Data^[0]);
p1^:=p2^;
p1:=p1+1;
p2:=p2+1;
p1^:=p2^;

capzap
18.05.2014, 22:20
Да ну, фигня это всё, это можно спокойно сделать с помощью shl, без всякого создания подобных функций, ладно бы ещ байты местами надо было бы менять

amn
19.05.2014, 00:32
Взял из примеров весьма нужную функцию - two_word_to_real
Великолепно работает, но сам код не понял. Если можно поподробней разъясните пожалуйста.

FUNCTION two_word_to_real : REAL
VAR_INPUT
IN_Data: POINTER TO ARRAY[0..1] OF WORD; (*Указатель на массив регистров для Float*)
END_VAR
VAR
p1: POINTER TO BYTE;
p2: POINTER TO BYTE;
END_VAR

p1:=ADR(two_word_to_real);
p2:=ADR(IN_Data^[1]);
p1^:=p2^;
p1:=p1+1;
p2:=p2+1;
p1^:=p2^;
p1:=p1+1;
p2:=ADR(IN_Data^[0]);
p1^:=p2^;
p1:=p1+1;
p2:=p2+1;
p1^:=p2^;

Если коротко, то массив из двух регистров имеет 4 байта в следующей последовательности
1-й байт, 2-й байт, 3-й байт, 4-й байт

После выполнения функции последовательность будет такая
3-й байт, 4-й байт, 1-й байт, 2-й байт


FUNCTION two_word_to_real : REAL
VAR_INPUT
IN_Data: POINTER TO ARRAY[0..1] OF WORD; (*Указатель на массив регистров для Float (всего 4 байта)*)
END_VAR
VAR
p1: POINTER TO BYTE; (указатель на результат функции)
p2: POINTER TO BYTE; (*указатель на массив регистров*)
END_VAR

p1:=ADR(two_word_to_real); (*указатель на начало результата функции (1-й байт)*)
p2:=ADR(IN_Data^[1]); (*указатель на второй элемент массива (3-й байт) *)
p1^:=p2^; (*копируем содержимое по адресу второго указателя в адрес первого указателя *)
p1:=p1+1; (*смещаем адрес на 1 байт, теперь он указывает на 2-й байт результата*)
p2:=p2+1; (*смещаем адрес на 1 байт, теперь он указывает на 4-й байт массива*)
p1^:=p2^; (*копируем содержимое по адресу второго указателя в адрес первого указателя *)
p1:=p1+1; (*смещаем адрес на 1 байт, теперь он указывает на 3-й байт результата*)
p2:=ADR(IN_Data^[0]); (*указатель на первый элемент массива (1-й байт) *)
p1^:=p2^; (*копируем содержимое по адресу второго указателя в адрес первого указателя *)
p1:=p1+1; (*смещаем адрес на 1 байт, теперь он указывает на 4-й байт результата*)
p2:=p2+1; (*смещаем адрес на 1 байт, теперь он указывает на 2-й байт массива*)
p1^:=p2^; (*копируем содержимое по адресу второго указателя в адрес первого указателя *)

lara197a
19.05.2014, 20:19
Адресная регистрация придумана давным давно.
А еще есть символьная.
В Вашем случае указатели вообще не уместны.
все давно пользуются вторым вариантом(символьная.)

приборист
20.05.2014, 13:12
Адресная регистрация придумана давным давно.
А еще есть символьная.
В Вашем случае указатели вообще не уместны.
все давно пользуются вторым вариантом(символьная.)

А символьная это как?
Все пытаюсь осознать указатели, а тут еще и символьная существует :)

lara197a
20.05.2014, 20:50
при создании переменной обзавите ее как нравится.
и используйте это слово по всей программе, где имеете данную переменную.
см. справку..

ibx
21.05.2014, 18:34
Можно поподробней - заинтриговали, но попытки изобразить нечто подобное с использованием справки ни к чему не привели.

приборист
22.05.2014, 15:23
при создании переменной обзавите ее как нравится.
и используйте это слово по всей программе, где имеете данную переменную.
см. справку..

Ааа.. Ну так всегда делал и делаю :)

Максим Tomahawk
03.09.2014, 08:11
В CoDeSys 3 есть Union, кто писал на С наверное предпочтёт через него сделать )

TYPE uRealBytes :
UNION
rValue : REAL; // Needs 4 Bytes in memory
abValue: ARRAY [0..3] OF BYTE;
END_UNION
END_TYPE

В CoDeSys 2.3 мне надо было REAL разбить на массив байт, чтобы их передать. Сделал это следующим образом:

P1: POINTER TO ARRAY [0..3] OF BYTE;
TempMassiv: ARRAY[0..3] OF BYTE;
P1 := ADR(Pressure);
TempMassiv := P1^;
И из TempMassiv теперь можно байты забирать куда нужно.

Yegor
03.09.2014, 08:39
кто писал на СКто писал на C, тот в цирке не смеётся того ломает прежде всего от невозможности разыменовать возврат ADR. То есть нельзя сделать a := ADR(a)^ как это допускается в Си (a = *&a), потому что ADR возвращает DWORD, а не POINTER. Будь иначе, можно было бы обойтись без объявления лишних переменных и типов.

capzap
03.09.2014, 08:48
С помощью shr/shl и and, можно обойтись буз указателей и лишних переменных если что

Валенок
03.09.2014, 10:49
потому что ADR возвращает DWORD, а не POINTER.
Так в КДС нету "просто POINTER"

to capzap
А без указателей для TC - не обойтись. Или union (КДС3, см.выше), или я-ля union с размещением 2 переменных в одной области памяти с помощью % (есть ли в КДС3 ?).
Только у TC сложно как-то. Там 2 строчки всего нужны. Но с rol ))

capzap
03.09.2014, 10:59
Превратить в реал да будет нужен указатель, но я то про перемещение байт имел ввиду, а rol это продвинутое смещение, примитив то всёравно shr

Yegor
03.09.2014, 16:08
Так в КДС нету "просто POINTER"Ну, да-да, POINTER TO _ТИП_ (в том числе POINTER TO ANY, между прочим, если речь о третьем кодесисе). Сути не меняет. ADR возвращает DWORD. Почему не могли сделать, чтобы возвращался указатель того же типа, что и аргумент, теперь остаётся только гадать.

Kavoo
30.05.2015, 14:48
Наверное для того чтоб ты мог пихнуть свой массив или там структуру в любое место памяти ПЛК, где можно обявить прямоадресуемую переменную.

Yegor
30.05.2015, 16:34
чтоб ты мог пихнуть свой массивХи-хи. Пример запихивания?

Можно сказать, что в КДС нет функции или оператора получения указателя. Есть только функция получения адреса типа DWORD, что не является указателем в системе типов компилятора.

Валенок
30.05.2015, 17:47
Почему не могли сделать, чтобы возвращался указатель того же типа, что и аргумент..
r : real;
d : dword;

sysmemcpy(adr(r),adr(d),4); //Cейчас - нормуль. Видимо при возврате того же типа что и аргумент - "тип мисмач", ведь real^ := dword^

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

Yegor
30.05.2015, 18:58
"тип мисмач"Тайп мисмач не случается, когда есть неявное преобразование. В данном компиляторе REAL в DWORD неявно преобразовать нельзя, POINTER в DWORD — можно. Вот этот код демонстрирует неявное преобразование указательного типа в числовой
PROGRAM PLC_PRGVAR
ptr1, ptr2: POINTER TO ARRAY [0..1] OF BYTE;
END_VAR

SysMemCpy(ptr1, ptr2, 1);На месте аргументов спокойно уже сейчас может стоять аналог ADR, возвращающий не число, а указатель, но такого аналога нет. Другими словами, операции взятия указателя в кодесисе просто нет. Указатели приходится заранее объявлять, а потом инициализировать через обратное приведение (тоже неявное — DWORD в POINTER).

Валенок
30.05.2015, 23:32
Указатели приходится заранее объявлять
Может kavoo имел ввиду


PROGRAM PLC_PRGVAR
tr1, tr2: ARRAY [0..1] OF BYTE;
END_VAR

SysMemCpy(adr(tr1), adr(tr2), 1);
без объявления указателей ?


В данном компиляторе REAL в DWORD неявно преобразовать нельзя
А много где можно именно преобразовать? И вроде выше - не преобразование, а другая точка зрения.
Например - кирпич. Строитель видит материал для стр-ва, математик - параллепипед, повар - гнет для квашения.. Но объект при этом не меняется.

Sergey666
30.05.2015, 23:45
Может kavoo имел ввиду


PROGRAM PLC_PRGVAR
tr1, tr2: ARRAY [0..1] OF BYTE;
END_VAR

SysMemCpy(adr(tr1), adr(tr2), 1);
без объявления указателей ?


А много где можно именно преобразовать? И вроде выше - не преобразование, а другая точка зрения.
Например - кирпич. Строитель видит материал для стр-ва, математик - параллепипед, повар - гнет для квашения.. Но объект при этом не меняется.

Академики ! Вы наше все ! А , пролетариат , за неимением булыжника увидит в кирпиче оружие... ;)

Yegor
31.05.2015, 14:25
без объявления указателей ?Типизатору (часть компилятора, которая вычисляет типы в узлах дерева выражений) не важно, объявленную вы переменную подставляете в качестве аргумента или просто вызов функции. Я своим примером проиллюстрировал, что SysMemCpy, имея сигнатуру [DWORD, DWORD, DWORD] спокойно принимает параметры [POINTER TO ..., POINTER TO ..., DWORD]. Соответственно нормальный оператор взятия указателя не помешал бы ничего никуда пихать.
А много где можно именно преобразовать?В Си тип float может неявно преобразовываться в тип int (дробная часть отбрасывается). Вот в C#, например, уже не может — придётся написать intVar = (int) floatVar, а intVar = floatVar — нельзя.
не преобразование, а другая точка зренияЭто преобразование в контексте системы типов. Если, например, функция требует аргумент типа A, а вы ей даёте другой тип B, то компилятор проверяет совместимость типов в частности через заложенные в него операции неявного приведения/преобразования. Если неявное приведение A -> B возможно, то аргумент принимается как есть прозрачно для программиста. Иначе программист приводит тип явно (функции типа REAL_TO_DWORD).

Валенок
31.05.2015, 22:17
SysMemCpy, имея сигнатуру [DWORD, DWORD, DWORD] спокойно принимает параметры [POINTER TO ..., POINTER TO ..., DWORD].

Да. Но первые два указаны как адреса в описании. Был бы адрес из 16 бит - были бы WORD.
Уже ж говорили что просто "pointer" - нету (Не хотели/Прое..ли/Проиграли на спор/Отвалилась кнопа P/Не выговаривали букву R/Не оказалось германо-аглицкого словаря/В память дедушке которого сбили над Каналом/Мания величия - а тут УКАЗАТЕЛЬ ... нужное подчеркнуть)
А что общее у адресов данного проца ? Размер 4 байта
А кто еще имеет размер 4 байт ? DWORD/DINT/UINT/REAL
А кто из них даже не число ? DWORD
DWORD похож на UINT ? так получилось.
Можно делать матоперации ? Можно. Ведь для взятия байта со смещением 4 от текущего адреса нужно к текущему адресу прибавить 4 !! Кто бы мог подумать ...

типа того


В Си,.. Вот в C#,
Всегда казалось что тут дед - Н.Вирт )) Со всеми вытекающими.


функции типа REAL_TO_DWORD
Именно эта функция - преобразование самого содержимого. А иногда нужен просто битовый формат хранения.

Sergey666
31.05.2015, 23:54
Очень было-бы интересно понаблюдать за разговором этих товарищей (Да со всем уважением) за ...столом с шашлыком и водочкой , не смотря на разделяющее их пространство ... хотя может и хорошо , когда два таких мозга разделены ... некоторым пространством...:D