Форум: "Основная";
Текущий архив: 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.036 c