C/Komentoriviparametrit ja main-funktio
Ohjelman suoritus alkaa main-funktiosta, jolla on kaksi vaihtoehtoista standardin määrittelemää muotoa:
int main(void) int main(int argc, char** argv)
Muut muodot kuten void main(void), jota kuitenkin usein näkee vanhemmissa C-oppaissa käytettävän, eivät ole laillisia standardin puitteissa.
Komentoriviparametrit
[muokkaa | muokkaa wikitekstiä]Parametrit sisältävää muotoa käytetään, jos ohjelma lukee komentoriviparametreja. Parametrien nimillä argc ja argv ei sinänsä ole väliä, mutta näitä nimiä käytetään standardissa ja ne ovat erittäin vakiintuneet, joten omia nimiä ei kannata lähteä keksimään. Jälkimmäinen parametri on usein merkitty char* argv[], mutta tämä on merkitykseltään täysin sama kuin char** argv, sillä taulukko muuttuu funktiolle välitettäessä ensimmäisen alkionsa osoitteeksi.
Parametri argc ilmaisee taulukon argv koon, joka voi olla 0 tai jokin positiivinen luku. Taulukko argv puolestaan sisältää ohjelman nimen ja kunkin parametrin omina merkkijonoinaan. Lisäksi taulukon lopussa, siis kohdassa argv[argc] on NULL-pointteri taulukon loppua merkitsemässä. Tätä ei kuitenkaan useinkaan käytetä, koska myös argc ilmaisee koon.
Periaatteessa argc voi olla 0, jolloin argv ei NULL-pointterin lisäksi muuta sisälläkään. Kuitenkin käytännössä argc:n yleensä oletetaan olevan vähintään 1, jolloin myös seuraavat arvot ovat saatavilla:
argv[0] ilmaisee ohjelman nimen tai komennon, jolla ohjelma ajettiin. Mikäli käyttöjärjestelmä ei syystä tai toisesta nimeä pysty kertomaan, on merkkijono tyhjä (ei kuitenkaan NULL).
Indeksistä 1 eteenpäin argv sisältää ohjelmalle annetut parametrit järjestyksessä. Tyypillisesti ohjelmaa ajettaessa (esim. komentoriviltä) parametrit erotellaan välilyönnein, mutta käynnistävä ohjelma (esim. shelli) on vastuussa parametrien erottelusta ja voi näinollen menetellä miten hyvänsä. Komentoriviltä ajettaessa parametreihin voi yleensä sisällyttää välilyöntejä lainausmerkkejä käyttäen.
Esimerkki:
#include <stdio.h> int main(int argc, char** argv) { printf("argc=%d\n", argc); for (int i = 0; argv[i]; ++i) printf("argv[%d]=%s\n", i, argv[i]); }
Ajettaessa ohjelma komennolla ./ohjelma eka toka 'foo bar' (bash-shellissä Linuxilla), tulostuu:
argc=4 argv[0]=./ohjelma argv[1]=eka argv[2]=toka argv[3]=foo bar
Paluuarvo
[muokkaa | muokkaa wikitekstiä]Paluuarvoa käytetään ilmaisemaan käyttöjärjestelmälle suoriutuiko ohjelma tehtävästään vai ei. Onnistunut suoritus voidaan ilmaista palauttamalla 0 tai EXIT_SUCCESS. Epäonnistunut suoritus ilmaistaan palauttamalla EXIT_FAILURE. Muut arvot C-standardi jättää implementaation määriteltäviksi, mutta tyypillisesti mikä tahansa nollasta poikkeava arvo tarkoittaa virhettä.
EXIT_SUCCESS ja EXIT_FAILURE ovat headerista stddef.h löytyviä vakioarvoja, jotka on tarkoitettu käytettäviksi ainoastaan ohjelman lopetuskoodeina (main-funktion paluuarvona tai exit-funktion parametrina).
Ohjelman paluukoodin tulostaminen komentoriviltä ajettaessa tapahtuu eri järjestelmissä hyvinkin eri tavoin, eikä siihen ole mitään helppoa yhtenäistä tapaa. Arvo on kuitenkin yleensä saatavilla sellaisenaan, joskin mahdollisesti lukualueeltaan rajattuna (esim. 0..255).
Vaikka funktion paluutyyppi on int eikä void, ei main-funktiossa C99-standardin mukaan tarvitse olla return-lausetta lainkaan. Jos suoritus päätyy funktion loppuun ilman returnia, vastaa se return 0:aa. Vanhempi ANSI-C (C89) edellyttää returnia aivan kuten muissakin ei-void-funktioissa.
Rekursio
[muokkaa | muokkaa wikitekstiä]C-kieli sallii main-funktion kutsumisen ja sen käytön funktiopointterin kautta. Tämä on kuitenkin huonoa ohjelmointityyliä, eikä esimerkiksi C++ salli mainiin koskemista lainkaan.