Siemka.
Ostatnio trochę poczytałem i znalazłem takie coś, jak Array Of Const
(Free Pascal).
Wiem, jak to zadeklarować i jak zrobić, aby działało, lecz mam jedno pytanie:
Aby takie coś użyć muszę wywołać z kodu procedurę (np): Wyswietl(['Tekst', 25]);
I tak się zastanawiam, czy nie można by się pozbyć tych kwadratowych nawiasów ([
oraz ]
) tak, aby było to tak: Wyswietl(Tekst, 25)
.
Szukałem, lecz nie znalazłem odpowiedzi, liczę na to, że tutaj dostanę jakąś podpowiedź (chyba, że tak się nie da).


- Rejestracja:ponad 17 lat
- Ostatnio:ponad 8 lat
- Postów:1105
Jeżeli Tekst
to string to musi być w apostrofach.



- Rejestracja:ponad 21 lat
- Ostatnio:2 minuty
Odpowiedź brzmi: tak powinno być. To nie jest to samo co parametry ...
w językach typu C, mimo że można tego w ten sposób użyć (np. zasymulować printf()
).
array of const
ma taką przewagę, że funkcja wie ile parametrów otrzymała, i zna ich typy. a ponieważ parametry są zgrupowane w tak naprawdę jeden i to nazwany, przekazanie ich gdzieś dalej jest banalne.
Istnieje coś takiego jak varargs
, ale służy do importowania funkcji napisanych w C z zewnętrznych bibliotek. wtedy nie trzeba nawiasów:
function printf(fmt:pchar):longint; varargs; cdecl; external 'msvcrt.dll';
const nl = #13#10; // nowa linia
begin
printf('ala ma %d %s'+nl, 2, 'koty');
end.
Powyższe można zapisać też z array of const
function printf(fmt:pchar; args:array of const):longint; cdecl; external 'msvcrt.dll';
const nl = #13#10;
begin
printf('ala ma %d %s'+nl, [2, 'koty']);
end.
Ale funkcje pisane w pascalu muszą używać array of const, a nie varargs.
Poprzednie zdanie jest kłamstwem. Można się bardzo uprzeć:
{$mode objfpc}
procedure wyswietl_inty(ile:integer); cdecl; varargs; external;
procedure wyswietl_inty_args(ile:longint; inty:array of const); cdecl; [alias:'_wyswietl_inty'];
var pargs:plongint;
i:integer;
begin
pargs:=@(plongint(@ile)[1]);
for i:=0 to ile-1 do
write(pargs[i],' ');
writeln;
end;
begin
wyswietl_inty(3, 1,2,3);
end.
ale:
• nie musi to być przenośne między architekturami (przykład działa dla win 32-bit)
• funkcja nie wie ile i jakie parametry otrzymała, więc trzeba to podać w inny sposób (tu: parametr ile
i założenie, że będą tylko inty)
• nie ma żadnej kontroli nad tym, czy prawidłowe parametry przekazujemy (można zrobić wyswietl_inty(1, 'dupa')
i dostaniemy śmieci)
Z tych powodów funkcje ze zmienną liczbą parametrów w C/C++ nadają się tylko do zastosowań typu printf
, gdzie zawsze przekazywany jest string z „formatem” określający ile i jakie parametry są przekazywane.
Za to we Free Pascalu i Delphi przy wykorzystaniu konstrukcji array of const wiemy ile i jakich typów są to parametry — niewielkim kosztem tych dodatkowych nawiasów.

- Rejestracja:ponad 13 lat
- Ostatnio:prawie 3 lata
Azarien napisał(a)
array of const
ma taką przewagę, że funkcja wie ile parametrów otrzymała, i zna ich typy. a ponieważ parametry są zgrupowane w tak naprawdę jeden i to nazwany, przekazanie ich gdzieś dalej jest banalne.
Poza tym przypadkiem gdy chcesz przekazać dalej całą tablicę... ;-)

- Rejestracja:ponad 20 lat
- Ostatnio:około rok
kiedyś napisałem funkcję sprintf, używało się jej tak: write(cośtam, ileśtam, ....., sprintf(b));
początek funkcji wyglądał tak:
function sprintf(var b:string):string;
begin
sprintf:='';
......
to co write miało wyświetlić trafiało do przekazywanego przez zmienną stringa.
robiłem sztuczki z chyba textbuf(output), są tam wskaźniki do cyklicznego bufora, można wydłubać co siedzi w buforze po czym go opróżnić.

- Rejestracja:ponad 21 lat
- Ostatnio:2 minuty
Poza tym przypadkiem gdy chcesz przekazać dalej całą tablicę...
no jak to?
procedure foo(args:array of const);
begin
...
end;
procedure bar(args:array of const);
begin
foo(args);
end;
to co write miało wyświetlić trafiało do przekazywanego przez zmienną stringa.
nowsze wersje Free Pascala mają proceduręwritestr
:
var s:string;
...
writestr(s,'ala ma ',2,' koty');
robiłem sztuczki z chyba textbuf(output)
bardziej wspieranym sposobem byłoby zdefiniowanie własnej procedury zamiast assign
(np. AssignString
) która by kojarzyła stringa ze zmienna typu text
(text jest rekordem normalnie zawierającym wskaźniki na funkcje I/O do pliku). potem byś korzystał z write/writeln:
var s:string; // string do którego będzie szedł tekst
var st:text;
...
assignstring(st,@s); // zamiast assign, pomijamy co ta funkcja zawiera...
write(st,'ala ma ',2,'koty'); // to idzie do stringa s
close(st);
ale ponieważ mamy writestr
, to nie jest to już potrzebne.

- Rejestracja:ponad 13 lat
- Ostatnio:prawie 3 lata
Azarien napisał(a)
Poza tym przypadkiem gdy chcesz przekazać dalej całą tablicę...
no jak to?
procedure foo(args:array of const);
begin
...
end;
procedure bar(args:array of const);
begin
foo(args);
end;
To było wieki temu kiedy z tym walczyłem, ale chodziło mi wtedy chyba bardziej o budowanie takiej tablicy, żeby przekazać dalej.
Np. w takim celu, żeby w bar() odczytać pierwszy element "args" i w zależności od niego przekazać do foo() albo stałą albo końcowe k elementów z "args".


- Rejestracja:ponad 21 lat
- Ostatnio:2 minuty
vpiotr napisał(a)
Ale może znasz sposób jak to zrobić - w funkcji bar przesłać "args" do "foo" z jednym parametrem dodatkowym - wewnątrz "args" (było potrzebne do jakiejś tam pochodnej writeln)
{$mode objfpc}
procedure print_args(args:array of const);
var i:integer;
begin
for i:=low(args) to high(args) do
case args[i].vtype of
vtinteger : writeln('integer : ',args[i].vinteger);
vtansistring : writeln('string : "',ansistring(args[i].vansistring),'"');
end;
end;
procedure insert_int(args:array of const; value:integer; idx:integer);
var len,i:integer;
args_arr:array of tvarrec;
begin
len:=length(args);
setlength(args_arr,len+1);
for i:=0 to idx-1 do
args_arr[i]:=args[i];
args_arr[idx].vtype:=vtinteger;
args_arr[idx].vinteger:=value;
for i:=idx to len-1 do
args_arr[i+1]:=args[i];
print_args(args_arr);
end;
begin
insert_int([1,2,'ala ma kota'], 99, 2);
end.
---------- New Program ----------
integer : 1
integer : 2
integer : 99
string : "ala ma kota"
Output completed (0 sec consumed) - Normal Termination
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.