Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Delphi]Вопросы использования AnsiString, PChar, String


Автор: malor 3.6.2007, 16:48
Вопросы по книгам:
"Программирование в Delphi. Учебник по классическим версиям Delphi" Архангельский, 2006.
"Delphi. Программирование на языке высокого уровня" Фаронов В.В.,2006.
"Библия Delphi" Михаил Фленов, 2005.

1. Зачем в Delphi используется название типа String если есть идентичные ему типы ShortString(при включенной директиве $H-) и AnsiString(при включенной директиве $H+)?
Архангельский с.869. 

2. Зачем используются два типа, хранящих одно и то же - Char и AnsiChar? Почему не выкинут один из них. 
Архангельский с.869.

3. Архангельский с.870: "Строки с нулевым символом в конце представляет собой массивы символов с индексами, начинающимися с 0".
Фаронов на с.137 пишет: "Символы в строке нумеруются, начиная с 1". 
Под что использован элемент массива с индексом 0?

3. В чем отличие String(AnsiString) от PChar?

4. Архангельский с.870:"Переменная типа AnsiString является указателем на динамически 
выделяемую область памяти, в которой хранится строка"
Тогда в чем отличие их от PAnsiString и PString,упомянутых в разделе 14.13 на с.877?

5. Фленов с.94 в табличке:
Максимальная длина строки AnsiString - 231 символ. Почему ?

6. Фленов с.101: "C типом string в этом отношении просто: если мы не указываем его размер, то Delphi может зарезервировать максимальный размер - 255 символов. У PChar нет такого максимального размера и поэтому вся ответственность за выделения памяти под эту переменную ложится на программиста"
А как же 2 Гб?

7.  Длина у ShortString в самом первом байте хранится в виде числа?

8. Фаронов с.139:"32-разрядные версии Windows используют три сорта символов: однобайтный символ ANSI, двухбайтный символ и символ Unicode... двухбайтный символ, в котором младший байт обычно кодируется семибитным ASCII-кодом, а старший указывает, как должен трактоваться этот код(каким символом он будет отображаться на экране или в документе)". 
Где можно подробнее почитать об этом?

9. Фаронов с.138. Пример использования PChar:
Код
var 
  pcS: PChar;
begin
  pcS:='Строка символов';
  ... и т.д. ...
end;

Аналогичный пример есть у Архангельского на с.871.

Фленов с.101:
"Тип PChar нельзя использовать напрямую, потому что это указатель на память. Поэтому указателю должна быть присвоена некоторая область. Это значит, что следующий пример будет недействителен
Код
var
  s:PChar;
begin
  s:='Привет!';
end;

В примере объявлена строка s типа PChar и сделана попытка присвоить ей текст. Такая операция 
невозможна, потому что s - указатель и пока ни на что не указывает".

Где правильно?

Delphi 7, WinXP

Автор: Alexeis 3.6.2007, 18:43
Цитата(malor @  3.6.2007,  16:48 Найти цитируемый пост)
1. Зачем в Delphi используется название типа String если есть идентичные ему типы ShortString(при включенной директиве $H-) и AnsiString(при включенной директиве $H+)?
Архангельский с.869. 

  Так для этого и существует, что тип String зависит от директив компиляции, а другие нет. Это для совместимости с кодом паскаля. 

Цитата(malor @  3.6.2007,  16:48 Найти цитируемый пост)
 Зачем используются два типа, хранящих одно и то же - Char и AnsiChar? Почему не выкинут один из них. 
Архангельский с.869.

  AnsiChar просто псевдоним типа Char. Это не 2 разных типа а один с разными именами.


Автор: Alexeis 3.6.2007, 18:44
Для домашних заданий, курсовых, существует "Центр Помощи".

Тема перенесена! 

Автор: Romkin 3.6.2007, 22:17
Выкинь Архангельского! Или используй как подставку. Только не читай.
Фленов тоже лажает smile
Фаронов - вроде ничего, но лучше читай классику, Тексейра и Пачеко, Кэнту и тд.
1. Тип string прописан в стандарте Паскаля, директива - для обратной совместимости. Наследство, так сказать. Остальные два типа - для независимости от директивы. Не забывай, что есть еще WideString smile Никто не исключает, что в будущем string будет соответствовать ему, а не ansistring. И, похоже, довольно скоро станет так...
2. Char - опять же, стандарт. И никто не гарантирует, что в будущем он останется однобайтовым. ansiChar - всегда будет 1 байт.
Если в процедуре ты опираешься на факт, что строка и символ - однобайтовые, (например, преобразуя тип) хорошим тоном считается явное указание приставки ansi. Когда это не важно - используют string.
3. Представление типов впамяти подробно описано в справке, раздел Memory Management. Кратко: Архангельский соврамши. У ShortString элемент с индексом 0 хранит длину строки, поэтому ее максимальная длина 255 байт. У ansiString нулевого элемента нет smile
4. Да. Память под строку выделяется при присвоении (если не углубляться в детали, а надо бы... см справку). Поэтому для s:ansistring сравнения s = '' и s = nil равноценны. PAnsiString - указатель на указатель, что такого? smile
5. Фигня. Максимальная длина ansistring - maxint (4 байта со знаком), shortstring - 255 байт.
6. Опять путаница shortstring и ansistring. В Delphi сейчас принято string = ansistring, и этот тип совместим с PChar (точнее, с PAnsiChar). Так сделано. То есть, если ты уверен, что в функции переменная PChar меняться не будет, смело давай туда PChar(s), где s: ansistring. Если внутри меняется - так делать нельзя.
7. Да. Известный прием byte(s[0]) дает длину. Но не рекомендуется, есть функция Length.
8. Форматов полно smile ищи поисковиками, посмотри Википедию.
9. Фленова тоже выкидывай. Достал своими ошибками smile Это соглашение компилятора: память под строковую константу выделяется еще на этапе компиляции, в s записывается ссылка на эту область памяти. Достаточно просто попробовать smile

Автор: malor 11.7.2007, 11:51
На строке 
 StrLCopy(PChar(simlist[i].nomer),PChar(st),10);
выдает:
Access violation at address 005890C2 in module 'MyProga.exe'. Read of address 40C14E78.


код процедуры такой:
Код
AssignFile(simF, ExtractFilePath(Application.ExeName)+'sim.txt');
  Reset(simF);
  while not Eof(simF) do
    begin
      Readln(simF,st);
      StrLCopy(PChar(simlist[i].nomer),PChar(st),10);
      ... и т.д. ...


simF объявлен как TextFile, simlist - массив структур, поле nomer объявлено как String. В него хотел закинуть первые десять символов из прочитанной строки.

Delphi 7

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)