Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
14-26711
WarLord
2003-05-21 09:48
2003.06.09
Code Explorer


6-26625
Arkara
2003-04-06 02:09
2003.06.09
Как вызвать стандартную звонилку Windows?


1-26522
Jaxtor
2003-05-27 16:17
2003.06.09
Динамический TComboBox


3-26371
Snake
2003-05-19 14:00
2003.06.09
Пожалуйста, помогите составить запрос...


14-26750
Markizzz
2003-05-22 21:37
2003.06.09
Счётчики для сайта





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