Dziwny problem z tablica w funkcji - referencja

0

Witam,

w moim programie znalazłem pewien błąd, który się powtarza, a wg mnie nie powinien. Z racji obszerności kodu przedstawie tylko testowy z samym błędem:

program test;
uses crt;
var a:array [1..5] of integer;
    i:integer;
function tablica(var tab:array of integer):byte; {referencja przy tablicy tab, wiec elementy globalnej tablicy a powinny sie zmieniac}

begin
tab[1]:=3;
tab[4]:=1;

end;

BEGIN
clrscr;
for i:=1 to 5 do a[i]:=i;

tablica(a);
for i:=1 to 5 do writeln(a[i]); {no i sie zmieniaja tylko tak, jakby w funkcji tablica() występowało numerowanie od 0 
a nie 1 do 5 jak w pascalu, co widac przy wypisaniu}
repeat until keypressed;
END.

Po uruchomieniu tego programu otrzymujemy takie wyniki:

 
1 //a[1]
3 //..
3
4 
1//a[5]

Funkcja powinna zmienic pozycje 1 na 3, tutaj zmienia pozycje 2, i pozycje 4 na 1, tutaj zmienia pozycje 5.

Nie wiem czy czegos nie wiem, czy jak?

Prosze o pomoc jak rozwiazać ten problem, występuje on nie tylko przy tablicach referencyjnych, samo operowanie tablicą w funkcji zaczyna sie jakby od 0

2

Przy takim przekazywaniu tablica zmienia numeracje na od 0. Jak chcesz aby numeracja pozostała to przekaż jako normalny typ:

type TFiveInt=array [1..5] of integer;
var a:TFiveInt
    i:integer;
function tablica(var tab:TFiveInt):byte;
0

No własnie, nie wiedzialem skad to, dziekuje za szybką odpowiedź.

Swoją drogą w jakim celu to sie zmienia nie wiem nadal, ale zakladam ze tworcy jezyka wiedza lepiej.

0

Swoją drogą w jakim celu to sie zmienia nie wiem nadal

Chodzi o to, że Twoja deklaracja wskazuje dowoloną, dynamiczną, tablicę. Twórcy FPC nazywają to Open Array. Jako że Open Array jest specjalnym przypadkiem Dynamic Array, to ona także jest numerowana od 0. Więc rozkazałeś tablicę statyczną kompilatorowi przerobić na dynamiczną, otwartą. I on to zrobił i przekazał to wewnątrz jako właśnie open array.
Wiele osób popełnia ten błąd jako że z nawiasami mówiącymi o zakresie "nie działa" co również wynika z niewiedzy na temat typowania.

0

Swoją drogą w jakim celu to sie zmienia nie wiem nadal, ale zakladam ze tworcy jezyka wiedza lepiej.

@_13th_Dragon nie do końca poprawnie sformułował swoją odpowiedź - tak naprawdę numerowanie się nie zmienia: każda tablica w Pascalu (i właściwie większości języków) jest wewnętrznie indeksowana od zera, a jedynie deklarując tablicę w stylu Var Tab: Array[10..25] of uint8; kompilator automatycznie przy jej odwołaniach odejmuje od indeksu właściwego dolną granicę, czyli w tym wypadku 10.
Tak więc pisząc Tab[23] := 90; w rzeczywistości (internalsowo/wewnętrznie) odwołujemy się do Tab[23-10] := 90;...
...stąd nie występuje żadna zmiana numerowania jako-tako.

Btw, w deklaracji Procedure Foo(var Tab: Array of Integer);, Tab jest tzw.open-array - to coś innego, niżeli:

Type TArray = Array of Integer;
Procedure Foo(var Tab: TArray);

1 użytkowników online, w tym zalogowanych: 0, gości: 1