Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.04.21;
Скачать: [xml.tar.bz2];

Вниз

Что это значит? (про указатели)   Найти похожие ветки 

 
Bel   (2003-04-08 16:57) [0]

Сижу ковыряю не свой проект, и вот встретил там такое:
При создании формы в TreeView (имя qtv1) добавляются из базы узлы, причём для TreeNode.Data делается так:

MyTreeNode1 := qtv1.Items.AddObject (qtv1.Selected, SQL1.FieldByName("Name").AsString, Pointer (SQL1.FieldByName("ID").AsInteger));

При развёртывании ветки доступ к полю Data делается так:

var ID: Integer;
Pointer(ID) := Node.Data;


Что-то мне не нравится здесь, а вот что, за малостью опыта, не знаю.
1. Пробовал трассировать. Получается, что Pointer(...) делает из целого 16-ричное значение, т.е. 173->$AD. Получается, что указателя как такового нет, это только для совместимости типов сделано (AddObject третьим параметром принимает Pointer)?
2. Корректно ли употребление Pointer(ID) в левой части выражения?
3. Как ещё можно сделать то же самое?
ID нужно, т.к. по нему потом ищутся потомки для текущей ветки.
PS. Программу писал не профессионал.


 
Кот Бегемот   (2003-04-08 17:04) [1]

1. Downright lie - not 16 bit but 32
2. Yeah - correct
3. Wherefore - all work fine

PS: I see :)))


 
Skier   (2003-04-08 17:04) [2]

>Bel
1) Pointer(SQL1.FieldByName("ID").AsInteger));
здесь - это просто приведение типов Integer -> Pointer,
что является вполне законной вещью.
2)
> Корректно ли употребление Pointer(ID) в левой части выражения?

Вполне. Это тоже приведение типов только в обратную сторону
Pointer -> Integer
3)

> Как ещё можно сделать то же самое?
>ID нужно, т.к. по нему потом ищутся потомки для текущей ветки.

Можно посмотреть вс-ва
TTreeNode.Index и TTreeNode.AbsoluteIndex


 
Skier   (2003-04-08 17:18) [3]

>Bel
2) Плохо подумал !
Правильно так : ID := Integer(Node.Data);


 
Bel   (2003-04-08 17:44) [4]

to Skier:

> Можно посмотреть св-ва
> TTreeNode.Index и TTreeNode.AbsoluteIndex

А как тогда можно сохранить значение ID, оно ведь потом нужно для нахождения всех детей текущего элемента. Там каждый раз при развёртывании ветки происходит её формирование. Т.е. изначально дерево формируется из элементов 1-го уровня (их 3), когда юзер щёлкает на плюсике, в обработчике OnExpanding формируется подветка для текущей. И так далее. Наверное, так сделано чтобы дерево не занимало много памяти (развёрнутое оно большое: 6 уровней, всего 350 элементов).

> Правильно так : ID := Integer(Node.Data);

Попробовал - получилось. Спасибо.
Получается, что поле-указатель используется не по назначению - не указывает куда-то, а содержит просто 16-ричное число, которое потом преобразуется к целому. Так, да?


 
Skier   (2003-04-08 17:54) [5]

>Bel

> Получается, что поле-указатель используется не по назначению
> - не указывает куда-то, а содержит просто 16-ричное число,
> которое потом преобразуется к целому. Так, да?

Да.

> А как тогда можно сохранить значение ID, оно ведь потом
> нужно для нахождения всех детей текущего элемента.

А зачем сохранять ID ? Для нахождения всех детей текущего элемента можно использовать св-ва TTreeNode.Count и TTreeNode.Item[...] c повторением для каждого TTreeNode.Item[...]
Если ID нужно ещё для каких-то хитростей то расскажи зачем...


 
MityaP   (2003-04-08 17:55) [6]

1)
>> MyTreeNode1 := qtv1.Items.AddObject (qtv1.Selected, >>SQL1.FieldByName("Name").AsString,
>> Pointer (SQL1.FieldByName("ID").AsInteger))
Тут все понятно... Для Pointer возвращает, грубо говоря, адрес, куда помещено значение SQL1.FieldByName("ID").AsInteger... Но адрес уже можно передать как объект (объеты передаются по их адресу в памяти)
2)
>> Pointer(ID) := Node.Data
Подменяет адреса...
Вместо пременной ID можно просто использовать нетипизированный указатель, тогда обойдется без такого чуда, как Pointer(ID) := Node.Data, а будет все просто и понятно:
var
p: pointer;
begin
p := Node.Data
....
end


 
Bel   (2003-04-08 18:00) [7]

