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

Вниз

хитрый массив   Найти похожие ветки 

 
race1   (2004-07-28 18:12) [0]

я хочу перевернуть массив наоборот, т.е. [1, 2, 3] превратить в [3, 2, 1]. т.к. это действо встречается часто, задумал я это дело в процедуру вынести

процедура принимает аргументом адрес переменной (байты которой являются элементами массива), и устанавливает адрес локального массива процедуры переданному адресу. т.е.


procedure proc(pnt: Pointer);
type
 TMyArray = Array of Byte;
 PMyArray = ^TMyArray;
var
 MyArrayP: PMyArray;
 MyArray: TMyArray;
begin
 MyArrayP := pnt;
 MyArray := MyArrayP^;
...

но дальше все действия с MyArray"ем приводят к ошибке. а почему?


 
Fay ©   (2004-07-28 18:28) [1]

Всё то же самое, только без MyArray не пробовал?


 
race1   (2004-07-28 18:42) [2]

всмысле, как без MyArray?

я попробовал так:
MyArray := pnt;
всё заработало; только неправильно размер массива MyArray определяется, но это не беда

а вообще pnt передаётся по ссылке (var pnt: Pointer), затем в качестве массива над данными по адресу pnt делаются изменения, далее переменная, на которую указывает pnt используется дальше в вызвавшей процедуре. насколько это безопасно?


 
jack128 ©   (2004-07-28 18:58) [3]


> я хочу перевернуть массив наоборот, т.е. [1, 2, 3] превратить
> в [3, 2, 1].
массив, какого то определенного типа(Integer там, или char) или массив произвольного, зарание неизвестного типа?


> TMyArray = Array of Byte;
>  PMyArray = ^TMyArray;
PMyArray - указатель на указатель на первый элемент массива - ты это понимаешь?

пример для массива байтов
TDynByteArray = array of byte;

procedure SwapByteArray(var Arr: TDynByteArray);
var
 i: Integer;
 Temp: byte;
begin
 for i := 0 to (Length(Arr) - 1) div 2 do
 begin
   Temp := Arr[i];
   Arr[i] := Arr[Length(Arr) - i - 1];
   Arr[Length(Arr) - i - 1] := Temp;
 end;
end;


 
Rem   (2004-07-28 19:23) [4]

TMyArray = Array of Byte;
...
MyArray: TMyArray;
...
MyArray := MyArrayP^;


Внимательно смотрим на то, что приведено.
Потом еще раз смотрим.
Ищем место, где определяется размер TMyArray.
На находим?
Тогда ищем место, где под MyArray выделяется память.
Не находим?
Пытаемся сделать выводы.


 
jack128 ©   (2004-07-28 19:36) [5]


> Тогда ищем место, где под MyArray выделяется память.
у почему под MyArray нужно выделять память? Это ж дин массив.

> процедура принимает аргументом адрес переменной (байты которой
> являются элементами массива),

совершенно не понял фразу. пример использования процедуры?


 
Kurtevich   (2004-07-28 19:57) [6]

я бы сделал так:

procedure proc(p: pointer; len: integer);
var i: integer;
   myarray: array of byte;
begin
 setlength(myarray, len);
 for i:=0 to len-1 do
   myarray[len-1-i] := byte((p+i)^);
 for i:=0 to len-1 do
   (p+1)^ := myarray[i];
end;


а вызывать нужно так:

proc(@array[0], sizeof(array));

с этими массивами надо поосторожнее, хрен его знает, что они в дельфе реально из себя представляют?

... хотя все это написано с ходу и может вобще полный бред...


 
Fay ©   (2004-07-28 20:01) [7]

2Kurtevich   (28.07.04 19:57) [6]

> proc(@array[0], sizeof(array));

Интересная мысль. Знаете фокус? Вы выполняете
ShowMessage(IntToStr(SizeOf(array)))
, а я угадываю результат! Очень круто!


 
Fay ©   (2004-07-28 20:01) [8]

Выполнили? 4, верно?! 8)


 
jack128 ©   (2004-07-28 20:13) [9]


> Выполнили? 4, верно?! 8)

var
 b: array[0..10] of byte;
нет, не угадал ;-)


> с этими массивами надо поосторожнее, хрен его знает, что
> они в дельфе реально из себя представляют?
читай доку и будет те счастье.


 
Fay ©   (2004-07-28 20:15) [10]

