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

Тема: POINTER TO what?

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

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1
    Пользователь
    Регистрация
    23.09.2008
    Адрес
    Центророссийск
    Сообщений
    3,177

    По умолчанию

    Начнем с простого:
    ... Пойду удавлюсь.
    Когда лопнет веревка, открываем литературу по ЛЮБЫМ языкам программирования, и изучаем типы, типытипы(и особенно - их размеры)
    Не забываем что pointer - сам по себе тоже тип.

    А pointer to что-то :

    1.Директива компилятору - как использовать бессмысленный набор байтов по указанному адресу.
    2.Вытекает из 1. и (ВНИМАНИЕ !) какое кол-во этих байтов


    Ошибка 1. (Толстая)
    pDWsour := ADR(W); (* Source is wrong *)
    ...
    pDWdest := ADR(DW2); (* Destin is right *)
    ...
    pDWdest^ := pDWsour^ +1; (* DW <= W, fetch throu pDW *)
    pDWdest^:= word_to_dword( dword_to_word( pDWsour^)) +1;
    (word_to_dword конечно же избыточен,но показывает ход преобразований)
    или проще
    := ( pDWsour^ and 16#0000_FFFF ) + 1;


    Ошибка 2. (Тоньше 1.)

    VAR
    ......
    W4: WORD;
    pWsour: POINTER TO WORD;

    pWdest: POINTER TO WORD;
    END_VAR

    pDWsour := ADR(W); (* Source is wrong *)
    pWsour := ADR(DW);
    pWdest := ADR(DW4); (* Destin is wrong *)
    pDWdest := ADR(W4);
    pDWdest^ := pDWsour^ +1; (* W <= W throu pDW *)
    Опс. Здесь мы гробим pWsour. (Понятно как ?)
    И в :
    pWdest^ := pWsour^ +1; (* DW <= DW throu pW *)
    Пытаемся прочитать х.з. откуда, что иногда приводит к :

    Доступ по несуществующему адресу. ПЛК остановлен
    (Слава Богу, что мы не управляли котельней!)
    Её-то Михалыч отремонтирует. А если б а.реактором ?
    И если приспичило :

    pDWdest^[/U] := pDWsour^ +1
    то придется применять проктологические методы

    pDWdest^ := ( pDWdest^ and 16#FFFF_0000 ) or ( ( pDWsour^ + 1 ) and 16#0000_FFFF );

    Сможете пояснить смысл этого действа ?



    PS
    Взяли на понт. Остались детки без подарков .......
    Последний раз редактировалось Валенок; 01.12.2010 в 19:04.

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

    По умолчанию

    Спасибо, уважаемый Учитель! Проясняется... Или это похмел проходит?
    Цитата Сообщение от Валенок Посмотреть сообщение
    Ошибка 1. (Толстая)
    ...
    Ошибка 2. (Тоньше 1.)
    Смысл ошибок понятен, хотя натолкал-то я их специально, в тщетной надежде, что прокатит использование пойнтера на длинный тип данных при обращении и к коротким типам (о своей задаче ЩАС расскажу чуть подробнее).
    Цитата Сообщение от Валенок Посмотреть сообщение
    И если приспичило :
    то придется применять проктологические методы
    Код:
    pDWdest^ := ( pDWdest^  and  16#FFFF_0000 ) or  ( ( pDWsour^ + 1 ) and  16#0000_FFFF );
    Сможете пояснить смысл этого действа ?
    Думаю, что да, Учитель. Надеясь на определенный способ расположения многобайтных данных в памяти, мы пер анус обращаемся к ним "по частям" и "склеиваем" части. Только ты впиндюрил ошибочку, ИМХО. Надо
    Код:
    pDWdest^ := ( pDWsour^  and  16#FFFF_0000 ) or  ( ( pDWsour^ + 1 ) and  16#0000_FFFF );
    Верно?
    И, конечно же, это не есть гут. Ибо в хороших переносимых программах не привязываются к таким особенностям реализации (расположения в памяти).

    Цитата Сообщение от Валенок Посмотреть сообщение
    PS
    Взяли на понт. Остались детки без подарков .......
    Это судьба Русского Учителя, уважаемый. Космонавтов учит, премьер-министрам сопли вытирает, а сам в рваных штанах
    Неси свой крест! Мы тобой восхищены!

    А теперь постараюсь пояснить, почему мне изощрения, ИМХО, не помогут. Дело в том, что я собираюсь не знать при исполнении, каковы же реально типы данных под пойнтером... Но это заслуживает отдельного поста. ЩА СДЕЛАЕМ...
    ...барабанная дробь...

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

    По умолчанию вот откуда вопрос-то взялся

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

    Сами по себе, это данные разных типов:
    - флаги отдельных свойств (ну, там можно BYTE юзать);
    - короткие пременные, тоже однобайтных хватает;
    - длинные переменные, как со знаком, так и без, некоторые требуют аж 4-х байт;
    - временнЫе данные, такие как время, дата, длительность разных пауз и задержек (до десятков секунд);
    - флоаты тоже. по сути работают. но я их постараюсь убрать и в качестве параметров не использовать.

    Эти данные имеют разные изменяемости:
    - неизменяемые переменные (типа номер версии ПО, задается при компилировании);
    - изменяемые программой, но не оператором (например, результат измерения или фаза работы);
    - изменяемые оператором и-или программой, но с разной "разрешительной системой", например, изменяемые только с кодом доступа или как попало;

    Эти данные еще имеют и разные свойства в смысле сохраняемости. Часть из них должна быть RETAIN, для остальных это бессмысленно. Часть параметров сохраняется вообще не в ПЛК, а в другом узле сети.
    Ну, и другие мелкие различия в порядке их редактирования, автоматического изменения и прочее - этим, скорее всего, придется пожертвовать ради великой Цели.

    А Цель такова: сделать работу с просмотром и редактированием параметров в одном участке кода. То есть, работать с параметром при его редактировании по его индексу. И все. Остальное предполагается извлекать из структуры PARSCRIPT, в которой есть вся необходимая инфо.
    В старом проекте (не на ПЛК) были просто огромные SWITCH-и и на каждый параметр свой CASE. Но там хоть привычная форма представления программ, в человеческих редакторах. В КОДЕСИС же (при всем уважении!) работать с огромными текстами неудобно.
    Да и вообще, считайте это моим капризом. "Хочу иконки, несмотря на социализм"

    Для реализации Цели я создаю такие элементы:

    1. Описание параметров.

    Код:
    TYPE PARSCRIPT :
    STRUCT
    	Numb:		BYTE;	(* Номер параметра по ЭД, 0...255 *)
    	Point:		BYTE;	(* Формат вывода: 0, 1, 2, 3 знака справа от точки *)
    	Mdf:		BYTE;	(* 0 prog RO, 1 user RO, 2 RW, 3 R(W в СТОПЕ), 4 R(W с паролем) *)
    	Node:		BYTE;	(* Место хранения параметра, 0 - в ПЛК, 1 - в ТП *)
    	Mini:		DINT;	(* Границы значения параметра *)
    	Maxi:		DINT;
    	Ptr:		POINTER TO DINT;(* Указатель на параметр *)
    	Name:		STRING(10);	(* Текст имени *)
    END_STRUCT
    END_TYPE
    2. Массив структур размером с количество параметров:

    Код:
    VAR_GLOBAL
    	apsPar: ARRAY [0..MAX_PAR_NMB] OF PARSCRIPT;
    END_VAR
    Этот массив с помощью функции set, подсказанной Учителем, заполняю при старте константами. В том числе, на место Ptr записываю адреса переменных-параметров:

    в фунции set есть строка

    Код:
    apsPar[ iParIndx].Name	:= Name;
    и функция вызывается многократно, на все параметры:

    Код:
    set( 101,	2,	0,	0,	0,	9999,	ADR(Dummy),			'Версия ПЛК');
    set( 102,	2,	0,	0,	0,	9999,	ADR(Dummy),			'Версия ТП');
    set( 103,	0,	4,	0,	1,	31,	ADR(_103_Addr_IP),		'Адр с ИП');
    set( 104,	0,	4,	0,	0,	5,	ADR(_104_Baud_IP),		'Скор с ИП');

    3. Собственно параметры, разных типов, сохраняемые и нет:

    Код:
    VAR_GLOBAL RETAIN
    (* Сохраняемые  П А Р А М Е Т Р Ы  работы ПЛК *)
    	_103_Addr_IP:	BYTE := 1;	(*Адрес для работы с ИП320 *)
    	_104_Baud_IP:	BYTE := 5;	(*Код 0-5 скорости работы *)
    ...
    (* Конец области задания П А Р А М Е Т Р О В *)
    END_VAR
    
    VAR_GLOBAL
    (* Не сохраняемые П А Р А М Е Т Р Ы  работы ПЛК *)
    	_120_ADC:		DINT;		(* Код АЦП *)
    	_170_Phase:		BYTE;		(* Фаза работы *)
    ...
    	_185_Time2Unld:	TIME;			(* Время до разгрузки *)
    	_186_Errors:		WORD;		(* Слово ощибок (аварий) *)
    (* Конец области задания П А Р А М Е Т Р О В *)
    END_VAR
    Дальше я еще не написал, т.е. все неприятности по поводу чтения и редактирования параметров оператором - впереди.
    Но уже сейчас понятно, что объявление в PARSCRIPT

    Код:
    Ptr:	POINTER TO DINT;	(* Указатель на параметр *)
    вызовет проблемы для тех параметров, которые вовсе не DINT.

    Как же быть? Как доступаться к параметрам, имея на руках только указатель, если параметры разные по типам?
    Последний раз редактировалось drvlas; 02.12.2010 в 11:11.

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

    По умолчанию

    Понесу свой крест.

    Не-а, милок. Как проктолог проктологу :

    pDWdest^ := ( pDWdest^ and 16#FFFF_0000 ) or ( ( pDWsour^ + 1 ) and 16#0000_FFFF );

    Именно pDWdest.

    Прежде чем что-то влить по адресу pDWdest^, а там ведь своё - только первое слово, ведь :

    pDWdest := ADR(W4)) ,

    а вливаться по pDWdest^ := будет дабл-слово,

    И чтоб не запороть там чужие данные ( (pDWdest+2)^ ), надоть оттуды их выковырнуть (старшее слово) :

    ( pDWdest^ and 16#FFFF_0000 )....

    А опосля, впихнуть его без изменений во вновь образуемое дабл-слово, похерив возможное переполнение первого слова в :

    pDWsour^ + 1

    т.е. :

    .... or ( ( pDWsour^ + 1 ) and 16#0000_FFFF );

    (Ессно, or можно поменять на +, характер образуемых здесь битовых полей никогда не приведет к переполнению)

    PS
    Пока незачот.

    Остальное посмотрю попозже. Щас спешу.
    Последний раз редактировалось Валенок; 02.12.2010 в 11:55.

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

    По умолчанию

    Цитата Сообщение от валенок Посмотреть сообщение
    пока незачот.
    котельне 3.14-здец... ждем михалыча

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

    По умолчанию

    Шнурую ботинки ...


    Как доступаться к параметрам, имея на руках только указатель, если параметры разные по типам?

    -Петька, прибор !!
    -100 !!
    -Чё 100 ?
    -А чё прибор.


    Сообщите про тип, например :


    struct tType
    ( tReal, t.... );


    function ...
    var_input
    typ : tType;
    ...


    А как вы думаете работает, например бейсик там, или лисп.

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

    По умолчанию

    to drvlas

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

    И чисто совет.
    Используйте перечисления. Чем меньше чисел, тем меньше ошибок.
    Зачем вам :

    .......Point:BYTE; (* Формат вывода: 0, 1, 2, 3 знака справа от точки *)

    Пишите, например :


    ......OutFormat : ( Format0, Format1, Format2......);

    Во-первых меньше дурацких комментариев (не при объявлении, а далее по коду), без потери наглядности.
    Во-вторых, присвоение
    OutFormat := Format2 - более осмысленно, чем Point := 2; (хотя - дело вкуса)

    В третьих, код легче модифицировать
    Последний раз редактировалось Валенок; 02.12.2010 в 23:02.

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

    По умолчанию

    советы по поводу перечислений - понятно. иногда делаю, иногда нет. но согласен со всеми аргументами.

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

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

    и думаю: что это учитель мне про список говорит? это он на русском языке вообще? моя твоя не панимай...

Ваши права

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