Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Data Pointer и все все все... [D7, XP]


Страницы:   1 2

Салат ©   (2007-08-06 19:40:00) 

Мне стыдно но я совсем не умею работать с указателями (Pointers) :( Расскажите в двух словах чайнику как через pointer работать с переменными (желательно на примере, где pointer будет указывать на record если такое возможно. если уж совсем близко то на примере TServerSocket.Socket.Connections[0].Data).


Юрий Зотов   (2007-08-06 23:36:00) [21]

> {RASkov} ©   (06.08.07 23:07) [8]

Да, компилятор Deplhi сам разыменовывает указатели. Любая объектная переменная ведь тоже указатель, поэтому по правилам Паскаля надо было бы писать, строго говоря, так:
Button1^.Caption := 'OK';
Но мы крышку не пишем, компилятор сам разыменовывает Button1.

Чтобы не путаться в своем же коде, я пользуюсь таким правилом: объектные переменные пусть разыменовывает компилятор, а простые (необъектные) указатели разыменовываю сам, по-старинке, явным образом. Это позволяет сразу отличать указатели от других типов переменных и правильно с ними работать (особенно, при использовании данных вида "указатель на указатель", когда требуется многократное разыменование).

> Вообщем с указателями только путаница

Никакой путаницы нет - надо только ОДИН раз понять, что это такое, а потом все будет очень просто. Указатели - штука для серьезного программиста совершенно необходимая (я бы даже сказал сильнее - кто не понимает указателей, того назвать программистом вообще нельзя). Без указателей нвозможно работать с динамической памятью напрямую (а это требуется частенько - например, при использовании многих функций WinAPI). Без понимания указателей нельзя толком понять и многие термины Delphi (длинная строка, динамический массив, объект, класс, VMT... и многое другое). Соответственно, не понимая этого, нельзя с этим и свободно работать - и именно от непонимания указателей бывает и много багов в программах, и много вопросов на форумах.


MetalFan   (2007-08-06 23:24:00) [22]

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


{RASkov}   (2007-08-06 23:07:00) [23]

> [5] MetalFan ©   (06.08.07 22:57)

Собственно... тоже пример по работе с указателями, но не их необходимости :)

Мои посты может быть такие, из-за того, что я панически "боюсь" их(указатели) :) И без надобности их не трогою....

Кстати вопрос по ним, если можно задам здесь в тему.... вот из [3]
Last ^.S := 'Элемент номер ' + IntToStr(Last ^.I);
Вот эти выделенные "крыши" - они непосредственно необходимы в данном месте или только для лучшего понимания, что есть что ??
Так как
Last.S := 'Элемент номер ' + IntToStr(Last.I);
Результат тот же....
"Крыша" - разыменование указателя, это я знаю..... Делфи наверняка, если их(крыши) не ставить, сама их подставляет, так?
Вообщем с указателями только путаница :)


Юрий Зотов   (2007-08-06 23:07:00) [24]

> Салат   (06.08.07 22:48) [4]

В Вашем варианте указатель вовсе не нужен:
ShowMessage(clients[1].data);
И без всяких указателей.

Вообще, указатель - это просто-напросто переменная, которая содержит в себе адрес , только и всего. Если значение указателя равно nil, то это значит, что он пустой (то есть, не содержит в себе никакого адреса). Ничего сложного.


{RASkov}   (2007-08-06 22:57:00) [25]

> [4] Салат   (06.08.07 22:48)

В данном примере никакого смысла нет в указателях....
И вообще указатели лучше не использовать, если нет на то особой необходимости. См пример из [3]
type
PData = ^TData; // Тип указателя на элемент стека
TData = record // Тип элемента стека
  I: integer; // Данные элемента
  S: string;  // Еще данные элемента
  Prev: PData; // Указатель на предыдущий элемент <----------- Иначе никак, а то можно было б лучше так Prev: TData
end;


MetalFan   (2007-08-06 22:57:00) [26]

хм... я раньше тоже не понимал) но однажды понял... но вот на пальцах объяснить не могу..
единственное, что в голову приходит: Pointer - это в общем случае просто 4 байта в памяти, "указывающие" на какую-либо область памяти или на nil...
к примеру:
type
 TRec = record
   Int: Integer;
   W: Word;
   Str: string;
 end;

procedure Proc;
var
 lInt: Integer;
 lStr: string;
 lRec: TRec;
 lPtr: Pointer;
begin
 lInt := 10;
 lPtr := @lInt;
 Integer(lPtr^) := 20;//изменили значение lInt
 lStr := 'string';
 lPtr := @lStr;
 string(lPtr^) := 'asd';// изменили значение lStr;
 lRec.Int := 100;
 lRec.W := 1;
 lRec.Str := 'sadssd';
 lPtr := @lRec;
 TRec(lPtr^).Int := 1;
 TRec(lPtr^).W := 2;
 TRec(lPtr^).Str := 'nnn';
end;


Салат   (2007-08-06 22:48:00) [27]

Спасибо, разобрался кое как :) вкривь и вкось сделал на массивах, но зато надежно, просто и работает. Для таких же как я может пригодится мой опыт:
TRecord = record
data: String[255];
end;

var
p: Pointer;
clients: array[0..2] of TRecord;

begin
p := @clients[1]; // связываем указатель с каким-то элементом массива
ShowMessage(TRecord(p^).data); // доступ к этому элементу
end;


Юрий Зотов   (2007-08-06 22:33:00) [28]

Построение стека записей:

type
 PData = ^TData; // Тип указателя на элемент стека
 TData = record // Тип элемента стека
   I: integer; // Данные элемента
   S: string;  // Еще данные элемента
   Prev: PData; // Указатель на предыдущий элемент
 end;

var
 Last: PData = nil; // Указатель на верхний элемент стека (пока пустого).

proсedure Push; // Создать новый элемент и затолкнуть его в стек.
var
 P: PData;
begin
 New(P); // Создали в динамической памяти новый элемент по адресу P.
 P^.Prev := Last; // Разместили новый элемент на вершине стека.
 Last := P // Протолкнули стек.
end;

proсedure Pop; // Вытолкнуть из стека верхний элемент и уничтожить его.
var
 P: PData;
begin
 if Last = nil then // Если стек пустой, то ничего делать не надо.
   Exit;
 P := Last; // Запомнили адрес верхнего элемента.
 Last := Last^.Prev; // Вытолкнули верхний элемент из стека.
 Dispose(P); // Освободили память, которую он занимал.
end;

procedure Clear; // Очистить стек и освободить всю занимаемую им память.
begin
 while Last <> nil do
   Pop
end;

var
 i: integer;
begin
 // Создать стек из 10 элементов
 for i := 0 to 9 do
 begin
   Push;
   Last^.I := i;
   Last^.S := 'Элемент номер ' + IntToStr(Last^.I);
 end;
 // Уничтожить стек
 Clear
end;


JanMihail   (2007-08-06 22:04:00) [29]

Сам толком не поинмаю, что за Pointer


JanMihail   (2007-08-06 21:58:00) [30]

type
 MyRecord = record
    str1: String[255];
    str2: String[255];
    i     : Integer;
end;

var
 Form1: TForm1;
 a: MyRecord;
 p: Pointer;

procedure TForm1.FormCreate(Sender: TObject);
begin
 p := @a;
end;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо