Difference between revisions of "Function/fi"
(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" | + | 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" | + | 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" | + | 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" | + | 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" | + | 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" | + | Lisäksi <syntaxhighlight lang="pascal" inline>{$mode objFPC}</syntaxhighlight>:ssa rutiini |
− | {{Doc|package=RTL|unit=system|identifier=exit|text=<syntaxhighlight lang="pascal" | + | {{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" | + | <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" | + | 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" | + | 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.