Двоичное представление строки

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Двоичное представление строки

Сообщение Pasha-V » 07.09.2015 17:02:19

Не подскажите, как узнать двоичное представление строки? Вид в котором она содержится в памяти.
Pasha-V
новенький
 
Сообщения: 11
Зарегистрирован: 28.03.2015 04:30:52

Re: Двоичное представление строки

Сообщение SSerge » 07.09.2015 18:08:35

SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Двоичное представление строки

Сообщение Pasha-V » 07.09.2015 18:17:45

Нет, я имел в виду как практически.
Например строка 'World'. Как узнать ее двоичное представление? Есть функция по преобразованию?
Pasha-V
новенький
 
Сообщения: 11
Зарегистрирован: 28.03.2015 04:30:52

Re: Двоичное представление строки

Сообщение runewalsh » 07.09.2015 18:40:12

Просто приведи строку к указателю, по нему содержимое и лежит, читай-извлекай чем хочешь. К типизированному, возможно, придётся двумя кастами: PByte(pointer(s)). Для shortstring — pointer(PChar(@s) + 1) вместо pointer(s), можно, конечно, просто @s[1], но с включенной range checking это упадёт на пустой строке.
Последний раз редактировалось runewalsh 07.09.2015 18:51:27, всего редактировалось 1 раз.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Re: Двоичное представление строки

Сообщение Pasha-V » 07.09.2015 18:47:20

Извиняюсь, нужно именно shortstring. Как-то можно посмотреть область памяти, где она лежит?
Pasha-V
новенький
 
Сообщения: 11
Зарегистрирован: 28.03.2015 04:30:52

Re: Двоичное представление строки

Сообщение runewalsh » 07.09.2015 18:52:17

Отредактировал сообщение. А вообще shortstring не нужна. Никогда. ;)
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Re: Двоичное представление строки

Сообщение Pasha-V » 07.09.2015 19:02:43

1)
shortstring нужна всегда, с ней проще, и она быстрее работает.

2)
Код: Выделить всё
writeln('Str - ', pointer(PChar(@Str) + 1));
— Can't read or write variables of this type
Pasha-V
новенький
 
Сообщения: 11
Зарегистрирован: 28.03.2015 04:30:52

Re: Двоичное представление строки

Сообщение runewalsh » 07.09.2015 19:24:39

shortstring нужна всегда, с ней проще, и она быстрее работает.

Нет. Во-первых, никогда нет. Во-вторых, пример: по умолчанию константы типа shortstring независимо от реальной длины строк с радостью занимают в исполняемом файле все 256 байт, а константы ansistring — нет. В-третьих, счастливо обрубать строки на 255 символах. В-четвёртых, shortstring при присваивании всегда копируются, а у ansistring есть счётчик ссылок.

Can't read or write variables of this type

Я сказал, как получить указатель на данные строки в памяти. Что с ними делать дальше — твоё дело. Должно быть более-менее очевидно, что writeln указателя — странная операция, нэ? Если хочешь вывести шестнадцатеричный дамп, то:

Код: Выделить всё
{$coperators+} // +=
{$modeswitch result+} // result в функциях
{$h+} // string = ansistring

function HexDump(const s: string): string;
var
  bytes: PByte;
  i: integer;
begin
  result := '';
  bytes := pointer(s);

  for i := 0 to length(s) * sizeof(s[1]) - 1 do
    result += HexStr(bytes[i], 2) + ' ';
end;

writeln(HexDump('hello')); // => 68 65 6C 6C 6F
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Re: Двоичное представление строки

Сообщение Лекс Айрин » 07.09.2015 20:20:54

Pasha-V писал(а):Извиняюсь, нужно именно shortstring. Как-то можно посмотреть область памяти, где она лежит?


оператором взятия адреса -- @
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Двоичное представление строки

Сообщение zub » 07.09.2015 20:32:19

>>pointer(PChar(@Str) + 1)
сегодня он +1, завтра -1, а в четверг +8
просто
Код: Выделить всё
@Str[1]
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Двоичное представление строки

Сообщение Pasha-V » 07.09.2015 21:14:55

1) Нет, ansistring не подходит.
Главное преимущество строк типа AnsiString по сравнению с короткими строками — отсутствие каких-либо ограничений на длину обрабатываемых данных. Но это преимущество имеет и обратную сторону медали — работа с динамически выделяемой памятью сопряжена со значительными накладными расходами. Как только переменной такого типа присваивается очередное значение, имеющее длину, отличную от длины предыдущего значения, приходится возвращать ранее занимаемый ресурс и выделять место под новое значение переменной. Это неизбежно приводит к появлению разрозненных освобожденных участков памяти, выполнению дополнительных работ по "уборке мусора" и, как следствие, к замедлению работы программы.

Простой пример — сортировка динамического и статического массивов. Динамический медленнее на 40%.

2) Если использовать указатель, то нужно так?
Код: Выделить всё
var
  P: ^string;
  S: string;
begin
  S := 'World';

А дальше?
Pasha-V
новенький
 
Сообщения: 11
Зарегистрирован: 28.03.2015 04:30:52

Re: Двоичное представление строки

Сообщение runewalsh » 07.09.2015 21:32:27