Речь шла о динамических массивах. Читай свой пост - заколбасит не по-детски!!!

> procedure proc(p: pointer; len: integer);
> var i: integer;
>    myarray: array of byte;
> begin
>  setlength(myarray, len);
>  for i:=0 to len-1 do
>    myarray[len-1-i] := byte((p+i)^);
>  for i:=0 to len-1 do
>    (p+1)^ := myarray[i];
> end;
>
> а вызывать нужно так:
>
> proc(@array[0], sizeof(array));


 
jack128 ©   (2004-07-28 20:18) [11]


> Речь шла о динамических массивах. Читай свой пост - заколбасит
> не по-детски!!!
прочитал..Действительно - дин массивы. Как это я не заметил ;-) Правда, что нужно автору вопроса - до сих пор не ясно...


 
Fay ©   (2004-07-28 20:25) [12]


> Правда, что нужно автору вопроса - до сих пор не ясно...

Ага 8)


 
olookin ©   (2004-07-28 20:34) [13]

а я в таких случаях делаю резервный массив. Через него произвожу преобразование. Сохраняю в исходный массив. А потом грохаю этот резерв.


 
Fay ©   (2004-07-28 20:40) [14]

А резервного элемента массива не хватает?


 
Arm79   (2004-07-28 23:17) [15]

я приводить пример программы не буду, тк аналога у меня нет, я с ходу писать мне не очень хочется, но смысл, как я понял, такой: первый элемент меняется местами с последним, второй с предпоследним и тд. Организуем цикл до тех пор, пока есть изменения и меняем местами i-ый элемент массива с High(наш красивый динамический массив)-i - элементом. Увеличиваем i на 1. Как только менять нечего (например, i>=(High - i)), меняем условие цикла и тем самым его завершаем. Разумеется все очень приблизительно, но алгоритм в правильном направлении.


 
Anatoly Podgoretsky ©   (2004-07-29 00:02) [16]

Ну какой же это хитрый массив?


 
ЮЮ ©   (2004-07-29 03:52) [17]

>я хочу перевернуть массив наоборот, т.е. [1, 2, 3] превратить в [3, 2, 1].

не лучше ли
1) создавать его сразу в нужном порядке
2) при использовании учитывать, что он перевернут, т.е. не
 myarray[i], a myarray[Length(a) - i];


 
race1   (2004-07-29 06:24) [18]

вобщем есть переменная, например, интегер, в ней хранятся 4 байта (01 00 00 00), а мне нужно эти байты перевернуть, т.е. сделать 00 00 00 01. думаю так: если массив на самом деле указатель, то установить адрес начала массива (кстати, array of byte) на адрес нашей integer переменной. в таком случае вроде должен получиться массив из 4 байтов. далее переворачиваем массив вверх ногами, но на самом деле изменяем и значение переменной интегер, т.к. массив и интегер находятся по одному и тому же адресу

но почему-то EInvalidPointer, если так:

 MyArray := Pnt;
 ...
 // работа с MyArray как с массивом
 ...


 
race1   (2004-07-29 06:24) [19]

ах, да, нам не нуен массив, нам нужна переменная интегер, массив временный


 
ЮЮ ©   (2004-07-29 07:34) [20]

>если массив на самом деле указатель, то установить адрес начала массива ...

такие фокусы можно, пожалуй, с array[0..3] of byte провернуть, но никак не с динамическим массивом


 
Romkin ©   (2004-07-29 09:37) [21]

Вашу Машу! Ну нафига работать с указателем? При этом не понимая, как надо с ним работать, и не понимая, что динамический массив - уже указатель!
procedure Reverse(var A: Array of integer);
var
 i, n: integer;
 T: integer;
begin
 if not assigned(A)
   then Exit;
 n := High(A);
 for i := Low(A) to n div 2 do
 begin
   T := A[i];
   A[i] := A[n - i];
   A[n - i] := T;
 end;  
end;

Вроде не ошибся. Перед вызовом процедуры массив должен быть создан


 
Digitman ©   (2004-07-29 09:37) [22]


> race1


procedure Mirror(Data: PInteger);
var
 i, Out: Integer;
begin
for i:= 0 to 3 do
  PByte(@Out)[i] := PByte(Data)[3 - i];
