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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.038 c
15-1138008330
Ega23
2006-01-23 12:25
2006.02.12
Какой текст сообщения должен быть?


2-1138023621
K_Lock
2006-01-23 16:40
2006.02.12
Новая запись в базу. Помогите разобраться.


15-1138064297
Andy BitOff
2006-01-24 03:58
2006.02.12
BDS 2006


2-1138275738
Андр
2006-01-26 14:42
2006.02.12
Как преобразовать строку из UTF-8 в WIN-1251


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





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский