Форум «Всё о Паскале» _ Теоретические вопросы _ указатели
Автор: lopata 15.12.2009 21:46
Только начала изучать указатели. Не совсем все понимаю. В частности не мог бы кто-нибудь объяснить простой пример :
program Pointer1; type TArr = array[1..5] of integer; var PArr: лТАгг; {Указатель на массив} Arr: TArr; i: integer; begin PArr := @Arr; {PArr содержит адрес первого элемента массива Arr} for i := 1 to 5 do begin Write(1,'-й элемент массива = '); Readln(PArrA[i]); {Учитывая то, что PArr указывает на первый элемент массива Arr, PArrA - это аналог идентификатора Arr} end; for i := 1 to 5 do begin PArr := @Arr[i]; {PArr содержит адрес i-го элемента массива Arr} Writeln(PArrA[1]); {PArrA - значение i-го элемента массива} end; end.
Не понятно почему указывает на первый элемент :
PArr := @Arr; {PArr содержит адрес первого элемента массива Arr}
и
PArr := @Arr[i]; {PArr содержит адрес i-го элемента массива Arr} Writeln(PArrA[1]); {PArrA - значение i-го элемента массива}
Совершенно непонятно что там делает Единица .Writeln(PArrA[1]);
Объясните пожалуйста и Не ругайтесь, только). Действительно хочу разобраться.
Автор: volvo 15.12.2009 23:04
Цитата
Не понятно почему указывает на первый элемент :
Потому что нумерация элементов массива начинается с 1. И если указатель указывает (хм... А как еще сказать, чтоб не было "масло масляное"?) на массив - это значит, что он указывает на начальный элемент массива (еще точнее - на первый его байт). В твоем случае начальный элемент - первый. Если сделать так:
type TArr = array[0 .. 4] of integer;
, то PArr будет указывать уже на нулевой (с индексом = 0) элемент массива.
Цитата
Совершенно непонятно что там делает Единица .Writeln(PArrA[1]);
Ты сначала программу поправь, потом продолжим, а то у тебя сейчас ничего компилироваться не будет, а говорить просто так - я не буду... (нет, ну там понятно, что должно быть, но почему ты сразу не проверила, компилируется программа или нет? Кто ж разбирается с примером, не зная, рабочий ли он вообще?)
Автор: lopata 15.12.2009 23:15
как бы тебе сказать...у меня все откомпилировалось...
PROGRAM Din; USES Wincrt; TYPE TArr = array [1..5] of integer; VAR PArr : ^TArr; Arr : Tarr; i : integer; Begin PArr := @Arr; for i := 1 to 5 do begin Write(i,'-tyi element of array = '); Read(Parr^[i]) end; for i := 1 to 5 do begin Parr := @Arr[i]; WriteLn(Parr^[1]); end; End.
Добавлено через 8 мин. и зачем указывать на первый элемент массива?
Автор: volvo 16.12.2009 1:31
Цитата
как бы тебе сказать...у меня все откомпилировалось...
Видишь ли, PArrA[1] и PArr^[1] - это разные вещи, тебе не кажется? Программа, приведенная в первом посте компилироваться не будет.
Цитата
и зачем указывать на первый элемент массива?
Затем, чтобы его напечатать. WriteLn ожидает в качестве параметров нечто, что он умеет печатать. (Это очень важно. Не просто список каких-то параметров, а именно тех, которые могут им обрабатываться). Теперь смотри, что происходило бы, если б мы передали
WriteLn(PArr^);
... А ничего хорошего. У тебя переменная PArr описана как ^TArr, то есть, фактически, разыменовывая ее (добавляя справа значок "^"), ты получаешь WriteLn(Область_памяти_интерпретируемая_как_ма ссив_типа_TArr); Но Write/WriteLn не умеют печатать массивы сразу, только поэлементно. Вот у тебя и выбор: либо получить ошибку "Не умею читать/писать переменные этого типа", либо передать что-то, что WriteLn умеет писать. А умеет она - только встроенные типы: всякие Integer-ы/Real-ы, String-и/Char-ы, и Boolean-ы. Никаких массивов...
Автор: lopata 16.12.2009 1:38
Цитата(volvo @ 15.12.2009 21:31)
Видишь ли, PArrA[1] и PArr^[1] - это разные вещи, тебе не кажется? Программа, приведенная в первом посте компилироваться не будет.