![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
PChar [D6]
SPeller © (2002-07-25 12:56:00)Всем доброго времени суток! Что-то я вроде бы и прочитал хелп по null-terminated string"ам, но всё-равно остались сомнения по такому вопросу: как правильно сделать так, чтобы процедура изменяла значение параметра PChar?
В примере из хелпа не надо указывать слово var для того чтобы изменить значение параметра, поэтому я объявляю свою процедуру так:
procedure MyProc(S1,S2:PChar);
Изменить надо оба параметра. Но когда я делаю в процедуре
S1:=PChar(Src);,где Src имеет тип String
компилятор выдаёт Value assigned to S1 never used и поэтому по всей видимости, вследствие оптимизации выкидывает этот код.
Как мне правильно сделать присвоение чтобы получить нужный результат?
И ещё вопрос. Почти во всех функциях по работе с PChar говорится что они не проверяют размер самой строки и делают своё дело куда придётся, но я не нашёл функцию, которая задаёт длину строки. Для String достаточно было сделать SetLength, а вот для PChar как сделать подобное? И надо ли вообще это делать? В хелпе говорится что обычное присвоение вроде S:="Hello word" автоматически делает копию текста и устанавливают указатель в начало. А если в правой части оператора присваивания стоит тоже PChar или что-то другое? Почему не нравитсяS1:=PChar(Src);? И как обстоит дело с высвобождением памяти, занимаемой PChar-строкой?
Вообще мне не понятен механизм, по которому осуществляется работа с PChar"ами. Как выделяется память, как освобождается, ведь это по существу просто указатель.
Прошу помощи в данном вопросе, а то в хелпе инфы по нему как кот наплакал.
Anatoly Podgoretsky (2002-07-26 17:29:00) [1]Да ничего особого, просто многие не понимают что такое PChar, откуда он взялся м как с ним работать, отсюда постоянные ошибки и требуется помощь от Пушкина, разбаловали строки в Паскале.
Толик (2002-07-26 17:24:00) [2]М-да. похоже тема задела за живое :)))
Anatoly Podgoretsky (2002-07-26 16:27:00) [3]Alx2 © (26.07.02 14:00)
Правильно, PChar это указатель, string это как минимум два указателя, сообственно сам стрниг и его содержимое, второго может не быть, а работать должно, оператор str^ как бы не применим в этом случае
В случае применения приведения, гарантирует работоспособность WinApi функции, в зависимости от содержимого будет выдано или содержимое на PChar соместимое и указатель на PChar соместимую строку, так как S := "", а не nil указатель, котрый может привести в растройство WinApi.
SPeller (2002-07-26 16:09:00) [4]2 Толик © (26.07.02 14:20)
Вот-вот, из-за чего и весь вопрос.
Толик (2002-07-26 14:20:00) [5]to SPeller © (26.07.02 13:51)
Честно говоря, есть за Делфёй такой грешок - выполнение разных действий на "заднем плане", к которым не получить доступ (например то же приведение типов из string в pchar), наличие всяких системных фунцций и пр.
С этим конечно можно смирится, но неприятный осадок недоверия остаётся...
Игорь Шевченко (2002-07-26 14:06:00) [6]Кстати, PChar(AnsiString) - это вызов функции _LStrToPChar :-)
Alx2 (2002-07-26 14:00:00) [7]>Anatoly Podgoretsky © (26.07.02 13:52)
>откуда ему знать, что ты хочешь присвоить адрес
>или содержимое этого адреса.
Из типов переменных, естественно.
Anatoly Podgoretsky (2002-07-26 13:52:00) [8]MBo © (26.07.02 13:24)
И правильно делает, ну откуда ему знать, что ты хочешь присвоить адрес или содержимое этого адреса.
SPeller (2002-07-26 13:51:00) [9]2 Anatoly Podgoretsky © (26.07.02 12:26)
Вот такая цитата:
var P: PChar;
...
P := "Hello world!";
points P to an area of memory that contains a null-terminated copy of “Hello world!”
Здесь ведь не надо ничего инициализировать, автоматически создаётся копия текста и ставится указатель туда. Если посмотреть практически, то мы присваиваем указателю строку. Такое возможно? Попрбуйте проделать подобное с другими типами указателей. Ничего акромя Incompatible types не выйдет. Значит это уже не простой указатель и компилятор часть забот берёт на себя. Это у заставило меня вообще задать вопрос, чтобы узнать точно, что к чему. Потому как в хелпе кроме того что это указатель на строку, заканчивающуюся на #0 ничего нет. (Да это я давно уже знаю)
> тогда вот передод ...
Знаете, обойдусь без посторонней помощи в таком вопросе. В крайнем случае словарь возьму. А решать, достаточно ли у меня знаний для программирования извините, не вам, и уж точно не по признаку знания английского. Да и откуда вам знать, каковы они?
ЗЫ: Кстати, это был почти самый длинный постинг от вас, обычно пара слов и всё, а тут на те, прорвало.... :)
MBo (2002-07-26 13:46:00) [10]Еще любопытный пример граблей
procedure TForm1.Button1Click(Sender: TObject);
var
s:String;
begin
SetLength(s,100);
GetWindowText(Handle,PChar(S),100);
S:=S+" is My Caption";//не сработает
// S:="My Caption is: "+s;//а так можно
Caption:=S;
end;
Александр Малыгин (2002-07-26 13:42:00) [11]TO: MBo
Извиняюсь, прогнал :-(
НоS := Pработает!
А наш пример перепишем так:
begin
s:="qqq";
p := StrPCopy(@Buf, s); // копирование строки в буфер и инициализация указателя
s:="www";
showmessage(s+" "+p); // здесь будет "www qqq"
end
Еще интересный факт.
Типы WideString и AnsiString совместимы по присваиванию, сравнению и передаче в качестве const параметра.
MBo (2002-07-26 13:24:00) [12]такое
p:=s;
мне компилятор запрещает
я просто привел пример, когда обычное присвоение не будет корректно работать.
Александр Малыгин (2002-07-26 13:14:00) [13]TO: MBo
Ваш код не корректен, поскольку вы копируете указатель:
p:=pchar(s);
Я же говорил, что не надо приводить тип, если цель - скопировать строку. Только указатель pchar должен быть инициализирован.
Пример:
var Buf : array[byte] of char; // буфер из 256 символов
P : pchar;
S : string;
begin
p := @Buf; // указатель инициализирован
s:="qqq";
p:=s; // копирование строки
s:="www";
showmessage(s+" "+p); // здесь будет "www qqq"
end;
MBo (2002-07-26 12:43:00) [14]
p:pchar;
s:string;
procedure TForm1.Button1Click(Sender: TObject);
begin
s:="qqq";
p:=pchar(s);
s:="www";
showmessage(s+" "+p);
end;
Александр Малыгин (2002-07-26 12:29:00) [15]Отнюдь!
Таким образом полученная строка ничем не отличается отS := "Константа";
Anatoly Podgoretsky (2002-07-26 12:26:00) [16]SPeller © (26.07.02 02:53)
Ты заставил меня засомневаться в Борланде, проверил я хелп, все в порядке.
A PChar is a pointer to a null-terminated string of characters of the type Char.
Сказано абсолютно все, ничего не удаяно и добавить нечего, рсталось у меня обно сомнение, на этот раз не на Борланда, а на тебя, может ты не знаешь английского языка в объеме достаточном для программирования, тогда вот передод:
PChar является указателем на строку символов типа Char, ограниченную нулем.
От переводчика:Символ ноль в Паскале указывается как #0 и имеет значение $0, знак ноль пригоден для указания любых символов в диапазоне от 0 и выше.
MBo (2002-07-26 12:24:00) [17]>Александр Малыгин
конечно, часто этого достаточно, но беда случится при изменении (с реаллокацией) таким образом полученных строк
Александр Малыгин (2002-07-26 12:16:00) [18]Люди! Будьте проще!
В Object Pascal тип string настолько совместим с pchar, что можно делать присваивания туда и обратно без приведения типов и использования функций. Компилятор все понимает и сам копирует содержимое строки. Разумеется, память должна быть уже выделена.
var S : string;
P : pchar;
...
P := S;
S := P;
P.S. Речь, конечно, идет о длинных строках (AnsiString, не ShortString).
SPeller (2002-07-26 02:53:00) [19]2 Anatoly Podgoretsky © (25.07.02 20:28)
В общем случае да. Но вот мне кажется, что информация, содержащаяся в хелпе, должна восприниматься после одного-двух-трёх прочтений, а не после детальнейшего изучения и анализирования каждого предложения из двух-трёх десятнков топиков.
Anatoly Podgoretsky (2002-07-25 20:28:00) [20]Мне кажется, что с хелпами все в порядке