Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.05.18;
Скачать: CL | DM;

Вниз

Pchar(s)^   Найти похожие ветки 

 
Vitec   (2008-04-15 19:18) [0]

подскажите пожалуйста, что означает запись: PChar(S)^
s- типа string PChar(S) - преобразуем строку в тип Pchar, а вот что означает значек ^ в конце?


 
Palladin ©   (2008-04-15 19:22) [1]

разименование указателя, бежим изучать основы паскаля...


 
Семеныч   (2008-04-15 19:25) [2]

По умолчанию S - это длинная строка. То есть, указатель на адрес ее тела (причем тело это заканчивается символом #0).

Тип PChar - это указатель на символ.

Значит, PChar(S) - это адрес первого символа строки S.

А PChar(S)^ - это сам первый символ строки (или символ #0, если строка пустая).


 
Anatoly Podgoretsky ©   (2008-04-15 19:53) [3]

> Vitec  (15.04.2008 19:18:00)  [0]

А зачем такие глупости делать, для работы со строками нет нужды приводить к PChar и далее делать разименование.


 
Vitec   (2008-04-15 20:09) [4]

Palladin,
угу, надо почитать, с указателями не подружился еще, без них обходился
Семеныч,
спасибо за разъяснения
Anatoly Podgoretsky
Пытаюсь разобраться в md5
function MD5String(const S: string): TMD5Digest;
begin
 Result := MD5Buffer(PChar(S)^, Length(S));
end;

нужно для функции MD5Buffer, которая используется для обработки данных разных типов


 
Anatoly Podgoretsky ©   (2008-04-15 20:21) [5]

> Vitec  (15.04.2008 20:09:04)  [4]

Это какой то бессмысленный код, вот если убрать каре, то будет рабочим.


 
Vitec   (2008-04-15 20:27) [6]

код как-раз прекрасно работает:
http://www.delphiworld.narod.ru/base/md5.html
в нем и разбираюсь.


 
Palladin ©   (2008-04-15 20:29) [7]


> Anatoly Podgoretsky ©   (15.04.08 20:21) [5]

это очень хитрый код... у меня доступа нет по http куда нибудь кроме delphimaster"a, но могу предположить, что объявление выглядит так
MD5Buffer(Var p; ...);


 
tesseract ©   (2008-04-15 20:30) [8]


> код как-раз прекрасно работает:


Это поймёт тебя компилятор или нет. Delphi иногда такое прощает.


 
tesseract ©   (2008-04-15 20:33) [9]


> это очень хитрый код... у меня доступа нет по http куда
> нибудь кроме delphimaster"a, но могу предположить, что объявление
> выглядит так


function MD5Buffer(const Buffer; Size: Integer): TMD5Digest;

т.е разименование тут роли сыграть не должно :-).


 
Palladin ©   (2008-04-15 20:34) [10]


> tesseract ©   (15.04.08 20:33) [9]

я так и предполагал const или var, очень даже должно, вместо нарыва на AV при s[1], мы хитро на уровне compiler magic приводим string к pchar и спокойно разименовываем


 
Johnmen ©   (2008-04-15 20:35) [11]


> Семеныч   (15.04.08 19:25) [2]
> По умолчанию S - это длинная строка. То есть, указатель
> на адрес ее тела (причем тело это заканчивается символом
> #0).

Не надо фантазий :)


 
tesseract ©   (2008-04-15 20:42) [12]


>  мы хитро на уровне compiler magic приводим string к pchar
> и спокойно разименовываем


Такие привычки надо ликвидировать, но тут сработает без проблем. "Плавающий AV " - плата за умность компилятора.


 
Vitec   (2008-04-15 21:01) [13]

Тогда еще вопрос, что такое плавающий AV? и почему s[1] может не прокатить?
P.s. про указатели уже почти дочитал :)


 
Игорь Шевченко ©   (2008-04-15 21:18) [14]


> Тогда еще вопрос, что такое плавающий AV?


Сегодня есть, завтра нет.


> почему s[1] может не прокатить?


может и прокатить


 
Vitec   (2008-04-15 21:46) [15]

Всем спасибо! И все же, из-за чего может возникнуть ошибка доступа к памяти при прямом обращении s[1], а не через указатели?


 
Palladin ©   (2008-04-15 21:58) [16]

как показывает практика, из-за специфики работы вызываемой функции, а точнее аффторов, ее писавших... которые были на столько чудаками на букву м, что проверяли корректность переданной длинны ASCIIZ... волшебники, мля...


 
tesseract ©   (2008-04-15 22:19) [17]


> волшебники, мля...


"И прям,  не волшебники" (С) Жмурки  

Из за специфики работы с памятью. Столько с GlobalAlloc натерпелся....


 
Игорь Шевченко ©   (2008-04-15 22:29) [18]

function MD5DigestCompare(const Digest1, Digest2: TMD5Digest): Boolean;
begin
 Result := False;
 if Digest1.A <> Digest2.A then
   Exit;
 if Digest1.B <> Digest2.B then
   Exit;
 if Digest1.C <> Digest2.C then
   Exit;
 if Digest1.D <> Digest2.D then
   Exit;
 Result := True;