> Skier © (08.04.03 17:54)

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


 
Bel   (2003-04-08 18:04) [8]

> MityaP © (08.04.03 17:55)

Неправда Ваша, судя по ответам Skier"а, почитайте все ответы. Указателями здесь и не пахнет.


 
MityaP   (2003-04-08 19:57) [9]

to [Bel © (08.04.03 18:00), (08.04.03 18:04)]
1) Сообщение пришло пока я писал... Как отослал - увидел..
2) Skier"а написал зачем это нужно... А что делается в момент Pointer(ID) := Node.Data ничего... Так в этот подменяется адрес, где переменной ID...
Если мы пишем ID := Integer(Node.Data) то ID изменит значени на значение адреса, куда Node.Data ссылается
Если мы пишем Pointer(ID) := Node.Data, то подменяется сам адрес... И если после этого, не дай Бог, положишь в ID что-то (например: ID := 1), то Node.Data похерится и при обращении к нему будет возникать обшибка...


 
Diouzshev   (2003-04-08 20:30) [10]

Почитай http://www.ibase.ru/devinfo/treedb.htm там все расписано.


 
Юрий Зотов   (2003-04-09 01:22) [11]

> MityaP © (08.04.03 17:55)

> 1)
>> MyTreeNode1 := qtv1.Items.AddObject (qtv1.Selected, >>SQL1.FieldByName("Name").AsString,
>> Pointer (SQL1.FieldByName("ID").AsInteger))

> Тут все понятно... Для Pointer возвращает, грубо говоря, адрес,
> куда помещено значение SQL1.FieldByName ("ID").AsInteger...

Принципиально не так. Возвращает обычное беззнаковое целое.


> 2)
>> Pointer(ID) := Node.Data
> Подменяет адреса...

Снова - принципиально не так. Никакие адреса здесь не подменяются, а просто присваивается все то же беззнаковое целое.



> MityaP © (08.04.03 19:57)

> Если мы пишем ID := Integer(Node.Data) то ID изменит значение > на значение адреса, куда Node.Data ссылается

> Если мы пишем Pointer(ID) := Node.Data, то подменяется сам
> адрес...

Зря Вы спорите. Обе конструкции равносильны. В обоих переменная ID получает значение Node.Data в виде 32-битного целого числа.


> И если после этого, не дай Бог, положишь в ID что-то
> (например: ID := 1), то Node.Data похерится и при обращении к
> нему будет возникать обшибка...

А вот это уже совсем напрасно. Переменная ID расположена по своему собственному адресу, а Node.Data - по своему. Они имеют одинаковые значения, ну так и что с того? Запустите Delphi, пройдите отладчиком - все увидите сами.


 
Юрий Зотов   (2003-04-09 01:34) [12]

> Bel © (08.04.03 16:57)

> Что-то мне не нравится здесь, а вот что,
> за малостью опыта, не знаю.
Все там нормально.

> Получается, что указателя как такового нет,
> это только для совместимости типов сделано
Именно так. Просто чтобы не ругался компилятор.

> Корректно ли употребление Pointer(ID) в левой части выражения?
Вполне.

> Как ещё можно сделать то же самое?
Как уже писали: ID := Integer(Node.Data);

> ID нужно, т.к. по нему потом ищутся потомки для текущей ветки.
Хранение в TreeNode.Data, ListItem.Data, Strings.Objects и т.п. ЛЮБОЙ информации размером не более 4-х байт - это вполне обычная практика.

> Программу писал не профессионал.
Профессионал - это всего лишь тот, кто за то же самое получает деньги. Об уровне это еще ничего не говорит. Есть огромное число "любителей", которые гораздо сильнее не менее огромного числа "профессионалов".


 
evvcom   (2003-04-09 02:21) [13]

Когда возникают подобные вопросы, я открываю CPU Window. После некоторой практики и Вам будет многое понятно. Главное - не бояться, а дизассемблер поможет понять многое, особенно, когда программа изобилует указателями и приведениями типов.


 
Bel   (2003-04-09 10:14) [14]

Всем большое спасибо за просвещение. Теперь мне всё понятно.

