Форум: "Основная";
Текущий архив: 2003.06.09;
Скачать: [xml.tar.bz2];
ВнизКогда нужно исспользовать SetLength для строк? Найти похожие ветки
← →
MegaVolt (2003-05-29 15:05) [0]Sabj:
Для примера
for i:=1 to x do s:+s+"a";
нужно ли тут применять SetLength rf;lsq раз при увеличении s если x неизвесно (например в цикле While)? Или если s элемент динамически созданной записи?
Т.е. когда нужно когда не нужно и почему.
Заранее благодарен.
← →
Skier (2003-05-29 15:15) [1]Для твоего случая - не нужно.
← →
Digitman (2003-05-29 15:15) [2]нет.
в данном конкретном случае не нужно - об этом позаботится компилятор, вставив в результирующий код неявный вызов SetLength()
← →
Sha (2003-05-29 15:19) [3]Надо только перед обращением к символу строки по индексу, и только в том случае, если индекс превышает длину.
По окончании работы со строкой можно освободить память, устанавливаяя нулевую длину строки.
← →
MegaVolt (2003-05-29 15:25) [4]Те если вот это правильно:
s:="asd";
SetLength(s,4);
s[4]="f";
Dj всех остальных случаях SetLength не применяется???
← →
Skier (2003-05-29 15:28) [5]>MegaVolt © (29.05.03 15:25)
Не думаю что есть точный рецепт применения SetLength.
Всё зависит от конкретного случая...
← →
Sha (2003-05-29 15:30) [6]Да
← →
Digitman (2003-05-29 15:33) [7]
> MegaVolt © (29.05.03 15:25)
в данном случае - да, правильно... т.е. как один из правильных вариантов явного увеличения памяти, отводимой под буфер строки.
если же не предпринять ни этого ни какого либо иного варианта увеличения буфера, есть ненулевой риск получить AV-исключение.
← →
Sha (2003-05-29 15:34) [8]Правда, иногда еще укорачивают строку при помощи SetLength, если хвост больше не нужен.
← →
MegaVolt (2003-05-29 15:37) [9]А как мне догадыватся что в этом случае нужно а тут не нужно
← →
Palladin (2003-05-29 15:43) [10]Головой
← →
Sha (2003-05-29 15:44) [11]Сам должен думать, что тебе надо по твоему алгоритму.
Если "Volt" больше не нужен, то:s:="MegaVolt"; SetLength(s,4);
Когда будешь пользоваться чем-нибудь, изменяющим отдельные символы внутри строки, типа FillChar или Move, действуй аналогично присваиванию s:="f";
← →
Serginio (2003-05-29 15:44) [12]Обычно SetLength для строк используется вместо буфера (array[0..lenbuf-1]) при применении процедуры Move., но есть еще множество вариантов. При объединении строк Delphi автоматически выделит нужную память.
← →
Sha (2003-05-29 15:45) [13]Поправка s[i]:="f";
← →
Sandman25 (2003-05-29 15:47) [14]2MegaVolt
см Sha © (29.05.03 15:19)
Например.
SetLength(S, 15);
for i := 1 to 15 do
S[i] := chr(i+ord("A"));
← →
Digitman (2003-05-29 15:50) [15]
> Palladin © (29.05.03 15:43)
)))
В форуме далеко не редки ситуации, когда для целей "догадывания" используются другие, альтернативные места)
> MegaVolt
а не надо догадываться !
просто надо представлять в каждый момент времени, что происходит со строкой ПЕРЕД операцией над ней и каково будет ее состояние ПОСЛЕ той или иной операции, которая, несмотря на внутреннюю схожесть, выглядеть с т.з. Паскаль-текста может по-разному ... и при неуверенности сразу же "лезть" в исходники System и SysUtils
← →
MegaVolt (2003-05-29 15:56) [16]А если я применяю такую запись
S:=copy(s,x,y);
то не нужно как я понимаю? Или всё таки нужно если размер результирующей строки меньше исходной?
← →
Skier (2003-05-29 15:58) [17]>MegaVolt © (29.05.03 15:56)
F1. Читаем...
If Index is larger than the length of S, Copy returns an empty string or array.
← →
Digitman (2003-05-29 16:06) [18]
> MegaVolt (29.05.03 15:56)
нет, не нужно.
простейшее объяснение - никаких явных преобразований типов между результирующим типом (ф-ция возвращает string) и типом переменной s: string перед присвоением не требуется и не происходит, поэтому компилятор самостоятельно заботится о :
- перераспределении памяти под переменную s, чтобы размер ее буфера соответствовал размеру буфера строки, возвращаемой из ф-ции;
- копировании из буфера возвращаемой строки в буфер переменной s;
- уничтожении результирующей строки с автоматическим освобождением памяти под ее буфер;
← →
MegaVolt (2003-05-29 16:12) [19]Я не про индех больше длинны строки а про то :
s:="MegaVolt";
s:=Copy(s,1,4);
в результате строка результата стала меньше изначальной строки вот я и спрашиваю нужно самому уменьшать строку под размер новой или дельфи сам? И кстати исходников функции Copy нету в System и SysUtils :(
← →
Palladin (2003-05-29 16:16) [20]стала
← →
Palladin (2003-05-29 16:19) [21]и вообще я не понимаю, не ужели трудно поэкспериментировать?
есть такая функция Length мог бы и посмотреть сам
← →
Digitman (2003-05-29 16:23) [22]
> исходников функции Copy нету в System и SysUtils :(
есть) ... procedure _Copy(...) смотри.
но setlength() ты там не увидишь, в ее теле, ибо этот вызов компилятор вставляет неявно
← →
Skier (2003-05-29 16:26) [23]
> но setlength() ты там не увидишь, в ее теле, ибо этот вызов
> компилятор вставляет неявно
А если включить Use debug DCUs ? Можно кое-что увидеть, и даже
очень интересного, особенно если прогнать построчно...:)
← →
Verg (2003-05-29 17:05) [24]Например, ты принял из какой-нибудь функции (напр, из dll) буфер buff типа pchar и количество символов в нем хранящихся charcount. Задача - сделать из нее строку (string) S.
Вариант1:
S:="";
while charcount>0 do
begin
S:=S+buffer^;
inc(buffer);
dec(charcount);
end;
Вариант2:
SetLength(S, charcount);
move(buffer^, s[1], charcount);
Угадай с трех раз - какой из вариантов будет работать быстрее и занимать меньше кода?
← →
MegaVolt (2003-05-29 17:48) [25]Второй вариант раз в 6 быстрее :) Начинаю понимать.
Спасибо :)
← →
MegaVolt (2003-05-29 17:54) [26]Кстати вместо второго варианта можно написать? Или нет?
s:=PChar(buffer);
← →
Skier (2003-05-29 17:56) [27]>MegaVolt © (29.05.03 17:54)
Можно, но зачем ? Buffer и есть PChar.
← →
Serginio (2003-05-29 18:05) [28]2(MegaVolt) Вот и можешь получить другую строку намного большую пока не найдется #0. PCHAR можно использовать и всесто Pointer для более простой арифметики над указателями. Надо быть уверенным при ее использовании, что это указатель на нуль терминированную строку. Простой пример при использовании со стримами.
Str.Read(TypeVal,SizoOf(TypeVal));
If TypeVal=IdStroka Then
Begin
Str.Read(LenStr,SizoOf(LenStr));
SetLength(str,lenStr);
Str.Read(str[1],LenStr);
end;
← →
panov (2003-05-30 02:22) [29]SetLength как раз можно использовать для ускорения работы со строками в такоом случае:
1.
var
s: String;
i: Integer;
begin
s := "";
for i := 0 to 255 do
begin
s := s + Chr(i);
end;
end;
2.
var
s: String;
i: Integer;
begin
SetLength(s,256);
for i := 0 to 255 do
begin
s[i] := Chr(i);
end;
end;
Второй пример будет работать быстрее из-за того, что не надо память перераспределять в цикле.
← →
Skier (2003-05-30 08:24) [30]>panov © (30.05.03 02:22)
for i := 1 to 256 do
← →
MegaVolt (2003-05-30 09:54) [31]Я имел в виду
s:=String(Buffer);
:)
← →
Anatoly Podgoretsky (2003-05-30 09:58) [32]MegaVolt © (30.05.03 09:54)
s := Buffer;
← →
MegaVolt (2003-05-30 10:32) [33]И это правильно???
← →
Anatoly Podgoretsky (2003-05-30 11:09) [34]Конечно
S - string
buffer - PChar
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.06.09;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.015 c