Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.07.2013, 14:47   #1
Иаковъ
 
Регистрация: 06.09.2011
Сообщений: 5
По умолчанию не могу понять пример работы с указателем

Друзья, пытаюсь разобраться с указателями и не могу понять пару моментов.
Есть пример:

program InterpretMem;
{$APPTYPE CONSOLE}
var
1) PI: PInteger;
2) PC: PAnsiChar;
begin
3) New(PI);
4) PI^ := $006D654D; // Байты $4D $65 $6D $00
5) PC := PAnsiChar(PI); // Теперь оба указателя указывают на одно место в памяти
6) Writeln(PI^); // Печатаем число.
7) Writeln(PC^); // Печатаем один символ ($4D).
8) Writeln(PC); // Печатаем строку в стиле C (байты $4D $65 $6D $00 интерпретируются как PChar)
Dispose(PI);
Readln;
end.

вопрос 1.
Мы объявили два указателя. Потом говорим в 5) PC := PAnsiChar(PI), что в моем понимании означает присваивание PC адреса того же участка памяти, куда указывает PI. Только PC указывает на символьные данные, а PI на целочисленные. Не могу понять совершенно строчку 8, ведь по идее в PC находится только адрес участка памяти, почему выводится Mem? Мы же должны разименовать PC, чтобы получить значение по этому адресу, но даже сделав это в 7) мы получим только вывод 'М'. Почему выводится значение, если вроде как по логике должен быть максимум адрес?

вопрос 2.
строка: PC: PAnsiChar, ведь это же равносильно PC: ^AnsiChar?
Почему тогда возникает ошибка если везде заменить PAnsiChar на ^AnsiChar?
Иаковъ вне форума Ответить с цитированием
Старый 03.07.2013, 14:54   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
ведь по идее
Нет. write распознает типы. Если PC: PAnsiChar то эта процедура, автоматически понимает что нужно взять данные по указателю и распечатать.
Цитата:
тогда возникает ошибка если везде заменить PAnsiChar на ^AnsiChar?
Какая ошибка? Предлагаешь включать телепаторы?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 03.07.2013, 15:00   #3
Иаковъ
 
Регистрация: 06.09.2011
Сообщений: 5
По умолчанию

вот какие ошибки компилятора возникают
var
PI: PInteger;
PC:^AnsiChar;
begin
New(PI);
PI^ := $006D654D; // Байты $4D $65 $6D $00
PC := ^AnsiChar(PI); // [dcc32 Error] Project1.dpr(16): E2010 Incompatible types: 'Pointer' and 'Char'
Writeln(PI^); // Печатаем число.
Writeln(PC^); // Печатаем один символ ($4D).
Writeln(PC); // [dcc32 Error] Project1.dpr(19): E2054 Illegal type in Write/Writeln statement
Dispose(PI);
Иаковъ вне форума Ответить с цитированием
Старый 03.07.2013, 16:39   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Incompatible types: 'Pointer' and 'Char'
А так никто не присваивает )
Приведение типа по другому нужно делать: PC:=PAnsichar(pi)
Только это глупо, потому как типы разные.
Цитата:
Illegal type in Write/Writeln statement
Тут свои особенности. Нужно приводить к типу PAnsiChar в таком случае. Впрочем по второй ошибке я точно не скажу. Никогда writeln не использую с указателями.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 04.07.2013, 06:09   #5
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Цитата:
Сообщение от Иаковъ Посмотреть сообщение
Код:
  Writeln(PC);          // [dcc32 Error] Project1.dpr(19): E2054 Illegal type in Write/Writeln statement
Если надо напечатать адрес, куда указывает данный указатель, то можно так Writeln(Integer(PC)); если особо хочется, то ещё и отформатировать в хекс-число
phomm вне форума Ответить с цитированием
Старый 04.07.2013, 11:28   #6
Иаковъ
 
Регистрация: 06.09.2011
Сообщений: 5
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
А так никто не присваивает )
Приведение типа по другому нужно делать: PC:=PAnsichar(pi)
если изменить только объявление переменной, то тоже возникает ошибка.
var
PI: PInteger;
PC: ^AnsiChar;// изменил PC:PAnsiChar
begin
New(PI);
PI^ := $006D654D; // Байты $4D $65 $6D $00
PC := PAnsiChar(PI);//[dcc32 Error] Project1.dpr(16): E2010 Incompatible types: 'Pointer' and 'PAnsiChar'

phomm, увидел мой немой вопрос . Я как раз параллельно пытался правильно разузнать адрес ячейки
Иаковъ вне форума Ответить с цитированием
Старый 04.07.2013, 11:45   #7
DiemonStar
Старожил
 
Регистрация: 08.02.2012
Сообщений: 2,173
По умолчанию

Цитата:
Illegal type in Write/Writeln statement
а чего вы хотели? по-сути это несколько overload-процедур с заранее прописанными параметрами. Т.е. вариант с PAnsiChar присутствует, а вариант с ^AnsiChar - нет. Вот и выдает ошибку.

если хотите получить значение указателя, то можно попробовать так:
Код:
Var 
  P : PAnsiChar;
  A : LongInt absolute P;
или воспользоваться массивом байтов...
Правильно поставленная задача - три четверти решения.

Последний раз редактировалось DiemonStar; 04.07.2013 в 11:50.
DiemonStar вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Пример работы с потоками, не могу разобраться! Kaaatso Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 27.05.2012 07:36
Пример работы в stl со строками ArniLand Общие вопросы C/C++ 2 30.06.2011 08:49
Пример работы с TThread Shouldercannon Общие вопросы Delphi 2 12.07.2010 16:47
Объясните пример работы с файлами. spamer Общие вопросы C/C++ 6 04.06.2009 01:55