> Diouzshev © (08.04.03 20:30)

Статья - то, что надо. Спасибо. Оказывается, хранить в Data не указатель, а просто число - это обычная практика.


 
viman   (2003-04-09 10:31) [15]

Профессионал - это всего лишь тот, кто за то же самое получает деньги. Об уровне это еще ничего не говорит. Есть огромное число "любителей", которые гораздо сильнее не менее огромного числа "профессионалов".

Супер! Абсолютно согласен!

А зачем сохранять ID ? Для нахождения всех детей текущего элемента можно использовать св-ва TTreeNode.Count и TTreeNode.Item[...] c повторением для каждого TTreeNode.Item[...]
Если ID нужно ещё для каких-то хитростей то расскажи зачем...


Затем что в элементам в дереве привязываются данные из другой таблицы, или возможно из этой. Ведь id в таблице никак не будет равно index`у в treeview.



 
MityaP   (2003-04-09 15:30) [16]

[Юрий Зотов © (09.04.03 01:22)]
> 2)
>> Pointer(ID) := Node.Data
> Подменяет адреса...

> Снова - принципиально не так. Никакие адреса здесь неподменяются, а просто присваивается все то же беззнаковое целое.
Это понятно, что присваивается беззнаковое целое... и что это принципиально не так (то бишь "Подменяет адреса...")... Но ты сделай так Pointer(ID) := Node.Data; ID := 2.,.
После этого в Node.Data лажа полная... Если быть более точным, там число 2...
Отсюда следствие....


 
MityaP   (2003-04-09 15:37) [17]

> MityP: И если после этого, не дай Бог, положишь в ID что-то
> (например: ID := 1), то Node.Data похерится и при обращении к
> нему будет возникать обшибка...

[Юрий Зотов © (09.04.03 01:22)]:
>А вот это уже совсем напрасно. Переменная ID расположена по >своему собственному адресу, а Node.Data - по своему. Они имеют >одинаковые значения, ну так и что с того? Запустите Delphi, >пройдите отладчиком - все увидите сами.

Думаю ты прав, но действительно херится...!!!...
Возьми вместо Node.Data просто Node... И поэкспериментируй...
После {Pointer(ID) := Node; ID := 1} Node исчезает бесследно!


 
malkolinge(fp)   (2003-04-09 15:43) [18]

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

зы
Писал я ДБ Трее, но в такие дебри не лез, я трее, по отзывам, отличный получился :)


 
Юрий Зотов   (2003-04-09 16:15) [19]

> MityaP

Я, конечно, не поверил, но уж больно уверенно Вы говорили, так что решил все же проверить. Докладываю результаты экспериментов.


> Но ты сделай так Pointer(ID) := Node.Data; ID := 2.
> После этого в Node.Data лажа полная...
> Если быть более точным, там число 2...


Проверил. Ни лажи, ни двойки там нет. Что там было, то и осталось. Как и должно было быть


> После {Pointer(ID) := Node; ID := 1} Node исчезает бесследно!

Проверил. Ничто никуда не исчезло. Дерево каким было - таким и осталось. И точно так же работало. Как и должно было быть.


> Отсюда следствие....

Согласен. И это следствие такое - не вводите людей в заблуждение.
Есть еще и другие следствия, но о них я лучше промолчу. Думаю, сами догадаетесь.


 
MityaP   (2003-04-09 16:31) [20]

[Юрий Зотов © (09.04.03 16:15)]
Видно у меня глюки...
Спасибо, что их обнаружил...
{ Следствие: пора мне полечиться малость... Так и сделаю..}
Thanks


 
MityaP   (2003-04-09 16:38) [21]

[Юрий Зотов © (09.04.03 16:15)]
Да, все нормально... Вчера видно точно меня заклинило...

Всем мое Sorry/!!!\



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.04.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.009 c
1-67381
OlegM
2003-04-10 09:57
2003.04.21
Как любой файл просмотреть в hex


14-67451
Sviat_b
2003-04-04 16:16
2003.04.21
Можно ли безболезненно перейти с Delphi5 на Delphi7 ?


1-67208
_stranger
2003-04-08 20:43
2003.04.21
Каретка


6-67409
Provodnick
2003-02-26 20:08
2003.04.21
Delphi and HTML.


1-67306
Мыш
2003-04-09 02:05
2003.04.21
access violation





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский