![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
строки [D6]
РоманВитов © (2002-11-26 22:06:00)Подскажите
Как поменять местами 2 строки
Юрий Зотов (2002-11-27 14:45:00) [1]> SottNick © (27.11.02 10:49)
По поводу длинных/коротких строк - это очевидно и пионеру. Именно поэтому во всех своих постингах я специально указывал слово "длинный". Спорить было не о чем.
По поводу обмена указателей - работайте с динамическими переменными и все будет прекрасно обмениваться. А статические - они на то и статические, чтобы их адрес не менялся.
Dmitriy Polskoy (2002-11-27 11:56:00) [2]
> s1,s2,s3:string[10];
При таком определении будет автоматически создана строка SortString со всеми вытекающими последствиями.
SottNick (2002-11-27 10:49:00) [3]Короче, я не знаю.
Вероятно, с длинными стрингами вы правы.
var
s1,s2,s3:string;
begin
s1:="абвгдйка";
s2:="ёпрст";
s3:=s1;
s1:=s2;
s2:=s3;
showmessage(inttostr(integer(@s1))+#13+inttostr(integer(@s2))+#13+inttostr(integer(@s3)));
end;
Указатели идут со смещением в 4 байта, т.е. указывают вероятно на еще одни указатели
Про то, как работают длинные сртинги, я не читал.
если строку
s1,s2,s3:string;
заменить на
s1,s2,s3:string[10];
всё будет совсем иначе
короче, наверняка прав Smithson
когда я сетовал на отсутствие процедуры, обменивающей указатели, я имел в виду любые типы
что-то вроде
var
s1,s2,s3:string[10];
p:^string[10];
begin
p:=@s1;
@s1:=@s2;
@s2:=p;
end;
Юрий Зотов (2002-11-27 09:53:00) [4]> SottNick © (27.11.02 09:37)
Вы неправы. Копилятор Delphi строит работу с длинными строками вовсе не так, как Вы думаете. При присвоении строк копируются именно четыре байта адреса и более ничего.
Smithson (2002-11-27 09:49:00) [5]Если речь идет про ShortString (String[255]), то прав SottNick, а вот если речь идет о нормальных строках Delphi(не Pascal, а официального их названия я не помню), то это динамические объекты с управляемым временем жизни (вспомни автоконструкторы и деструкторы в С++), но физически переменная S: String будет именно указателем на блок памяти. И более того, при копировании строки S1 := S2 копируется адрес на этот блок памяти и увеличивается его внутрений счетчик ссылок. А вот если одну из строк начать изменять, то обнаружится, что счетчик ссылок у нее больше одного и вот тогда будет произведено копирование данных и уменьшение счетчика ссылок в строке-оригинале. Сделано в общем толково, но неочевидно и не слишком быстро.
MBo (2002-11-27 09:41:00) [6]>SottNick
А вот и нет!
происходит как раз копирование 4 байт, и счетчик ссылок исходной строки увеличивается на 1.
Только если мы изменим одну из строк, произойдет реальное копирование содержимого
SottNick (2002-11-27 09:37:00) [7]ээээээээээ
как на разных языках
по слогам:
при операции присвоения
s1:=s2;
происходит копирование содержимого одной переменной в другую
при этом адреса (указатели памяти) строк остаются прежними
а вовсе не
>>Оператор S1 := S2 копирует не тело строки, а ее адрес
>>Юрий Зотов © (27.11.02 09:11)
то есть
при копировании строки из 255 символов в другую
происходит копирование 255 байтов
а не 4 байтов, если б мы копировали указатель памяти одной строки вместо указателя другой
Юрий Зотов (2002-11-27 09:28:00) [8]> SottNick © (27.11.02 09:17)
В самом деле?
А почему адрес S1 должен быть равен адресу S2? Это две разные разные переменные, и адреса у них тоже разные. С какой стати?
После присвоения S1 := S2 должны быть одинаковыми не адреса, а содержимое эти переменных. Приведите их к типу Integer или Pointer и сравните в отладчике.
MBo (2002-11-27 09:21:00) [9]>SottNick
Не @s1, а @s1[1] (что то же самое, что и просто s1)
@s1 - адрес переменной-указателя (указатель на указатель), естественно, разные переменные лежат по разным адресам, но вот их содержимое указывает на один и тот же адрес (конечно, пока не произойдет перераспеределения памяти)
SottNick (2002-11-27 09:17:00) [10]> Юрий Зотов
не правильно
если
s1:=s2;
то
@s1<>@s2
неужель Вы и впрям так заблуждались?
Alx2 (2002-11-27 09:15:00) [11]>Юрий Зотов © (27.11.02 09:11)
Так я сначала попробовал. И написал все совершенно серьезно. И даже корректно должно работать.
Юрий Зотов (2002-11-27 09:11:00) [12]> SottNick
Длинные строки - это указатели и есть. Оператор S1 := S2 копирует не тело строки, а ее адрес. Так что происходит именно то, о чем Вы говорите.
> Alx2
А Вы попробуйте. Не уверен, но есть подозрение, что сработает. Серьезно.
Alx2 (2002-11-27 08:57:00) [13]>Alx2 © (27.11.02 08:56)
Да, забыл сказать, что
Var S1,S2 : String;
Alx2 (2002-11-27 08:56:00) [14]>Anatoly Podgoretsky © (27.11.02 08:08)
>а как ты представляешь замену указателей без дополнительной
>переменной, асм вставки не рассматриваем
Вот так, например:
Integer(S1) := Integer(S1) - Integer(S2);
Integer(S2) := Integer(S1) + Integer(S2);
Integer(S1) := Integer(S2) - Integer(S1);
SottNick (2002-11-27 08:13:00) [15]2 Anatoly Podgoretsky
я представляю не замену, а обмен ... указателями, а не значениями переменных
естественно через временную переменную типа указатель
это возможно?
дай демку
Anatoly Podgoretsky (2002-11-27 08:08:00) [16]Так оно и работает, а как ты представляешь замену указателей без дополнительной переменной, асм вставки не рассматриваем
SottNick (2002-11-27 07:21:00) [17]а как было бы хорошо, имей мы процедуру, меняющую только указатели...
TTCustomDelphiMaster (2002-11-26 22:09:00) [18]Так же как и 2 числа. Через временную переменную.