end;

менять на

function MD5DigestCompare(const Digest1, Digest2: TMD5Digest): Boolean;
begin
 Result := (Digest1.A = Digest2.A) and (Digest1.B = Digest2.B) and (Digest1.C = Digest2.C) and (Digest1.D = Digest2.D);
end;


 
palva ©   (2008-04-15 22:37) [19]


> И все же, из-за чего может возникнуть ошибка доступа к памяти
> при прямом обращении s[1], а не через указатели?

Из-за того что нельзя обращаться к символам пустой строки. Обычно это приводит к чтению по нулевому адресу - так уж устроены строки.

{$APPTYPE CONSOLE}
var
 s: String;
 i: Integer absolute s;
begin
 s := "";
 WriteLn(Integer(PChar(s))); // 4207937
 // Здесь был выделен буфер, и туда скопирована пустая строка с завершающим нулевым байтом.
 WriteLn(Ord(PChar(s)^));    // 0
 WriteLn(i);         // 0
 WriteLn(Ord(s[1])); // попытка чтения по адресу ноль
end.


 
tesseract ©   (2008-04-15 22:50) [20]


>  Обычно это приводит к чтению по нулевому адресу - так уж
> устроены строки.


Хорошо, если,  по нулевому, иногда приводит к записи в реальную кучу. И  "плавающий AV" в подарок.


 
palva ©   (2008-04-15 22:56) [21]


> Хорошо, если,  по нулевому, иногда приводит к записи в реальную
> кучу.

На это моей фантазии не хватило.


 
Семеныч   (2008-04-16 00:27) [22]


> Johnmen ©   (15.04.08 20:35) [11]
>
> > Семеныч   (15.04.08 19:25) [2]
> > По умолчанию S - это длинная строка. То есть, указатель
> > на адрес ее тела (причем тело это заканчивается символом #0).
>
> Не надо фантазий :)


Заявление, потрясающее как своей информативностью, так и своей обоснованностью. Впрочем, здесь такое не редкость, как я успел убедиться. Увы.

Однако же, есть вот такой код

procedure TForm1.FormCreate(Sender: TObject);
var
 Source, Target: string;
 P: Pointer;
 i: integer;
begin
 Source := "qwerty";
 P := Pointer(Source);
 Target := "";
 for i := 1 to Length(Source) do
 begin
   Target := Target + PChar(P)^;
   P := Pointer(Cardinal(P) + 1);
 end;
 Caption := Target;
 P := Pointer(Cardinal(P) + 1);
 Caption := Format("%s #%d", [Target, Ord(PChar(P)^)]);
end;

Что мы видим из этого кода?
1. Что по умолчанию S - это длинная строка.
2. Что S есть указатель на адрес собственного тела.
3. Что тело это заканчивается символом #0.

Таким образом, код полностью подтверждает каждое слово в той самой моей фразе, которую Вы процитировали и почему-то посчитали фантазией. Не снисходя до пояснений и уж тем более, доказательств.

Уважаемый синештаноноситель! Я, конечно, понимаю, что пояснения и доказательства - дело не царское, но все же: не могли бы Вы все это хоть как-то прокомментировать?

Конечно, хотелось бы комментариев вразумительных. А не в том же духе.


 
Vitec   (2008-04-16 09:00) [23]

теперь понятно, прочитал заодно про ASCIIZ в википедии и какие с ним обычно бывают ошибки, а также из-за чего возникают Access Violation
всем еще раз спасибо за разъяснения!


 
Семеныч   (2008-04-16 09:16) [24]


> Johnmen ©   (15.04.08 20:35) [11]


Дополнение к [22]. Про азбуку (счетчик ссылок и размер в памяти) затрудняться не стоит. Надо сказать, что именно в цитате есть фантазия и почему. Ждем-с.


 
Leonid Troyanovsky ©   (2008-04-16 09:30) [25]


> Семеныч   (16.04.08 00:27) [22]

> 1. Что по умолчанию S - это длинная строка.
> 2. Что S есть указатель на адрес собственного тела.
> 3. Что тело это заканчивается символом #0.

Под умолчанием, видимо, подразумевается $H+.

А вот с телом не совсем точно. Разница проявляется
именно в пустой строке: указатель есть nil, и никакой
памяти для нее не распределено, т.е. он не указывает на #0,
в отличии от PChar("").

Ну, и точнее говорить не на "тело", а на распределенный
для строки блок, начинающийся с 12 байтового заголовка
по отрицательному смещению.

Все это доступно изложено в хелпе, которому и следует,
IMHO, в подобных случаях отсылать страждущих.

--
Regards, LVT.


 
Семеныч   (2008-04-16 10:22) [26]

> Leonid Troyanovsky ©   (16.04.08 09:30) [25]

