![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
FillChar для строки [D7, XP]
Dmitry_177 © (2007-05-26 02:25:00)Как правильно выполнить FillChar для строки?
Если выполнить так:
var
s: string;
...
FillChar(s, SizeOf(s), #0);
ИМХО очистится не сама строка, а указатель на нее..
Вот так правильно ли будет?
var
s: string;
...
FillChar(PChar(s)^, Length(s), #0);
(2007-06-12 03:36:00) [1]Удалено модератором
(2007-06-12 03:36:00) [2]Удалено модератором
Dmitry_177 (2007-05-27 20:52:00) [3]Спасибо большое тебе..:)
Однокамушкин (2007-05-27 20:36:00) [4]
> Dmitry_177 (27.05.07 18:38) [46]
В общем-то да... за исключением того, что если строка передаётся для записи, и размер буфера известен во время написания программы, то со string'ом можно и не связываться, достаточно буфера array[0..N] of Char
Dmitry_177 (2007-05-27 18:38:00) [5]т.е. грубо говоря если в функцию передается строка которая будет модифицироваться в самой этой функции, то лучше передавать ее как Pointer(str)^, а если для чтения то PChar(str)?
Однокамушкин (2007-05-27 07:37:00) [6]
> Dmitry_177 (27.05.07 01:00) [42]
> Однокамушкин, н а в api как лучше вставлять строки pchar(str)
> или pointer(str)^ ?
А это вообще сильно зависит от того, куда вы их собираетесь вставлять... в api есть типы LPTSTR и LPCTSTR, в Delphi они переводятся одинаково - PChar, но на самом деле смысл их разный... LPTSTR - это обычный указатель на строку, когда встречается параметр такого типа, это значит, что содержимое строки api-функция скорее всего будет менять, а вот LPCTSTR - это указатель на константное содержимое, т.е. данные по этому указателю api-функция будет только читать, но не модифицировать... соответственно, во втором случае можно передавать указатель на немодифицируемую память, чего никак нельзя делать в случае LPTSTR...
В общем, для LPCTSTR правила такие: можно передавать либо строковый литерал (т.е. просто константу), либо строку, приведённую к PChar... PChar, кстати, потому и заменяется на вызов _LStrToPChar, чтобы корректно обрабатывать именно передачу LPCTSTR-парамеров... Так что тут только два варианта: строковый литерал или приведение к PChar...
А вот для LPTSTR правила другие... там надо передавать либо nil, если вам, с одной стороны, результат не нужен, а с другой функция это допускает, либо указатель на реальный буфер, который надо заранее выделить, никакие литералы здесь уже недопустимы... И если буфер делается через string, то тут почти без разницы, как её приводить - через PChar или через Pointer, потому что для не пустой строки разницы между этим операциями не будет, разве что Pointer чуть-чуть побыстрее...
Германн (2007-05-27 01:36:00) [7]P.S. Поскольку это "Начинающие", то в [43] я не прикалываюсь, а говорю с полной ответственностью.
Германн (2007-05-27 01:34:00) [8]
> а в api как лучше вставлять строки pchar(str) или pointer(str)^
> ?
pchar(str) разумеется. Это вполне нормально.
Dmitry_177 (2007-05-27 01:00:00) [9]Однокамушкин, н а в api как лучше вставлять строки pchar(str) или pointer(str)^ ?
Однокамушкин (2007-05-26 17:40:00) [10]
> Dmitry_177 (26.05.07 16:42) [38]
> т.е. с "^" на конце..
Правильно, про ^ я просто забыл...
> begin...end © (26.05.07 17:19) [40]
> AV не будет. Может быть только Range Check Error -- если,
> конечно, включена опция Range Checking.
Ну да, конкретно здесь не будет, потому что не будет обращения к этому указателю... А вообще, словить av там, где s[1] при s='' очень просто...
begin...end (2007-05-26 17:19:00) [11]> Однокамушкин (26.05.07 10:43) [21]
> Видимо, имелся ввиду s[1]... Но это тоже корректно только
> если s<>'', а то будет то же av...
AV не будет. Может быть только Range Check Error -- если, конечно, включена опция Range Checking.
Loginov Dmitry (2007-05-26 16:55:00) [12]> Кстати если так подумать то ведь я не только в FillChar
> передавал PChar(str), но и во все API функции.. Тогда лучше
> в них Pointer(str) передавать?
Вряд ли это че-то будет лучше, не говоря уж о том, что многие API-функции Windows работают в Unicode-формате, и тама расходы на преобразование в UNICODE и обратно куда больше, чем расходы при использовании PChar.
Dmitry_177 (2007-05-26 16:42:00) [13]т.е. с "^" на конце..
Dmitry_177 (2007-05-26 16:41:00) [14]Да и еще, при: FillChar(Pointer(str), Length(str), #0); при последующей работе с str выскакивает AV, а так: FillChar(Pointer(str) ^, Length(str), #0);
Dmitry_177 (2007-05-26 16:36:00) [15]Кстати если так подумать то ведь я не только в FillChar передавал PChar(str), но и во все API функции.. Тогда лучше в них Pointer(str) передавать?
Однокамушкин (2007-05-26 15:46:00) [16]
> просто на сколько я знаю "#0"-это именно нулевой символ,
> а "0" - это символ 48..
0 и '0' - это разные вещи... 0 соответствует #0, а '0' - #48...
Dmitry_177 (2007-05-26 15:13:00) [17]Loginov Dmitry, в ZeroMemory ее коде FillChar, посмотри..
Anatoly Podgoretsky (2007-05-26 15:11:00) [18]> Loginov Dmitry (26.05.2007 15:05:31) [31]
Шило на мыло
palva (2007-05-26 15:08:00) [19]
> Однокамушкин (26.05.07 12:53) [23]
> А так, как мы уже тут говорили...
> FillChar(Pointer(s), cbStrLen, #0)
Теперь всегда так буду делать. Конечно, если мне когда нибудь взбредет в голову вспомнить детство и позаниматься извращениями.
Loginov Dmitry (2007-05-26 15:05:00) [20]ZeroMemory :)