Difference between revisions of "Function/fi"

From Free Pascal wiki
Jump to navigationJump to search
(Created page with "{{Function}} Funktio eli '''function''' on rutiini, joka toisin kuin aliohjelma (procedure) palauttaa arvon. Funktion kutsu käytännössä ko...")
 
 
Line 1: Line 1:
 
{{Function}}
 
{{Function}}
  
Funktio eli '''function''' on [[Routine/fi|rutiini]], joka toisin kuin [[Procedure/fi|aliohjelma (procedure)]] palauttaa arvon. Funktion kutsu käytännössä korvautuu sen palautusarvolla. Jos [[sExtendedsyntax|<syntaxhighlight lang="pascal" enclose="none">{$extendedSyntax}</syntaxhighlight> kääntäjän kytkin (compiler switch)]] on pois päältä,  
+
Funktio eli '''function''' on [[Routine/fi|rutiini]], joka toisin kuin [[Procedure/fi|aliohjelma (procedure)]] palauttaa arvon. Funktion kutsu käytännössä korvautuu sen palautusarvolla. Jos [[sExtendedsyntax|<syntaxhighlight lang="pascal" inline>{$extendedSyntax}</syntaxhighlight> kääntäjän kytkin (compiler switch)]] on pois päältä,  
 
funktion kutsu ei voi esiintyä ei-tuottavina lauseina, vaan niiden on oltava osa lauseketta.
 
funktion kutsu ei voi esiintyä ei-tuottavina lauseina, vaan niiden on oltava osa lauseketta.
  
Sana <syntaxhighlight lang="pascal" enclose="none">function</syntaxhighlight> on [[Reserved word/fi|varattu sana]].
+
Sana <syntaxhighlight lang="pascal" inline>function</syntaxhighlight> on [[Reserved word/fi|varattu sana]].
  
 
== Palautusarvo ==
 
== Palautusarvo ==
  
 
Normaalin aliohjelman esittelyn lisäksi funktion esittely sisältää myös [[Data type/fi|palautustyypin]]: muodollisen parametriluettelon jälkeen tulee [[Colon/fi|kaksoispiste-]] ja palautustyyppi.  
 
Normaalin aliohjelman esittelyn lisäksi funktion esittely sisältää myös [[Data type/fi|palautustyypin]]: muodollisen parametriluettelon jälkeen tulee [[Colon/fi|kaksoispiste-]] ja palautustyyppi.  
Seuraava funktion esittely palauttaa esimerkiksi  [[Boolean/fi|<syntaxhighlight lang="pascal" enclose="none">boolean</syntaxhighlight>]] tyyppisen arvon.
+
Seuraava funktion esittely palauttaa esimerkiksi  [[Boolean/fi|<syntaxhighlight lang="pascal" inline>boolean</syntaxhighlight>]] tyyppisen arvon.
 
<syntaxhighlight lang="pascal">
 
<syntaxhighlight lang="pascal">
 
function myFunction(const firstParameter: real): boolean;
 
function myFunction(const firstParameter: real): boolean;
Line 28: Line 28:
 
end;
 
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
Jos <syntaxhighlight lang="pascal" enclose="none">{$modeswitch result+}</syntaxhighlight> on käytössä. Se asetetaan [[Mode ObjFPC|<syntaxhighlight lang="pascal" enclose="none">{$mode objFPC}</syntaxhighlight>]] ja [[Mode Delphi|<syntaxhighlight lang="pascal" enclose="none">{$mode Delphi}</syntaxhighlight>]],  
+
Jos <syntaxhighlight lang="pascal" inline>{$modeswitch result+}</syntaxhighlight> on käytössä. Se asetetaan [[Mode ObjFPC|<syntaxhighlight lang="pascal" inline>{$mode objFPC}</syntaxhighlight>]] ja [[Mode Delphi|<syntaxhighlight lang="pascal" inline>{$mode Delphi}</syntaxhighlight>]],  
niin  toteutuslohkon sisällä on käytössä [[Identifier/fi|tunniste]] <syntaxhighlight lang="pascal" enclose="none">result</syntaxhighlight> myöskin:
+
niin  toteutuslohkon sisällä on käytössä [[Identifier/fi|tunniste]] <syntaxhighlight lang="pascal" inline>result</syntaxhighlight> myöskin:
 
<syntaxhighlight lang="pascal" line start="13" highlight="4">
 
