Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.12;
Скачать: CL | DM;

Вниз

Как сделать на дельфи...   Найти похожие ветки 

 
igi   (2006-01-15 11:20) [0]

В С++ код выглядит так:
int a;
int *p;
int x = 0;

p = malloc(BLOCK_SIZE);
for (a = 0; a < BLOCK_SIZE; a += sizeof(int))
 x += *(int *)((char *)p + a);


Пытаюсь перевести в Дельфи:

     var
       x, a : integer;
       p: ^integer;
    begin
       x := 0;
       GetMem(p, BLOCK_SIZE);
       for a:=0 to BLOCK_SIZE - 1 do
       x := x + p[a];
    end;


Но ошибка в p[a], ка кделать правильно?


 
begin...end ©   (2006-01-15 11:32) [1]

Странный какой-то код...

var
 a, x: Integer;
 p: PInteger;
begin
 x := 0;
 GetMem(p, BLOCK_SIZE);
 a := 0;
 while a < BLOCK_SIZE do
 begin
   x := x + PInteger(Cardinal(p) + a)^;
   Inc(a, sizeof(Integer))
 end
end


 
igi   (2006-01-15 11:39) [2]

спасибо большое, просто с этими указателями не сталкивался никогда


 
igi   (2006-01-15 11:45) [3]

А, прокомментируйте пожалуйста строку PInteger(Cardinal(p) + a)^;

Я щас просто читаю книгу Криса Касперски, Оптимизация программ... так вот, чтоб лучше понимать хочу опробовать все присмеры на дельфе...


 
begin...end ©   (2006-01-15 11:50) [4]

> igi   (15.01.06 11:45) [3]

Прокомментирую. Только сначала, пожалуйста, прокомментируйте, что  призван делать код из [0] (и, следовательно, из [1]).
:о)

Выделяется неинициализированная область памяти, она рассматривается как массив целых значений, вычисляется сумма этих (фактически, случайных) значений. Зачем это?
:о)


 
igi   (2006-01-15 11:58) [5]

Код на С это из примера к главе Эффективность разворачивания циклов читающих память. Я так понял он читает всю выделенную память.

Этот x += *(int *)((char *)p + a);
пример с примеров с диска, а в книге тело цикла выглядит так
x += *(int *)((int)p + a );


 
begin...end ©   (2006-01-15 12:20) [6]

> igi   (15.01.06 11:58) [5]

> Я так понял он читает всю выделенную память.

Я тоже так понял. Только не понял, зачем.
:о)

Переменная p после успешного вызова malloc (или GetMem) представляет собой указатель на начало выделенного блока памяти (размером BLOCK_SIZE). Указатель, по сути дела -- это целое значение, адрес в памяти процесса. В коде [0] выделенный непрерывный блок памяти рассматривается как массив четырёхбайтовых целых чисел (вообще говоря, так считать корректно только в случае, если BLOCK_SIZE кратно 4), и находится сумма этих чисел. Как прочитать очередной элемент этого массива? Каждый следующий элемент массива находится в памяти на 4 байта "правее", чем предыдущий (т.е. его адрес на 4 больше, чем у предыдущего). Значит, нужно к указателю на предыдущий элемент прибавить 4, а потом разыменовать указатель. Поскольку напрямую арифметические операторы к указателям неприменимы, приходится обходить это с помощью приведения типов. В строке PInteger(Cardinal(p) + a)^ к началу блока памяти Cardinal(p) прибавляется нужное число a (для чтения первого элемента -- 0, для чтения второго -- 4, и т.д.), затем полученный указатель разыменовывается PInteger(...)^.

В Delphi быстрее (да и корректнее) будет работать такой код:

var
 x, i: Integer;
 p, t: PInteger;
begin
 GetMem(p, BLOCK_SIZE);
 t := p;
 x := 0;
 for i := 1 to BLOCK_SIZE div sizeof(Integer) do
 begin
   x := x + t^;
   Inc(t)
 end
end


 
igi   (2006-01-15 12:40) [7]

спасибо за объяснение, кой что понял. Осталось понять что значит вот это значек в конце ^, и что такое разыменовывается ?


 
Fay ©   (2006-01-15 12:42) [8]

2 igi   (15.01.06 12:40) [7]
> и что такое разыменовывается
получается_значение_по_адресу_указателя


 
igi   (2006-01-15 12:46) [9]

2Fay ©   (15.01.06 12:42) [8]
Ааааа.... понятно, спасибо, теперь все стало на свои места :)



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

Текущий архив: 2006.02.12;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.044 c
1-1137354346
2Wish
2006-01-15 22:45
2006.02.12
List Index out of bounds


8-1125641317
palgen
2005-09-02 10:08
2006.02.12
Как поменять разрешение ?


15-1138103841
ZMRaven
2006-01-24 14:57
2006.02.12
WB и его проблемы


15-1137675762
ilya39
2006-01-19 16:02
2006.02.12
Замена символов


15-1138020310
dan317
2006-01-23 15:45
2006.02.12
список раскрывающихся абзацев : посоветуйте компонент