Data^ := Out;
end;


 
Romkin ©   (2004-07-29 09:44) [23]

ЮЮ ©  (29.07.04 03:52) [17] Не лучше :))
С помошью процедуры реверсирования порядка элементов много чего делается :))
Например, циклический сдвиг массива...


 
Sandman25 ©   (2004-07-29 09:45) [24]

[22] Digitman ©   (29.07.04 09:37)

procedure Mirror(var Data: PInteger);


 
Sandman25 ©   (2004-07-29 09:46) [25]

И кстати, все равно неправильно - получаем указатель на стек.


 
Sandman25 ©   (2004-07-29 09:47) [26]

Вру, [25] игнорируем :)


 
ЮЮ ©   (2004-07-29 09:50) [27]

>Например, циклический сдвиг массива...

если только СДВИГ, то - да, причем ПО ФАЗЕ :)

а изменить порядок обхода будет труднее?


 
Digitman ©   (2004-07-29 10:01) [28]


> Sandman25 ©   (29.07.04 09:45) [24]


зачем VAR ? это уже косвенная ссылка получается, т.е. указатель на указатель ... в процедуру, как я понял, нужно передать адрес переменной типа Integer и, рассматривая заначение этой  переменной как стат.массив из 4-х байт, зеркально поменять его элементы "на месте" .. или я чего-то недопонял


 
Sandman25 ©   (2004-07-29 10:03) [29]

[28] Digitman ©   (29.07.04 10:01)

Все правильно. Это я чего-то недопонял. Посчитал, что нам нужно изменить Data. Поэтому же написал и [25].


 
Anatoly Podgoretsky ©   (2004-07-29 10:03) [30]

Digitman ©   (29.07.04 09:37) [22]
for i:= 0 to 1 do //Length div 2


 
Digitman ©   (2004-07-29 10:14) [31]


> Anatoly Podgoretsky ©   (29.07.04 10:03) [30]


?

мы же не слова меняем, а байты ..


 
Anatoly Podgoretsky ©   (2004-07-29 10:24) [32]

Увидел, что испточник и приемник разные, а то бы был Двойной реверс, а так все нормально.
1-4
2-3
3-2
4-1


 
Kurtevich   (2004-07-29 10:45) [33]


> Интересная мысль. Знаете фокус? Вы выполняете
> ShowMessage(IntToStr(SizeOf(array)))
> , а я угадываю результат! Очень круто!


ну да, ОК, я прогнал - тут надо length или шото такое вызывать -мне просто влом в документаию лезть смотреть... я же сказал, что все это накалякано сходу - экспромтом за пол минуты!

фокусник тоже мне... [7]


 
nikkie ©   (2004-07-29 20:33) [34]

>вобщем есть переменная, например, интегер, в ней хранятся 4 байта (01 00 00 00), а мне нужно эти байты перевернуть, т.е. сделать 00 00 00 01. думаю так: если массив на самом деле указатель, то установить адрес начала массива (кстати, array of byte) на адрес нашей integer переменной. в таком случае вроде должен получиться массив из 4 байтов.
плохая идея. здесь неявно подразумевается порядок представления integer байтами. на другой архитектуре можно получить совершенно неожиданный результат. арифметическую перестановку байтов надо реализовывать арифметическими операторами.


 
SergP ©   (2004-07-29 20:57) [35]

А какой смысл переворачивания массива?
Не проще ли "перевернуть" индекс и таким образом обращаться к элементам масссива?
Типа например имеем массив A:array[1..10] of Mytype;

Обращаемся к нему A[i] - будет обычным (относительно i)
А обращаемся так: A[11-i] - будет типа "перевернутым" (относительно i)?



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

Форум: "Основная";
Текущий архив: 2004.08.15;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.058 c
14-1091174607
Kreogen
2004-07-30 12:03
2004.08.15
BOX или не BOX


14-1091284985
Водитель трамвая
2004-07-31 18:43
2004.08.15
Хочу убить свой винт с почестями. Как это сделать?


9-1083347204
wolf3d
2004-04-30 21:46
2004.08.15
Если кто знает об игре Crazy Plumber


14-1090820397
syte_ser78
2004-07-26 09:39
2004.08.15
как програмно создать ярлык?


4-1088416870
vertal
2004-06-28 14:01
2004.08.15
Передача управления другой программе без возврата





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