Delphi: Загадочный тип PCHAR (исходники)Источник: programmersclub
Здравствуйте, дельфисты! Сегодня вам поведую, что это за тип PCHAR. И как его корректно использовать. Этот тип упоминается во всех API функциях, которые принимают в качестве параметра какое-либо строковое значение. Сначала я расскажу вам про тип string. Тип string является главным преимуществом языка Pascal над языком С. Именно из-за этого типа программы, написанные на Pascal, весят больше, чем программы, написанные на С. Все знают, что тип string является массивом, котором каждый элемент является типом CHAR (следовательно, юникодовский тип WideString - массив из WideChar). Только размер этого массива неизвестен заранее и при каждом присваивании его длина изменяется. Но так же можно и при объявлении ограничить размер строки. Но размер строки ограничивается только формально, потому что нельзя обратиться к элементу массива больше чем размер строки указанной в разделе var. Конечно, размер каждой строки должен быть не более 2ГБ, примерно 2 миллиарда символов (для widestring 1 миллиард символов, так как один символ задаётся 2 байтами). Так как строка это массив, следовательно, через квадратные скобки можно обращаться к каждому элементу массива. Str:='programmersclub.ru'; После данных манипуляций переменная str будет равна 'ProgLammersclub.ru', замечу, что первый символ в строке имеет индекс 1. Так как тип string и тип array of char сходны следователь их можно присвоить друг к другу. Но, при присваивании переменной массива переменной строки будет ошибка, так как у массива мы жёстко задаём размер массива, а у строки мы не знаем длину даже при её ограничении. Var Обращаться к 55 символу переменной str2 уже нельзя, но физически в памяти он существует. При получении указателя на строку возвращается адрес первого символа в строке, значит, такие выражения одинаковы: P1:=@str; Теперь тип PCHAR. Фактически тип PCHAR это указатель на тип CHAR. Это понятно и потому как он назван. По "программеским" правилам при объявлении нового типа типизированных указателей берётся тип, на который указывает указатель и спереди ставится буква P. Вот его объявление: Type Ну, если этот тип указывает на только один символ, то, как же функции понимают параметры, которые мы передаём им. Всё очень просто. Каждая строка, переданная в качестве параметра какой либо функции должна иметь в конце символ #0. Функция по указателю находит первый символ строки и идёт дальше пока не наткнётся на символ #0. Delphi автоматизировала преобразование строки когда в параметре мы указываем саму строку: MessageBox(0,'привет','привет',0) здесь автоматика, а почему не автоматика при указывании переменных я не знаю. Мы всегда пишем MessageBox(0,pchar(str),pchar(str),0); Всё нормально. Тот же результат при использовании указателей. MessageBox(0,@str,@str,0); Это потому что массивы обычно заполняются нулями. var В сообщении перед двойкой стоит какой то символ. Это потому что нумерация в Delphi может начинаться с любого индекса, в данном случае она начинается 1, а 0 символ не используется. Значит то, что я вам сказал в начале это неправильно: А массив выводится нормально, потому что Delphi автоматически правит указатель на массив. Не знаю почему, но вместо двоек выводится не пойми что. Мистика!!! var Отсюда понятно что изначально все переменные заполняются нулями. И переменная STR тому не исключение. Как видите в заголовке есть символы 'hs' потом квадратик потом двойки. Всему есть разумное объяснение. Строка STR_ARR не кончается нулём, следовательно, функция не нашла нуль только в конце строки STR_ARR и пошла дальше к переменной STR, поэтому строка STR_ARR получилась такой длинной. Квадратик в после строки 'hs' понятен из первого примера. Вот такие пироги. Изначально казалось, что тип string проще и лучше, а получилось как всегда! Тип string принёс нам массу неприятностей. Поэтому C++ намного популярнее Delphi. Вот такими словами кончается моя очередная статья. Руслан Аблязов
|