Текущий архив: 2004.07.11;
Скачать: CL | DM;
Вниз
SwapMemory Найти похожие ветки
← →
Кастуся (2004-06-27 23:06) [0]мастаки! недавно узнал, что есть функция CopyMemory? Может есть подобная SwapMemory, которая эти блоки меняет местами? В принципе и самому реализовать можно, но мот кто делал уже?
← →
jack128 © (2004-06-27 23:14) [1]
> недавно узнал, что есть функция CopyMemory
молодец ;-)
> В принципе и самому реализовать можно, но мот кто делал
> уже?
я делал.
← →
Ломброзо © (2004-06-28 00:53) [2]Интересно, что проще - Магомета к горе привести или гору к Магомету? Если есть два задействованных кусочка памяти, значит, есть и два указателя на неё? Может, указатели местами поменять?
← →
jack128 © (2004-06-28 01:13) [3]
> Может, указатели местами поменять?
не всегда. Если это ЕДИНСТВЕННЫЕ указатели на эту область памяти, то да.. А если таких указателей по программе раскиданно вагон и маленькая тележка, то тяжко это будет...
← →
Mim1 © (2004-06-28 03:13) [4]
> [3] jack128 © (28.06.04 01:13)
>
> > Может, указатели местами поменять?
> не всегда. Если это ЕДИНСТВЕННЫЕ указатели на эту область
> памяти, то да.. А если таких указателей по программе раскиданно
> вагон и маленькая тележка, то тяжко это будет...
Можно сделать чтобы вагон указателей указывали на указатель указывающий на данные.
Каламбурчик. :)
← →
Кастуся (2004-06-28 10:34) [5]Ну, огрехи будут?
procedure SwapMemory(b1,b2:pointer;l:Cardinal);
var
p:pointer;
begin
getmem(p,l);
MoveMemory(p,b1,l);
MoveMemory(b1,b2,l);
MoveMemory(b2,p,l);
freemem(p,l);
end;
← →
default © (2004-06-28 10:40) [6]Кастуся (28.06.04 10:34) [5]
ну это очень тупо, см. [2] и [4]
← →
jack128 © (2004-06-28 10:57) [7]
> Кастуся (28.06.04 10:34) [5]
> ну это очень тупо, см. [2] и [4]
смотря как и где ;-) Давайте соизмерять усилия которые мы прилагаем для решения задачи с важностью задачи ;-) Так мудро как ИШ про овощи мне не сказать :-)
Чтобы сделать как [4] может потребоваться всю прогу переписать.. А может и нет. Тут Кастуся сам(а) будет решать..
> Ну, огрехи будут?
в начале тест на перекрывающие области
if abs(Integer(b1) - Integer(b2)) < l then
raise Exception.Create("Блоки памяти перекрываются");
ЗЫ и старайся не использовать идентификатор "l" - с единицей сливается..
← →
default © (2004-06-28 11:02) [8]jack128 © (28.06.04 10:57) [7]
думаешь мен-ер памяти Delphi "перекрыв-ся указ-ли" может "производить"?только если они самопальные)
проверка не нужна
← →
КаПиБаРа © (2004-06-28 11:26) [9]Проверка нужна, но Exception генерировать не надо. Можно копировать перекрывающиеся блоки без проблем.
← →
Тимохов © (2004-06-28 11:57) [10]зачем пользоваться movememory: если мне не изменяет память move работает быстрее (опять же если не ошибаюсь).
← →
Кастуся (2004-06-28 23:09) [11]
> Ломброзо © (28.06.04 00:53) [2]
> Интересно, что проще - Магомета к горе привести или гору
> к Магомету? Если есть два задействованных кусочка памяти,
> значит, есть и два указателя на неё? Может, указатели местами
> поменять?
Вперед. Действуй. Вот тебе два integer"а поменяй местами указатели на их "содержимое". У меня что-то не получается!
> jack128 © (28.06.04 10:57) [7]
> сам(а) будет решать
сам
← →
jack128 © (2004-06-28 23:22) [12]
> думаешь мен-ер памяти Delphi "перекрыв-ся указ-ли" может
> "производить"?только если они самопальные)
> проверка не нужна
именно.
> Вперед. Действуй. Вот тебе два integer"а поменяй местами
> указатели на их "содержимое". У меня что-то не получается!
? а в чем проблема?
var
i1: Integer = 100;
i2: Integer = 200;
procedure TForm1.Button1Click(Sender: TObject);
var
p1, p2: PInteger;
P: PInteger;
begin
p1 := @i1; p2 := @i2;
ShowMessage(Format("i1 = %d, i2 = %d", [p1^, p2^]));
p := p1; p1 := p2; p2 := p;
ShowMessage(Format("i1 = %d, i2 = %d", [p1^, p2^]));
end;
← →
Игорь Шевченко © (2004-06-28 23:27) [13]Я, если честно, не понимаю, зачем и что надо менять местами. Если содержимое двух областей памяти, на которые что-то указывает, пусть даже по всех программе, то есть классический способ обмена через третью область, равную по величине. Но в любом случае лкчше оперировать указателями, и не разбрасывать их по всей программе, а держать в одном месте. :)
← →
Кастуся (2004-06-29 09:46) [14]нет надо, чтобы именно i1 и i2 после обмена содержали 200 и 100 соответственно, а не p1 и p2!!!
← →
Sandman25 © (2004-06-29 09:49) [15][14] Кастуся (29.06.04 09:46)
i1: PInteger :)
← →
SammIk © (2004-06-29 10:06) [16]2[10]
С чего ты взял?
А так быстрее?xor ecx,ecx
rep1:
mov eax,mem1[eax+ecx*4]
mov mem2[edx+ecx*4],eax
inc ecx
jmp rep1;
:))))
Всего хорошего, но оптимальныи вариант,для большинства задач,
менять указатели. Скорость возрастает огого^^^^^
← →
Кастуся (2004-06-29 11:08) [17]
> Sandman25 © (29.06.04 09:49) [15]
> [14] Кастуся (29.06.04 09:46)
>
> i1: PInteger :)
нет:
> var
> i1: Integer = 100;
> i2: Integer = 200;
>
> ...
> var
> p1, p2: PInteger;
← →
Кастуся (2004-06-29 11:11) [18]
> Всего хорошего, но оптимальныи вариант,для большинства задач,
> менять указатели. Скорость возрастает огого^^^^^
ну так поменяйте! Надо, чтобы
> var
> i1: Integer = 100;
> i2: Integer = 200;
а после некоторых махинаций i1 и i2 содержали 200 и 100 соответственно
← →
Defunct (2004-06-29 11:42) [19]Кастуся (29.06.04 11:08) [17]
Кастуся (29.06.04 11:11) [18]
вывод: Кастуся просто не понимает значения слова "указатель".
← →
Defunct (2004-06-29 11:43) [20]hm.. a где делся мой копирайт?
← →
SammIk © (2004-06-29 11:50) [21]2[18]
Вы, дорогая, путаете понятиЯ.
Указатель это переменная типа DWORD, которая указывает на область памяти, где эти вашии
лежат, а не сами они.
← →
Кастуся (2004-06-29 13:07) [22]
> SammIk © (29.06.04 11:50) [21]
пошла в ... дорогая, сама ты дорогая.
> Кастуся (28.06.04 23:09) [11]
>
> > jack128 © (28.06.04 10:57) [7]
> > сам(а) будет решать
>
> сам
!!!
← →
Кастуся (2004-06-29 13:11) [23]короче. есть массив
a:array[1..2] of integer;
a[1]:=1;
a[2]:=2;
- очень сильно упрощаю.
необходимо после некоторых махинаций сделать,
чтобы
a[1]:=2;
a[2]:=1;
!!!
не используя дополнительной integer переменной!
что-то типа такого, только чтобы верно было:
var
p:pointer;
begin
p:=@a[1];
@a[1]:=@a[2];
@a[2]:=p;
end;
← →
Erik1 (2004-06-29 14:30) [24]Можно на ASM использовать регистер.
Move a, EAX
Move b, a
Move EAX, b
Так подойдет? И вобще о чем спор, из темы непоятно.
← →
ZiRoCool (2004-06-29 14:43) [25]>>var
>>p:pointer;
>>begin
>>p:=@a[1];
>>@a[1]:=@a[2];
>>@a[2]:=p;
>>end;
ну это конечно тупость :)
я лично не представляю как через указатели поменять переменные, не трогая самих переменных!
>>короче. есть массив
>>a:array[1..2] of integer;
>>a[1]:=1;
>>a[2]:=2;
ну а это осуществить просще некуда
даже
>>не используя дополнительной integer переменной!
← →
ZiRoCool (2004-06-29 14:44) [26]от блин, Erik1, на 13 сек мя опередил!
← →
ZiRoCool (2004-06-29 14:46) [27]от блин, Erik1, на 13 сек мя опередил!
НО, можно сделать даже так, чтобы не использовать ВООБЩЕ дополнительной памяти и регистров. этот же закон справедлив для ЛЮБЫХ данных(строк, чисел и т.д.). а терь мне скажи, как ты в регистр свой EAX поместиш строку типа "HelloWorld" (указатели не предлагать!)?
← →
Mim1 © (2004-06-29 14:46) [28]Немного не к тему но.
Школьная задача на смекалку.
Есть две числовых переменных a = 10 и b = 20. Переменые типа байт. Как поменять значения этих переменных местами?
решение
a := a + b;
b := a - b;
a := a - a;
:)
Может вас это интересует?
← →
ZiRoCool (2004-06-29 14:49) [29]Erik1, не move, а mov ;)
← →
ZiRoCool (2004-06-29 15:03) [30]Mim1, а если немного в эту проблему углубиться, можно нечто по лучче вывести, например таким же принцыпом можно поменять местами переменные типа string, тока подумать нада :)
← →
Mim1 © (2004-06-29 15:12) [31]
> [30] ZiRoCool (29.06.04 15:03)
Думается что при существующем алгоритме думать совсем не надо, учитывая еще и то что у чтроки практически недосигаемый верхний барьер. Однако для строк такой код приведет к неявному выделению памяти.
← →
ZiRoCool (2004-06-29 15:19) [32]Mim1, на счёт выделения ты может и прав, НО
попробуй поменять местами две переменные типа байт со значениями 255 и 1 :), как нистранно появится ошибка переполнения.
но есть более гибкий алгоритм, применимый к любым данным, любой длинны, не зависимо от самих данных:a = a xor b;
b = a xor b;
a = a xor b;
и усё! и описаная мною выше ситуация, как в сказке не вызвала ошибку :)
← →
Кастуся (2004-06-29 16:44) [33]
> ZiRoCool (29.06.04 14:43) [25]
> >>var
> >>p:pointer;
> >>begin
> >>p:=@a[1];
> >>@a[1]:=@a[2];
> >>@a[2]:=p;
> >>end;
> ну это конечно тупость :)
так конечно. я же и говорю ,что этот код не катит!
а если есть масси из строк? как тама поменять местаим строки?
← →
SammIk © (2004-06-29 17:47) [34]2[Кастуся] Делаем выводы, если не дорогая, значит дешовая..
Ну это так, размышление.....
А чем тебе указатели не нравятся?
← →
Digitman © (2004-06-29 17:48) [35]
> Кастуся (29.06.04 13:11) [23]
> короче. есть массив
> a:array[1..2] of integer;
> a[1]:=1;
> a[2]:=2;
> - очень сильно упрощаю.
> необходимо после некоторых махинаций сделать,
> чтобы
> a[1]:=2;
> a[2]:=1;
> !!!
> не используя дополнительной integer переменной
нет уж, давай-ка не упрощай ... каждая конкретная задача имеет одно или более строго определенных решений, универсальных решений нет и быть не может
конкретно в данном случае решение может выглядеть, например, так
p: PInteger; //это не integer !! это просто некий указатель
New(p);
p^ := a[1];
a[1] := a[2];
a[2] := p^;
Dispose(p);
как видишь, это полностью удовлетворяет условию "дополнительной integer переменной" полностью работоспособно
← →
ZiRoCool (2004-06-30 19:43) [36]Digitman, хех, ну прикольнул :)
>>p: PInteger; //это не integer !! это просто некий указатель
>>New(p);
это да, НО этот указатель то какраз и указывает на ту самую нежелательную ДОПОЛНИТЕЛЬНУЮ INTEGER ПЕРЕМЕННУЮ ;))))))))
← →
ламер © (2004-06-30 19:57) [37]> ZiRoCool (30.06.04 19:43) [36]
New(P) не создаёт никаких переменных. нет идентификатора - нет переменной.
← →
ZiRoCool (2004-06-30 19:59) [38]ламер, переменная создаётся, только ДИНАМИЧЕСКИ, под неё выделяется память
Страницы: 1 вся ветка
Текущий архив: 2004.07.11;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.038 c