Показано с 1 по 10 из 35

Тема: POINTER TO what?

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1
    Пользователь Аватар для drvlas
    Регистрация
    30.09.2010
    Адрес
    Киев
    Сообщений
    700

    По умолчанию

    Цитата Сообщение от Игорь Петров Посмотреть сообщение
    Если подпрограмма получает указатель и не знает что это, то сообщить ей тип логично. Она может по CASE для возможных типов взять переменную правильно, если ей это надо.
    Да, я именно так и понял то, что советовал уважаемый Валенок. В функциях чтения и записи значения параметра (там, где доступ к нему идет по индексу) будет CASE на варианты
    Код:
    BYTE
    WORD
    DWORD
    STRING
    TIME
    DATE
    При этом в структуре PARSCRIPT, описывающей интимности каждого параметра, добавляется элемент

    Код:
    Typ: PARTYPE;
    В нем и будет указываться тип переменной для данного параметра. И достаточно функции доступа указать индекс параметра, чтобы она извлекла из глобального массива структур ту, что описывает наш параметр и по элементу .Type сориентироваться, как доступаться к параметру.

    Я вот думаю: если пойнтер указывает, сколько извлекать байт (и сколько записывать), то не будет ли достаточно иметь разные указатели только на те типы данных, которые различаются количеством байт?
    Тогда у нас будет:
    Код:
    BYTE
    WORD
    DWORD
    STRING
    - и все. А всякие там INT, UINT, DINT, TIME, DATE - отдыхают. И обращение к переменной типа TIME будут происходить так же, как к переменной DWORD. Выдернутся 4 байта, а потом программа сделает с ними чего надо - и они обратно запихнутся так же. Даже порядок сохранения байтов не имеет значения, ИМХО.
    Можно так?

    Спасибо за подсказки! Постараюсь это проверить и сообщить результат.
    Последний раз редактировалось drvlas; 03.12.2010 в 20:00.

  2. #2
    Пользователь
    Регистрация
    23.09.2008
    Адрес
    Центророссийск
    Сообщений
    2,264

    По умолчанию

    Последняя идея имхо не лучшая.
    Тип - это тип.

    i : int := -15000;
    w : word := 50000;

    if ( i or w ) < 0 then ?

    Лично я нехочу заморачиваться , как конкретно данный язык будет расширять данные, до longinta все расширит или i пихнет в word или w в int


    К тому же типы - это не только стандартные.

    Например TTemperatura.
    Свойства :
    1.вывод на экран : с одним знаком после запятой, с суффиксом '*С' или текстовое сообщение 'Обрыв датчика' .......
    2.время от последнего опроса.
    ....

    Если тип - ф.блок, обрабатывающий температуру и с кучей своих данных ( таймеров и др.. ) ?



    У вас жестко определенная структура PARSCRIPT
    А зачем жестко ? Кому-то нужен min-max, а кому-то нет….
    Ведь кол-во свойств и их самоё определяет сам тип.
    Да и данные у Вас хранятся отдельно от своих свойств.
    А вдруг владельцы данных захотят поменять некоторые свойства ?
    Со списком это было бы проще (имхо)

    И жаль, конечно, что в кдс-2 нет хотя бы типа-функции.

    PS
    А вдруг тип : pointer to pointer to ......
    Последний раз редактировалось Валенок; 03.12.2010 в 20:53.

  3. #3
    Пользователь Аватар для drvlas
    Регистрация
    30.09.2010
    Адрес
    Киев
    Сообщений
    700

    По умолчанию

    Цитата Сообщение от Валенок Посмотреть сообщение
    К тому же типы - это не только стандартные.

    Например TTemperatura.
    ...
    Со списком это было бы проще (имхо)
    Вот он, профессорский подход! Но я сейчас так мелко плаваю, что не готов решать задачу в таком общем виде. И список меня пугает.

    А решая все же только свою задачу, я говорю: да,
    Цитата Сообщение от Валенок Посмотреть сообщение
    У вас жестко определенная структура PARSCRIPT
    жесткая. В нее входит то, что мне в этом проекте нужно. Что, кстати, не мешает в другом проекте внести иную (тоже жесткую) структуру.

    Цитата Сообщение от Валенок Посмотреть сообщение
    Да и данные у Вас хранятся отдельно от своих свойств.
    А вдруг владельцы данных захотят поменять некоторые свойства?
    Те данные, которые у меня (с Вашей легкой руки) хранятся в коде, это всего лищь константы, описывающие структуру каждого параметра. Сами же параметры разбросаны как угодно, не являясь элементом никакого массива или структуры. Мне кажется удобным...

    Более того, порядок размещения описателей данных в массиве структур apsPar[]вообще не имеет значения, ибо я собираюсь доступаться к элементам массива поиском номера параметра - перебирая индекс, просматривать массив apsPar[] до совпадения с номером параметра в apsPar[i].Numb
    То есть я в любой фазе разработки могу выбросить пару строк или добавить, переставить строки как угодно - и проект не поломается. Я имею в виду строки
    Код:
    set(...);
    set(...);
    Сейчас играюсь с примером доступа по описанным принципам - уже мажется Чуть позже предоставлю пример на строгий суд Учителей. Зачет-то нужен

  4. #4
    Пользователь Аватар для drvlas
    Регистрация
    30.09.2010
    Адрес
    Киев
    Сообщений
    700

    По умолчанию

    Цитата Сообщение от drvlas Посмотреть сообщение
    Сейчас играюсь с примером доступа по описанным принципам
    Вот и работающий пример. Параметры - очень разные. от логических до даты. Указывая на все параметры пойнтером

    Код:
    POINTER TO DWORD
    я часто вытаскиваю кучу всякого мусора, но подчищаю его, как показал Учитель. В результате, если пройти всю программу, мы увидим, что все вспомогательные переменные получили правильные значения.

    Да, для записи без повреждения котельни нужно еще поработать. Там действительно придется полагаться на то, что самый младший байт лежит по адресу переменной, а остальные - по возрастающим адресам. Это не кашерно, но иного пути не вижу. Так что SetPar ждет своего часа...

    З.Ы. И как-то странно у меня складывается с ФБ. Пока не стал записывать
    Код:
    GetPar( by1:=5, X => dw);
    ничего не работало. Т.е. конструкции вида
    Код:
    dw := GetPar( by1:=5).X;
    ну не выполняются и все тут! Вижу нулевое значение вместо Х... Что за Х...
    Вложения Вложения

  5. #5
    Пользователь
    Регистрация
    23.09.2008
    Адрес
    Центророссийск
    Сообщений
    2,264

    По умолчанию

    Цитата Сообщение от drvlas Посмотреть сообщение
    Код:
    GetPar( by1:=5, X => dw);
    ничего не работало. Т.е. конструкции вида
    Код:
    dw := GetPar( by1:=5).X;
    ну не выполняются и все тут! Вижу нулевое значение вместо Х... Что за Х...
    К сожалению проза жизни. Программа не может быть операндом. А фб - это все-таки программа, хоть и с неявной передачей указателя на текущую структуру. Лобби от функций проплатили этот запрет.
    Иначе кому они нужны были б.

  6. #6
    Пользователь Аватар для drvlas
    Регистрация
    30.09.2010
    Адрес
    Киев
    Сообщений
    700

    По умолчанию а зачет???

    Во всяком случае, по GetPar Михалыч не дал по шее.

    Видать, для зачета нужно еще и SetPar показать...

    Я как понимаю на сегодняшний день. Указатели сами по себе есть 32-битные переменные (ну, для ПЛК100 так, во всяком случае). В зависимости от объявления указателя, контроллер вытаскивает данные строго указанной длины -
    Код:
    1 бит для BOOL
    1 байт для BYTE, SINT, USINT
    1 слово для WORD, INT, UINT
    2 слова для DWORD, DINT, DUINT
    строка для STRING (окончание по нулю?)
    иное, если пользовательский тип данных
    При этом способ размещения данных в получаемом значении как-то зафиксирован: по указанном уадресу - младший байт, а затем по возрастающей.
    Аналогично следует размещать данные при записи. Потанцевав, ясен перец, с неразрушением данных в чужих полях (ибо наш универсальный пойнтер указывает на 4-байтный простор, который нужно засеять).

    Хочу еще попробовать просто присваивать пойнтеры разных типов. Если получится, то танцев будет меньше.

    З.Ы. Удивлен экспериментом с битовой переменной. Если пойнтер направить на некое битовое поле, в котором записать "1" не в младший разряд, то по GetPar выдернется, естественно, целый байт. А вот явное преобразование DWORD_TO_BOOL отсекает безжалостно все, кроме младшего бита
    Я-то думал, всякое ненулевое значение целого байта по указанному адресу считается TRUE. А вот нет... Берем на заметку.

  7. #7

    По умолчанию

    Цитата Сообщение от drvlas Посмотреть сообщение
    Т.е. конструкции вида
    Код:
    dw := GetPar( by1:=5).X;
    ну не выполняются и все тут!
    Не путайте прынципиально разные штуки 1 и2:

    1. Вызов экземпляра с одновременным присваиванием данных:

    Код:
    GetPar(by1:=5);
    или просто вызов (со старыми данными)

    Код:
    GetPar();
    2. Чтение/запись переменных экземпляра,
    без вызова его кода:

    Код:
    dw := GetPar.X;
    Это при вызове функции нужно дать все, а ФБ что надо, выборочно. Поэтому приходится писать имена переменных, чтобы компилятор понял чего ему дают.

  8. #8
    Пользователь
    Регистрация
    23.09.2008
    Адрес
    Центророссийск
    Сообщений
    2,264

    По умолчанию

    Drvlas наверное имел ввиду что на нижнем уровне что ф.б., что прог,что функ. :

    ..
    CALL ...
    ...

    И что для ф.б. не сделали из

    X := FB(A := ?).X

    релиз типа :


    ..
    mov FB.A, ? ______________________;A := ?

    push @FB _______________________;FB()
    call привязаная_к_FB_прога

    mov X, FB.X ______________________;X := FB.Х


    А было б неплохо, а ?



    PS
    Замучил этот автосборщик пробелов
    Последний раз редактировалось Валенок; 04.12.2010 в 12:54.

  9. #9
    Пользователь Аватар для drvlas
    Регистрация
    30.09.2010
    Адрес
    Киев
    Сообщений
    700

    По умолчанию

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

    перечел ваш классический труд, п.п. 5.3.2 и 5.3.3. то, что я понял сейчас, никак не противоречит изложенному там, конечно. но там неочевидна разница - обратиться к переменным экземпляра до вызова или после вызова.
    спасибо!

  10. #10
    Пользователь Аватар для drvlas
    Регистрация
    30.09.2010
    Адрес
    Киев
    Сообщений
    700

    По умолчанию о времени

    Готовлю я себе примерчик, отрабатываю даже то, что сейчас не нужно... И наткнулся на такую ругню компилятора:

    Код:
    	toda:		TOD;
    	dat:		DATE;
    ...
    toda := toda + TOD#00:01;
    dat := dat + DATE#0000-00-01;
    На первое присвоение пишет:
    Код:
    Несоответствие операнда 2 в "+": невозможно преодразовать TOD в TOD
    А на второе:
    Код:
    Неверный формат даты
    Несоответствие операнда 2 в "+": невозможно преодразовать DATE в DATE
    Вопрос: как прибавить к дате 1 день? Ко времени суток 1 минуту?
    ИСПРАВЛЕНО: Ко времени дня добавить можно

    Код:
    toda := toda + T#1m;
    А вот к дате... Даже 24 часа не помогают - дает из 2010-12-03 2013-08-29...

    Определил, что

    Код:
    dat := TIME_TO_DATE(T#1d);
    Компилируется нормально и дает 2 января 1970 года. А вот прибавить так 1 день НИЗЗЯ:

    Код:
    dat := dat  + TIME_TO_DATE(T#1d);
    Так что вопрос открытый
    Последний раз редактировалось drvlas; 04.12.2010 в 14:33.

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •