IPB
ЛогинПароль:

 
 Ответить  Открыть новую тему 
> значения индекса, массив, указатель и не только...
compiler
сообщение 18.07.2007 16:34
Сообщение #1


Человек
*****

Группа: Пользователи
Сообщений: 1 050
Пол: Мужской
Реальное имя: Станислав

Репутация: -  3  +


есть програмка (на FP)
program PointerArray;  
//на основе doc/ref/Types(3) / Pointers(3.4) 
var i : Longint;  
	p : ^Longint;  
	pp : array[0..100] of Longint;  
function proc():boolean;
var j: longint;
begin
	proc:=true;
	for j := 0 to 105 do  
		if p[j]<>pp[j] then  proc:=false ; 
		
end;
begin  
	for i := 0 to 100 do pp
:= i; { Fill array }  
	p := @pp;
	WriteLn (i:3);
	if proc() then  
		WriteLn ('YES !')  
	else 	WriteLn ('Ohoh, problem !');		
	for i := 0 to 105 do begin
		p := @pp[i];
		WriteLn (i:3);
		if proc() then  
			WriteLn ('YES !')  
		else 	WriteLn ('Ohoh, problem !');		
	end;
	readln;
	read;
end. 

интересует строчка [i]p := @pp[0]; что знасит этот индекс(0)? если пишем p := @pp; все работает так-же, но если указываем другой индекс получаем проблемку...

Сообщение отредактировано: compiler - 18.07.2007 16:35


--------------------
Спасибо!
Удачи!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 18.07.2007 17:00
Сообщение #2


Гость






Цитата(compiler @ 18.07.2007 16:34)
что знасит этот индекс(0)?
Значит, что за точку отсчета при обращении к массиву через указатель, принимается нулевой элемент (в данном случае).

Цитата(compiler @ 18.07.2007 16:34)
если пишем p := @pp; все работает так-же, но если указываем другой индекс получаем проблемку...

А вот смотри, почему ее получаем:

первая итерация - p := @pp[0], при заходе в функцию Proc значение p[j] сравнивается с pp[j]. Поскольку в свою очередь, базовый индекс (та самая точка отсчета) P равняется 0, то P[j] = pp[base + j] = pp[j]. Что проверяется? Условие p[j] = pp[j]? Подставь то, что я написал, будет истина.

Вторая (и последующие) итерации: базовый индекс больше нуля, следовательно в Proc проверяется условие pp[base + j] = pp[j] при base > 0. Если посмотреть, как ты заполнял массив pp, то понятно, что ни при одном base > 0 равенства не будет.

Кстати, у тебя еще и выход за границу массива происходит, ты в курсе?
 К началу страницы 
+ Ответить 
compiler
сообщение 18.07.2007 17:31
Сообщение #3


Человек
*****

Группа: Пользователи
Сообщений: 1 050
Пол: Мужской
Реальное имя: Станислав

Репутация: -  3  +


Цитата(volvo @ 18.07.2007 17:00) *
Кстати, у тебя еще и выход за границу массива происходит, ты в курсе?
ага... и если p := @pp; и p := @pp[0]; обычно ведут себя одинаково то теперь они проявляют интересные свойства...
program InterestingTest;  
var i : Longint;  
	p,p2 : ^Longint;  
	pp, pp2 : array[0..100] of Longint;  
begin  
	for i := 0 to 100 do  pp[i] := i;   
	pp2:=pp;
	p := @pp[0];
	p2 :=@pp2;
	for i := 0 to 150 do if p[i]<>p2[i]then
                WriteLn (i:4,'---------','p=',p[i]:3, '----------','p2=',p2[i]:3);
	readln;
	read;
end.
хотя... тест довольно не однозначный...
куда мы получаем доступ обращаясь за границы массива?


--------------------
Спасибо!
Удачи!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 18.07.2007 17:43
Сообщение #4


Гость






Цитата
куда мы получаем доступ обращаясь за границы массива?

program InterestingTest;
var i : Longint;
	p,p2 : ^Longint;
	pp, pp2 : array[0..100] of Longint;
        s: string = 'compiler from pascalnet.ru';
begin
	for i := 0 to 100 do  pp[i] := i;
        for i := 0 to length(s) do
          pp2[i] := ord(s[i]);

        p := @pp[100];
        for i := 0 to length(s) do
          write(chr(p[i]));
        writeln;

	readln;
	read;
end.

Теперь понятно, куда?
 К началу страницы 
+ Ответить 
compiler
сообщение 18.07.2007 17:58
Сообщение #5


Человек
*****

Группа: Пользователи
Сообщений: 1 050
Пол: Мужской
Реальное имя: Станислав

Репутация: -  3  +


Цитата(volvo @ 18.07.2007 17:43) *
Теперь понятно, куда?
не совсем... я получил следующий текст
Цитата
d***{символ}compiler from pascal.ne
, где * -- пробел, а {символ} -- в данной кодировке есть некая стрелочка влево(!)

Сообщение отредактировано: compiler - 18.07.2007 17:59


--------------------
Спасибо!
Удачи!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 18.07.2007 18:48
Сообщение #6


Гость






Да, привел немного некорректный пример... Вот так будет лучше:

program InterestingTest;
var
  i : Longint;
  // Во-первых, строка - перед массивами, т.е, ты получаешь доступ НЕ к строке
  s: string = 'compiler from pascalnet.ru'; 

  p,p2 : ^Longint;
  pp, pp2 : array[0..100] of Longint;

begin
        // Заполняем массив кодами двоек, чтоб было четко видно границу...
	for i := 0 to 100 do  pp[i] := ord('2'); 

        // А во второй массив пишем коды элементов строки
        for i := 0 to length(s) do begin
          pp2[i] := ord(s[i]); // <-- с нулевого индекса pp2
        end;

        p := @pp[100]; // Теперь начинаем смотреть с 100-го эл-та массива pp
        for i := 0 to length(s) do begin
          write(chr(p[i]));
        end;
        writeln;

	readln;
	read;
end.

Что имеем на выходе? Вначале - двойка, которая завершает массив PP, потом нулевой символ (откуда взялся - непонятно, попробую посмотреть позже), следующий символ (та самая стрелочка влево) - это длина строки = 27, проверяется элементарно: при компиляции с ключом {$H+} этого символа не будет. Ну, а потом - уже остальные символы...
 К началу страницы 
+ Ответить 
compiler
сообщение 18.07.2007 19:05
Сообщение #7


Человек
*****

Группа: Пользователи
Сообщений: 1 050
Пол: Мужской
Реальное имя: Станислав

Репутация: -  3  +


спасибо, вроде разобрался... (кроме трех неизвестных символов)


--------------------
Спасибо!
Удачи!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 28.07.2025 9:37
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"