C-ohjelmoinnin toiminnot esimerkein: Rekursiivinen & Inline
โก รlykรคs yhteenveto
C-ohjelmoinnin funktiot ovat uudelleenkรคytettรคviรค koodilohkoja, jotka jakavat suuren ohjelman pienempiin aliohjelmiin, mikรค helpottaa sen ymmรคrtรคmistรค, testaamista ja muokkaamista. Jokaisella funktiolla on deklaraatio, mรครคritelmรค ja kutsuosa.

Mikรค on funktio C:ssรค?
Toiminto C-ohjelmoinnissa on uudelleenkรคytettรคvรค koodilohko, joka helpottaa ohjelman ymmรคrtรคmistรค, testaamista ja muokkaamista muuttamatta kutsuvaa ohjelmaa. Funktiot jakavat koodin ja moduloivat ohjelman parempien ja tehokkaampien tulosten saavuttamiseksi. Lyhyesti sanottuna suurempi ohjelma jaetaan useisiin aliohjelmiin, joita kutsutaan funktioiksi.
Kun jaat suuren ohjelman useisiin toimintoihin, on helppoa hallita jokaista toimintoa erikseen. Aina kun ohjelmassa tapahtuu virhe, voit helposti tutkia vialliset toiminnot ja korjata vain ne virheet. Voit helposti soittaa ja kรคyttรครค toimintoja aina kun niitรค tarvitaan, mikรค sรครคstรครค automaattisesti aikaa ja tilaa.
Kirjasto vs. Kรคyttรคjรคn mรครคrittรคmรคt toiminnot
Jokaisessa C-ohjelmassa on ainakin yksi funktio, joka on pรครคtoiminto, mutta ohjelmalla voi olla mikรค tahansa mรครคrรค toimintoja. C:n pรครคfunktio () on ohjelman aloituspiste.
C-ohjelmoinnissa funktiot jaetaan kahteen tyyppiin:
- Kirjaston toiminnot
- Kรคyttรคjรคn mรครคrittรคmรคt toiminnot
Ero kirjaston ja kรคyttรคjรคn mรครคrittรคmien funktioiden vรคlillรค C:ssรค on, ettรค meidรคn ei tarvitse kirjoittaa koodia kirjastofunktiolle. Se on jo olemassa otsikkotiedostossa, jonka sisรคllytรคmme aina ohjelman alkuun. Sinun tarvitsee vain kirjoittaa funktion nimi ja kรคyttรครค sitรค oikean syntaksin kanssa. Printf, scanf ovat esimerkkejรค kirjastotoiminnoista.
Sen sijaan kรคyttรคjรคn mรครคrittรคmรค funktio on erรครคnlainen funktio, jossa meidรคn on kirjoitettava funktion runko ja kutsuttava funktiota aina, kun vaadimme funktiota suorittamaan jonkin toiminnon ohjelmassamme.
Kรคyttรคjรคn mรครคrittรคmรค funktio C:ssรค on aina kรคyttรคjรคn kirjoittama, mutta myรถhemmin se voi olla osa 'C'-kirjastoa. Se on C-ohjelmoinnin suuri etu.
C-ohjelmointitoiminnot on jaettu kolmeen toimintoon, kuten
- Toimintoilmoitus
- Toiminnon mรครคritelmรค
- Toimintakutsu
Toimintoilmoitus
Funktion deklarointi tarkoittaa ohjelman nimen kirjoittamista. Se on pakollinen osa funktioiden kรคyttรคmiseksi koodissa. Funktion deklaroinnissa mรครคritรคmme vain funktion nimen, jota aiomme kรคyttรครค ohjelmassamme, kuten muuttujadeklaraatiossa. Emme voi kรคyttรครค funktiota, ellei sitรค ole deklaroitu ohjelmassa. Funktion deklarointia kutsutaan myรถs "funktion prototyypiksi".
Funktioilmoitukset (kutsutaan prototyypiksi) tehdรครคn yleensรค pรครคfunktion () ylรคpuolelle ja ovat yleisessรค muodossa:
return_data_type function_name (data_type arguments);
- return_data_type: on kutsuvalle lausekkeelle palautetun arvofunktion tietotyyppi.
- Funktion_nimi:-merkkiรค seuraa sulkeet
- Argumenttien nimet ja niiden tietotyyppimรครคrittelyt (valinnaisesti) sijoitetaan sulkeisiin.
Tarkastellaan seuraavaa ohjelmaa, joka nรคyttรครค kuinka kuutiofunktio mรครคritellรครคn kokonaislukumuuttujan kuutioarvon laskemiseksi
#include <stdio.h> /*Function declaration*/ int add(int a,b); /*End of Function declaration*/ int main() {
Muista, ettรค funktio ei vรคlttรคmรคttรค palauta arvoa. Tรคssรค tapauksessa kรคytetรครคn avainsanaa void.
Esimerkiksi funktion output_message ilmoitus osoittaa, ettรค funktio ei palauta arvoa: void output_message();
Toiminnon mรครคritelmรค
Funktiomรครคrittely tarkoittaa vain funktion rungon kirjoittamista. Toiminnon runko koostuu lauseista, jotka suorittavat tietyn tehtรคvรคn. Funktiorunko koostuu yhdestรค lauseesta tai lausekkeesta. Se on myรถs pakollinen osa toimintoa.
int add(int a,int b) //function body { int c; c=a+b; return c; }
Toimintakutsu
Funktiokutsu tarkoittaa funktion kutsumista aina, kun sitรค vaaditaan ohjelmassa. Aina kun kutsumme funktiota, se suorittaa toiminnon, jota varten se on suunniteltu. Funktiokutsu on valinnainen osa ohjelmaa.
result = add(4,5);
Tรคssรค on koko koodi:
#include <stdio.h> int add(int a, int b); //function declaration int main() { int a=10,b=20; int c=add(10,20); //function call printf("Addition:%d\n",c); getch(); } int add(int a,int b) //function body { int c; c=a+b; return c; }
lรคhtรถ:
Addition:30
Funktion argumentit
Funktion argumentteja kรคytetรครคn tarvittavien arvojen vastaanottamiseen funktiokutsulla. Ne ovat yhteensopivia sijainnin mukaan; ensimmรคinen argumentti vรคlitetรครคn ensimmรคiselle parametrille, toinen toiselle parametrille ja niin edelleen.
Oletusarvoisesti argumentit vรคlitetรครคn arvon mukaan, jolloin kutsuttavalle funktiolle annetaan kopio tiedoista. Itse vรคlitetty muuttuja ei muutu.
Tarkastelemme seuraavaa ohjelmaa, joka nรคyttรครค arvon kautta vรคlitetyt parametrit:
int add (int x, int y); int main() { int a, b, result; a = 5; b = 10; result = add(a, b); printf("%d + %d\ = %d\n", a, b, result); return 0;} int add (int x, int y) { x += y; return(x);}
Ohjelman tulos on:
5 + 10 = 15
Muista, ettรค a:n ja b:n arvoja vรคlitettiin lisรคtoimintoon, koska sitรค ei muutettu, koska vain sen arvo vรคlitettiin parametriin x.
Vaihteleva soveltamisala
Muuttujan laajuus tarkoittaa muuttujien nรคkyvyyttรค ohjelman koodissa.
C-kielessรค funktion sisรคllรค deklaroidut muuttujat ovat paikallisia kyseiselle koodilohkolle, eikรค niihin voida viitata funktion ulkopuolella. Funktioiden ulkopuolella deklaroidut muuttujat ovat kuitenkin globaaleja ja kรคytettรคvissรค koko ohjelmasta. Ohjelman alussa #define-merkillรค deklaroidut vakiot ovat kรคytettรคvissรค koko ohjelmasta. Tarkastellaan seuraavaa ohjelmaa, joka tulostaa globaalin muuttujan arvon sekรค pรครคfunktiosta ettรค kรคyttรคjรคn mรครคrittรคmรคstรค funktiosta:
#include <stdio.h> int global = 1348; void test(); int main() { printf("from the main function : global =%d \n", global); test () ; return 0;} void test (){ printf("from user defined function : global =%d \n", global);}
Tulos:
from the main function : global =1348 from user defined function : global =1348
Keskustelemme ohjelman yksityiskohdista:
- Ilmoitamme kokonaisluvun globaalin muuttujan, jonka alkuarvo on 1348.
- Ilmoitamme ja mรครคritรคmme test()-funktion, joka ei ota argumentteja eikรค palauta arvoa. Tรคmรค toiminto tulostaa vain globaalin muuttujan arvon osoittaakseen, ettรค globaaleihin muuttujiin pรครคsee kรคsiksi missรค tahansa ohjelmassa.
- Tulostamme globaalin muuttujan pรครคfunktion sisรคllรค.
- Kutsumme testifunktiota globaalin muuttujan arvon tulostamiseksi.
C:ssรค, kun argumentteja vรคlitetรครคn funktion parametreille, parametrit toimivat paikallisina muuttujina, jotka tuhoutuvat funktiosta poistuttaessa.
Kun kรคytรคt globaalit muuttujat, kรคytรค niitรค varoen, koska ne voivat johtaa virheisiin ja ne voivat muuttua missรค tahansa ohjelmassa. Ne tulee alustaa ennen kรคyttรถรค.
Staattiset muuttujat
Staattisilla muuttujilla on paikallinen laajuus. Ne eivรคt kuitenkaan tuhoudu toiminnosta poistuttaessa. Siksi staattinen muuttuja sรคilyttรครค arvonsa ikuisesti ja sitรค voidaan kรคyttรครค, kun funktio syรถtetรครคn uudelleen. Staattinen muuttuja alustetaan, kun se ilmoitetaan, ja se tarvitsee etuliitettรค staattinen.
Seuraava ohjelma kรคyttรครค staattista muuttujaa:
#include <stdio.h> void say_hi(); int main() { int i; for (i = 0; i < 5; i++) { say_hi();} return 0;} void say_hi() { static int calls_number = 1; printf("Hi number %d\n", calls_number); calls_number ++; }
Ohjelma nรคyttรครค:
Hi number 1 Hi number 2 Hi number 3 Hi number 4 Hi number 5
Rekursiiviset toiminnot
Tarkastellaan luvun kertomaa, joka lasketaan seuraavasti 6! =6 * 5 * 4 * 3 * 2 * 1.
Tรคmรค laskutoimitus suoritetaan toistuvasti laskemalla tosiasia * (fakta -1), kunnes tosiasia on yhtรค kuin 1.
Rekursiivinen funktio on toiminto, joka kutsuu itseรครคn ja sisรคltรครค poistumisehdon rekursiivisten kutsujen lopettamiseksi. Tekijรคlukulaskelman tapauksessa poistumisehto on tosiasia, joka on yhtรค suuri kuin 1. Rekursio toimii "pinoamalla" kutsuja, kunnes poistumisehto on tosi.
Esimerkiksi:
#include <stdio.h> int factorial(int number); int main() { int x = 6; printf("The factorial of %d is %d\n", x, factorial(x)); return 0;} int factorial(int number) { if (number == 1) return (1); /* exiting condition */ else return (number * factorial(number - 1)); }
Ohjelma nรคyttรครค:
The factorial of 6 is 720
Tรครคllรค keskustelemme ohjelman yksityiskohdista:
- Ilmoitamme rekursiivisen tekijรคfunktiomme, joka ottaa kokonaislukuparametrin ja palauttaa tรคmรคn parametrin kertoimen. Tรคmรค toiminto kutsuu itseรครคn ja pienentรครค numeroa, kunnes poistuminen tai perusehto saavutetaan. Kun ehto on tosi, aiemmin luodut arvot kerrotaan keskenรครคn ja lopullinen tekijรคarvo palautetaan.
- Ilmoitamme ja alustamme kokonaislukumuuttujan arvolla โ6โณ ja tulostamme sitten sen kertoimen arvon kutsumalla tekijรคfunktiota.
Tarkastellaan seuraavaa kaaviota ymmรคrtรครคksesi paremmin rekursiivista mekanismia, joka koostuu funktion kutsumisesta itseรครคn, kunnes perustapaus tai stop-kohtaus saavutetaanping ehto saavutetaan, ja sen jรคlkeen kerรครคmme edelliset arvot:
Sisรคiset toiminnot
C-ohjelmoinnin funktiota kรคytetรครคn tallentamaan useimmin kรคytetyt kรคskyt. Sitรค kรคytetรครคn ohjelman modulointiin.
Aina kun funktiota kutsutaan, kรคskyosoitin hyppรครค funktion mรครคritelmรครคn. Toiminnon suorittamisen jรคlkeen kรคskyosoitin putoaa takaisin lauseeseen, josta se hyppรคsi funktion mรครคritelmรครคn.
Aina kun kรคytรคmme toimintoja, vaadimme ylimรครคrรคistรค osoitin siirry funktion mรครคritelmรครคn ja palaa lauseeseen. Kรคytรคmme sisรคisiรค toimintoja poistaaksemme tรคllaisten osoitinpรคiden tarpeen.
Inline-funktiossa funktiokutsu korvataan suoraan todellisella ohjelmakoodilla. Se ei hyppรครค mihinkรครคn lohkoon, koska kaikki toiminnot suoritetaan rivifunktion sisรคllรค.
Inline-funktioita kรคytetรครคn enimmรคkseen pieniin laskelmiin. Ne eivรคt sovellu suuriin tietokoneisiin.
Inline-funktio on samanlainen kuin tavallinen funktio, paitsi ettรค avainsanan teksti on ennen funktion nimeรค. Sisรคiset funktiot luodaan seuraavalla syntaksilla:
inline function_name ()
{
//function definition
}
Kirjoitetaan ohjelma inline-funktion toteuttamiseksi.
inline int add(int a, int b) //inline function declaration { return(a+b); } int main() { int c=add(10,20); printf("Addition:%d\n",c); getch(); }
lรคhtรถ:
Addition: 30
Yllรค oleva ohjelma esittelee rivifunktion kรคyttรถรค kahden luvun lisรครคmiseen. Kuten nรคemme, olemme palauttaneet kahden luvun lisรคyksen vain rivifunktion sisรคllรค kirjoittamatta ylimรครคrรคisiรค rivejรค. Toiminnon kutsun aikana olemme juuri vรคlittรคneet arvot, joille meidรคn on suoritettava yhteenlasku.