zub писал(а):сегодня он +1, завтра -1, а в четверг +8

Имхо, для «коротких» строк предположение о длине в нулевом символе вполне безопасно.
zub писал(а):@Str[1]

Будет «ложное срабатывание» рейнджчека на пустой строке, говорю же. Ещё один довод против shortstring, «длинные» к указателям приводятся без проблем!
Pasha-V писал(а):Простой пример — сортировка динамического и статического массивов. Динамический медленнее на 40%.

Уж не знаю, как ты получил этот результат, но это неправда, потому что сортировка обоих массивов тривиально сводится к Sort(data: PType; count: integer).
Pasha-V писал(а):работа с динамически выделяемой памятью сопряжена со значительными накладными расходами

Больше слушай, да. Присваивание уже существующей строки не выделяет память, бтв. Единственный сценарий, в котором «длинные строки» работают медленнее, чем могли бы — это когда к длинной по одной присоединяются 9000 коротких. Для таких сценариев, которые для тебя вроде как не актуальны и не собираются быть актуальными, существует паттерн или готовый класс String Builder.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Re: Двоичное представление строки

Сообщение Pasha-V » 07.09.2015 22:08:02

Уж не знаю, как ты получил этот результат

Вообще, это известный факт — динамика медленнее. Можешь сам проверить. Моя программка:
Код: Выделить всё
uses
  sysutils, dateutils;

const
  Len = 16000000; // длина массива случайных чисел
  Ran = 16000000; // диапазон случайных чисел

type
  TStat = array[1..Len] of longword;
  TDyn = array of longword;
  PStat = ^TStat;

procedure JotMess;
var
  w: longword;
begin
  assign(stdout, 'C:\Mess.txt');
  rewrite(stdout);
  randomize;
  for w := 1 to Len do
    write(stdout, random(Ran) + 1, ' ');
  close(stdout);
end;

procedure Make(stat: PStat; dyn: TDyn; s: char);
var
  w: longword;
begin
  assign(input, 'C:\Mess.txt');
  reset(input);
  if s = 'S' then
    for w := 1 to Len do
      read(stat^[w], s)
  else
    for w := 0 to Len - 1 do
      read(dyn[w], s);
end;

procedure CSort(arr: PStat);
var
  b: array[1..Ran + 1] of byte;
  i, j, k: longword;
begin
  fillbyte(b, Ran + 1, 0);
  for i := 1 to Len do
    inc(b[arr^[i]]);
  k := 1;
  for j := 1 to Ran + 1 do
    for i := 1 to b[j] do
    begin
      arr^[k] := j;
      inc(k);
    end;
end;

procedure CSort(arr: TDyn);
var
  b: array of byte;
  i, j, k: longint;
begin
  setlength(b, Ran + 1);
  for i := 0 to Len - 1 do
    inc(b[arr[i]]);
  k := 0;
  for j := 0 to Ran do
    for i := 0 to b[j] - 1 do
    begin
      arr[k] := j;
      inc(k);
    end;
end;

procedure Jot(stat: PStat; dyn: TDyn; a: char);
var
  w: longword;
begin
  assign(stdout, 'C:\' + a + '.txt');
  rewrite(stdout);
  if a = 'S' then
    for w := 1 to Len do
      write(stdout, stat^[w], ' ')
  else
    for w := 0 to Len - 1 do
      write(stdout, dyn[w], ' ');
  close(stdout);
end;

var
  Stat: PStat;
  Dyn: TDyn;
  First: tdatetime;

begin
  JotMess;
  new(Stat);
  Make(Stat, Dyn, 'S');
  First := now;
  CSort(Stat);
  writeln('Stat: ', millisecondsbetween(First, now));
  Jot(Stat, Dyn, 'S');
  dispose(Stat);
  setlength(Dyn, Len);
  Make(Stat, Dyn, 'D');
  First := now;
  CSort(Dyn);
  writeln('Dyn: ', millisecondsbetween(First, now));
  Jot(Stat, Dyn, 'D');
  finalize(Dyn);
end.
Pasha-V
новенький
 
Сообщения: 11
Зарегистрирован: 28.03.2015 04:30:52

Re: Двоичное представление строки

Сообщение runewalsh » 07.09.2015 22:25:08

Pasha-V писал(а):Можешь сам проверить.

Проверил. В Debug действительно быстрее (800 vs 1250). Но цифры Debug не имеют значения. В Release поровну (540 vs 550 лол). И те 10 мс разницы — SetLength временного массива, в реальности же сортировки производятся не подсчётом и память не распределяют вообще и что статический, что динамический будут одинаковы с точностью до такта.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Re: Двоичное представление строки

Сообщение zub » 07.09.2015 22:53:45

runewalsh
>>Имхо, для «коротких» строк предположение о длине в нулевом символе вполне безопасно.
>>Будет «ложное срабатывание» рейнджчека на пустой строке, говорю же. Ещё один довод против shortstring, «длинные» к указателям приводятся без проблем!
Проверку на нулевую длину никто не отменял. Зато эта адресация монопесуальна к тупу строки - синтаксически одинакова что для "длинных", что для "коротких", пусть о внутреннем устройстве строки заботится компилятор, это его работа
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 15

Рейтинг@Mail.ru