>> 1. Что по умолчанию S - это длинная строка.
>> 2. Что S есть указатель на адрес собственного тела.
>> 3. Что тело это заканчивается символом #0.

> Под умолчанием, видимо, подразумевается $H+.

Естественно.

> А вот с телом не совсем точно. Разница проявляется
> именно в пустой строке: указатель есть nil, и никакой
> памяти для нее не распределено

Это тоже азбука. Но заметьте, что о пустой строке в приведенных выше пресловутых трех пунктах искомой цитаты нет ни одного звука. То есть, все три абсолютно верны.

О пустой строке я сказал лишь то (см. [2]), что PChar(S)^ - это "символ #0, если строка пустая". И это тоже абсолютно верно.

> Ну, и точнее говорить не на "тело", а на распределенный для строки блок,
> начинающийся с 12 байтового заголовка по отрицательному смещению.

Насколько помню, заголовок - это все же 8 байт (4 - счетчик ссылок и 4 - размер). Ну да ладно, суть не в этом.

Суть в том, что заголовок находится именно по отрицательному смещению, поэтому сам указатель содержит адрес именно первого символа строки и никакой другой. А это и есть адрес тела строки. Как видим, и здесь все абсолютно точно.

И, наконец: если уж что-то кому-то показалось неточным или неправильным, то надо было, видимо, написать, что именно и почему (как это сделали Вы - а то, что я с Вами не согласился, это уже другой вопрос и это тоже нормально).

Но почему же вместо этого здесь принято бросаться снисходительными и голословными поучениями?


 
Leonid Troyanovsky ©   (2008-04-16 13:26) [27]


> Семеныч   (16.04.08 10:22) [26]

> Насколько помню, заголовок - это все же 8 байт (4 - счетчик
> ссылок и 4 - размер). Ну да ладно, суть не в этом.

Ну, да. Это раньше еще был  allocSiz: Longint, sorry.

> То есть, все три абсолютно верны.

Я ж показал, что не абсолютно.
Т.е., для полноты не хватает именно пустой строки.

Кста потому,  PChar(S)^ - это "символ #0, если строка пустая",
(т.е. бестелесная), а Pointer(s) = nil - перечитай еще раз тезисы 2, 3.

--
Regards, LVT.


 
Johnmen ©   (2008-04-16 13:41) [28]


> Семеныч   (16.04.08 00:27) [22]
> Семеныч   (16.04.08 09:16) [24]
> Семеныч   (16.04.08 10:22) [26]

Кипит наш разум возмущенный (с) ?
Я думаю, к данному моменту уже успокоился...

Так вот.
Если ты начинаешь применять отформализованную демагогию и понятие абсолюта, то я, в этом же духе, на
> Но заметьте, что о пустой строке в приведенных выше пресловутых трех
> пунктах искомой цитаты нет ни одного звука.

вполне могу возразить:
Но заметьте, что о непустой строке в приведенных выше пресловутых трех пунктах искомой цитаты нет ни одного звука.

Вот такие дела...


 
Anatoly Podgoretsky ©   (2008-04-16 15:14) [29]

> Leonid Troyanovsky  (16.04.2008 13:26:27)  [27]

И при этом

> PChar(S)^ - это "символ #0, если строка пустая",

РеадОнли память, в сегменте констант, на это часто прокалываются, например с OemToChar(PChar(S), PChar(S))


 
Семеныч   (2008-04-16 15:56) [30]

> Johnmen ©   (16.04.08 13:41) [28]

1. Насчет формализованной демагогии - см. [11].

2. Вы не ответили на вопрос (последний абзац в [26]). Умышленно?


 
Johnmen ©   (2008-04-16 16:54) [31]


> Семеныч   (16.04.08 15:56) [30]
> 2. Вы не ответили на вопрос (последний абзац в [26]). Умышленно?

Да, умышленно. Ибо он для меня риторический.
Если для тебя он иной, то отвечаю:
Наверняка - не знаю, а о предположениях умолчу. Умышленно.


 
Семеныч   (2008-04-16 17:25) [32]

> Johnmen ©   (16.04.08 16:54) [31]

Тогда с себя и начни. Умышленно.


 
Johnmen ©   (2008-04-16 19:12) [33]


> Семеныч   (16.04.08 17:25) [32]
> Тогда с себя и начни. Умышленно.

Что конкретно мне начать с себя?



Страницы: 1 вся ветка

Текущий архив: 2008.05.18;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.045 c
15-1207119287
Ega23
2008-04-02 10:54
2008.05.18
А вот как сделано: регистрируешься на каком-нибудь сайте,


2-1208769333
Alexey
2008-04-21 13:15
2008.05.18
Ошибка в отчёте


3-1196084789
AntonUSAnoV
2007-11-26 16:46
2008.05.18
пропадает полоса прокрутки в dbgrid


2-1208426824
Вход в папку
2008-04-17 14:07
2008.05.18
вход в папку в компоненте DirectoryListBox


15-1207555479
vajo
2008-04-07 12:04
2008.05.18
Windows XP часто требует ввести код активации





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