<syntaxhighlight lang="pascal" line start="13" highlight="4">
 
// käytetään `result` tunnistetta
 
// käytetään `result` tunnistetta
Line 37: Line 37:
 
end;
 
end;
 
</syntaxhighlight>
 
</syntaxhighlight>
Lisäksi <syntaxhighlight lang="pascal" enclose="none">{$mode objFPC}</syntaxhighlight>:ssa rutiini
+
Lisäksi <syntaxhighlight lang="pascal" inline>{$mode objFPC}</syntaxhighlight>:ssa rutiini
{{Doc|package=RTL|unit=system|identifier=exit|text=<syntaxhighlight lang="pascal" enclose="none">exit</syntaxhighlight>}} asettaa myös palautusarvon ja jättää pinoon kehyksen.  
+
{{Doc|package=RTL|unit=system|identifier=exit|text=<syntaxhighlight lang="pascal" inline>exit</syntaxhighlight>}} asettaa myös palautusarvon ja jättää pinoon kehyksen.  
 
Kahdessa aikaisemmassa esimerkissä olisi voinut esiintyä muita lausekkeita ja ne olisi toteutettu, kun taas  
 
Kahdessa aikaisemmassa esimerkissä olisi voinut esiintyä muita lausekkeita ja ne olisi toteutettu, kun taas  
<syntaxhighlight lang="pascal" enclose="none">exit</syntaxhighlight>:n jälkeen palataan funktiosta pois.  
+
<syntaxhighlight lang="pascal" inline>exit</syntaxhighlight>:n jälkeen palataan funktiosta pois.  
Tämä on samanlainen käyttäytyminen kuin C:n tai joidenkin muiden ohjelmointikielien <syntaxhighlight lang="C" enclose="none">return</syntaxhighlight> lausekkeen käyttäytyminen.
+
Tämä on samanlainen käyttäytyminen kuin C:n tai joidenkin muiden ohjelmointikielien <syntaxhighlight lang="C" inline>return</syntaxhighlight> lausekkeen käyttäytyminen.
  
  
Line 84: Line 84:
 
{$endif}
 
{$endif}
 
</syntaxhighlight>
 
</syntaxhighlight>
Muuten riippuen siitä, mikä [[sAsmmode|<syntaxhighlight lang="pascal" enclose="none">{$asmMode}</syntaxhighlight>]] on aktiivinen, <syntaxhighlight lang="asm" enclose="none">@result</syntaxhighlight> (Intel) tai <syntaxhighlight lang="asm" enclose="none">__result</syntaxhighlight> (AT&T) -makroa voidaan käyttää.
+
Muuten riippuen siitä, mikä [[sAsmmode|<syntaxhighlight lang="pascal" inline>{$asmMode}</syntaxhighlight>]] on aktiivinen, <syntaxhighlight lang="asm" inline>@result</syntaxhighlight> (Intel) tai <syntaxhighlight lang="asm" inline>__result</syntaxhighlight> (AT&T) -makroa voidaan käyttää.
 
<syntaxhighlight lang="pascal" line start="56" highlight="20,31,36,40,41">
 
<syntaxhighlight lang="pascal" line start="56" highlight="20,31,36,40,41">
 
type
 
type

Latest revision as of 17:20, 6 August 2022

Deutsch (de) English (en) español (es) suomi (fi) français (fr) русский (ru)

Funktio eli function on rutiini, joka toisin kuin aliohjelma (procedure) palauttaa arvon. Funktion kutsu käytännössä korvautuu sen palautusarvolla. Jos {$extendedSyntax} kääntäjän kytkin (compiler switch) on pois päältä, funktion kutsu ei voi esiintyä ei-tuottavina lauseina, vaan niiden on oltava osa lauseketta.

Sana function on varattu sana.

Palautusarvo

Normaalin aliohjelman esittelyn lisäksi funktion esittely sisältää myös palautustyypin: muodollisen parametriluettelon jälkeen tulee kaksoispiste- ja palautustyyppi. Seuraava funktion esittely palauttaa esimerkiksi boolean tyyppisen arvon.

function myFunction(const firstParameter: real): boolean;

Funktion toteuttamisessa on useita tapoja toteuttaa funktion palautusarvo.

 1program functionDemo(input, output, stderr);
 2
 3{$mode objfpc}
 4
 5// Perinteinen tapa:
 6// palautus arvo tallennetaan muuttujaan 
 7// jonka nimi on sama kuin funktion nimi
 8function myLine(const x: real): real;
 9begin
10	myLine := 0.5 * x + 2;
11end;

Jos {$modeswitch result+} on käytössä. Se asetetaan {$mode objFPC} ja {$mode Delphi}, niin toteutuslohkon sisällä on käytössä tunniste result myöskin:

13// käytetään `result` tunnistetta
14function myParabola(const x: real): real;
15begin
16	result := sqr(x) - 1;
17end;

Lisäksi {$mode objFPC}:ssa rutiini exit asettaa myös palautusarvon ja jättää pinoon kehyksen. Kahdessa aikaisemmassa esimerkissä olisi voinut esiintyä muita lausekkeita ja ne olisi toteutettu, kun taas exit:n jälkeen palataan funktiosta pois. Tämä on samanlainen käyttäytyminen kuin C:n tai joidenkin muiden ohjelmointikielien return lausekkeen käyttäytyminen.


19// käytetään exit rutiinia
20function even(const x: longint): boolean;
21begin
22	exit(not odd(x));
23end;

Assembly kielen yhteydessä sovelletaan muita sääntöjä. Jos palautustyyppi on kiinteä arvo, käytetään akku-rekisteriä, jos se mahtuu sinne:

25// in assembly language:
26// return type fits into a single register => use accumulator register
27function zero(const x: int64): boolean;
28{$ifdef CPUx86_64}
29assembler; register;
30{$asmMode intel}
31asm
32	// xor modifies flags => put it in front of test
33	xor rax, rax     // rax := 0 [false]
34	
35	// examining the assembler output
36	// we can verify x is stored in register rdi [i.e. not rax]
37	test x, x        // x = 0 ?
38	jnz @zero_done   // if x <> 0 then goto done
39	
40	inc rax          // rax := 1 [true]
41@zero_done:
42	// When you examine the assembler output
43	// you will notice the compiler automatically inserts code
44	// that moves the contents of rax to the right spot on the stack.
45end;
46{$else}
47begin
48	// NOTE: with optimization switches enabled
49	//       the compiler produces with the following Pascal statement
50	//       even shorter (and maybe faster) code
51	//       than the assembler implementation above
52	result := x = 0;
53end;
54{$endif}

Muuten riippuen siitä, mikä {$asmMode} on aktiivinen, @result (Intel) tai __result (AT&T) -makroa voidaan käyttää.

56type
57	bodyAttributes = record
58		surfaceArea: real;
59		volume: real;
60	end;
61
62// in assembly language:
63// return type doesn't fit into accumulator => @result macro gives address
64function sphere(const radius: real): bodyAttributes;
65{$ifdef CPUx86_64}
66assembler;
67{$asmMode intel}
68const
69	three: longint = 3;
70	four: longint = 4;
71var
72	r: real;
73asm
74	pextrq r, radius, 0 // r := (@radius+0)^
75	lea rax, @result    // rax := @result
76	fld r               // radius
77	
78	fld st(0)           // radius radius
79	fild four           // 4 radius radius
80	fldpi               // pi 4 radius radius
81	fmul                // 4*pi radius radius
82	fxch                // radius 4*pi radius
83	fld st(0)           // radius radius 4*pi radius
84	fmul                // radius^2 4*pi radius
85	fmul                // 4*pi*radius^2 radius
86	fst [rax].bodyAttributes.surfaceArea
87	
88	fmul                // 4*pi*radius^3
89	fild three          // 3 4*pi*radius^3
90	fdivp               // 4/3*pi*radius^3
91	fst [rax].bodyAttributes.volume
92end;
93{$else}
94begin
95	sphere.surfaceArea := 4 * pi() * sqr(radius);
96	sphere.volume := 4 / 3 * pi() * sqr(radius) * abs(radius);
97end;
98{$endif}

Alun perin Pascal odotti täsmällisesti yhden tehtävän tulosmuuttujalle. FPC ei kuitenkaan kiellä käyttämästä useita. Se lähettää varoituksen, jos mikään mahdollisista palautumisarvoista ei ole käytössä tai poistumisrutiinia ei ole kirjoitettu.

Warning
Function result does not seem to be set
You can get this warning if the compiler thinks that a function return value is not set. This will not be displayed for assembler procedures, or procedures that contain assembler blocks.
100begin
101	writeLn(sphere(2.0).surfaceArea);
102end.

Katso myös