Programovanie v jazyku C
Ďalšie informácieZákladná filozofia C jazykaProgramovať v jazyku C (alebo v ľubovolnom inom) znamená písať Zdrojový text programu v textovom editore a dodržiavať syntaktické pravidlá programovacieho jazyka. Preložiť program - znamená spustiť špeciálny program - Kompilátor, ktorý transformuje zdrojový text programu do binárneho vykonateľného súboru (executable = vykonateľný).
Vykonateľné súbory (označované príponou .EXE ) obsahujú strojové inštrukcie v binárnom tvare určené pre konkrétny typ procesora počítača. Operačný systém počítača spúšťa vykonateľný program pomocou príkazu napríklad:
Čo sa deje po spustení programu?
Zdrojový text programu - Čo v ňom nájdeme? Máme dva možné pohľady na obsah: Z formálnej obsahovej stránky to budú nasledovné elementy:
Z programátorskej stránky - to sú konštrukcie ktoré predstavujú jednak
Programátorské konštrukcie nám umožňujú budovať algoritmické postupy využívajúce:
Dátové objekty /DO/ (premenné a konštanty)
Blok dátových objektov a príkazov { ... }
Funkcie
Procedúry -
Deklarácie - sú príkazy, ktoré udávajú typ a meno premenných alebo funkcií ale neprideľujú žiaden obsah. Slúžia na informovanie o budúcej Definícii . Definície - sú príkazy, ktoré pridelia premennej alebo funkcii konkrétneho typu obsah alebo program a obsah v pamäti. Premenné - sú dátové objekty ktoré v v C jazyku sú charakterizované typom. Dátové objekty konkrétneho typu majú svoju veľkosť vyjadrenú počtom slov ktoré zaberajú v Operačnej pamäti. Prístup k dátovým objektom je jednak cez ich názvy, a jednak cez z adresy na ktoré ukazujú tzv. pointre na dané premenné. Jazyk C používa dva druhy premenných a to lokálne a globálne.
Príkazy
Súbory -
Návrat na začiatoktokPostup spracovania programu.Programy sú vytvárané - písané v textovom editore. Najlepšie sa to robí v špecializovanom vývojovom prostredí - ktoré ma integrované HELP súbory obsahujúce príklady, popis príkazov jazyka a návody práce. Postup činností pri spracovaní programu vyjadruje nasledovná schéma:
Editor - nástroj na písanie dokumentu - vytvára zdrojový text súboru, ktorého názov je ukončený charakteristickou príponou ( .C , resp. Borland C++ má .CPP ). Preprocesor - je program, ktorý automaticky upraví vytvorený zdrojový program, a odstráni v ňom všetky poznámky a zbytočné medzery. Z hlavičkových súborov (.h) skopíruje požadované deklarácie funkcií používaných v programe a nakoniec vytvorí pracovný textový súbor určený pre prekladač - t.j. kompilátor jazyka C. Compiler - Prekladač alebo aj Kompilátor je program, ktorý zdrojový text prekladá do strojového kódu, ale do jeho relatívneho formy. Vzniká súbor rovnakého názvu ale s novou príponou (.obj). Program v relatívnom tvare je prekladaný so štartovacou adresu 0, nemá nastavené žiadne absolútne adresy, ešte nemá doriešené adresovania na premenné a volania funkcií náväzných modulov programu. Compiler odhaľuje chyby syntaxe príkazov (t.j. chybne zapísané príkazy - nezodpovedajúce pravidlám) a nedoriešené vzťahy na deklarácie externých funkcií. O zisteniach informuje v sprievodnom súbore rovnakého názvu ale s upravenou koncovkou (.lis). Linker - volaný aj zostavovací program, spája všetky relatívne moduly do jedného uceleného programu a nahradzuje relatívne adresy z relatívnych modulov (.obj) absolútnymi adresami. Z knižničných súborov (.lib), ktoré obsahujú ďalšie relatívne moduly, pripája požadované moduly a prepája ich s volaniami funkcií v iných, do výsledného programu pripojených, relatívnych modulov. Vo vytváranom programe nahradzuje fiktívne volania absolútnymi volaniami na miesta kam moduly, obsahujúce funkcie z knižničných súborov, umiestnil. Týmto vzťahom vzájomnej komunikácie modulov hovoríme krížové referencie. Výsledkom činnosti linkera je spustiteľný program rovnakého názvu s príponou ( .exe ), ktorý má vyriešené všetky krížové referencie a je bez chýb. Debuger - (odstraňovač chrobákov = po našom odstraňovač "múch") je ladiaci program, ktorý umožňuje krokovať ladený program a vyhľadať chyby práce programu, t.j. nesprávneho algoritmu. Umožňuje zisťovať príčiny tzv. "Runtime Errors", t.j. chyby ktoré sa prejavia až po spustení programu v "čase jeho behu". Takýto program môže byť po formálnej stránke v poriadku. Tomuto procesu hovoríme ladenie. Debuger má schopnosť sledovať chod ladeného programu po krokoch (step = krok). , t.j zastaviť po každom riadku programu, resp. zastavovať na miestach do ktorých sa pred spustením ladeného programu vložia tzv. STOP ZNAČKY (BREAK POINTS) Dôvodm pre zastavenie programu môže byť udalosť napr. zmena hodnoty sledovanej premennej. V bodoch zastavenia nám debuger umožňuje prekontrolovať momentálny stav premenných použitých v programe. Odhalením odchýlky od požadovaného stavu obsahu dátových objektov programátor ďalšou analýzou určí chybu v programe. Najčastejšou chybou je nezhoda medzi tým čo chceme aby program robil a tým čo a ako mu to inštrukciou prikážeme. Proces ladenia - je činnosť v ktorej programátor opakovane upravuje zdrojový text programu, spúšťa proces kompilácie a odstraňuje zistené chyby. Niektoré chyby môžu vyvolávať aj iné náväzné (tzv. sekundárne) chyby programu, preto nájsť skutočnú príčinu chyby býva komplikovaná činnosť vyžadujúca trpezlivosť. Práca profesionálnych programátorov je charakteristická tým, že množstvo chýb v porovnaní s vytvoreným množstvom programových inštrukcií býva časom menšia a menšia. Chybovosť u profesionálov sa neskôr viac prejavuje v zlým pochopením zadania úlohy zadávateľom, resp. chybami v analýze riešenia úlohy ako takej. Z týchto dôvodov dolaďovanie programov by mala byť tímová práca analytikov ale aj programátorov. Významnú úlohu majú aj testovači. Sú to ľudia ktorých pracovnou náplňou je overovanie funkcie programu v každom režime práce. Vyjadrujú sa k farebnému dizajnu aplikácií, obsahovej stránke, pracovnej pohode, prístupu k HELPom pri riešení konkrétnych pracovných postupov v aplikácii a odhaľujú anomálie práce aplikácie t.j. nezhody medzi tým čo má program robiť a čo skutočne robí. Všetky takto zistené veci sú dôvodom na úpravu zdrojového textu programu. Najčastejšie sa však prejaví problém až po nasadení aplikácie do prevádzky. Nie nadarmo sa hovorí: "Až prax overí všetky funkcie". Návrat na začiatokPríkazy preprocesora.Sú to príkazy ktoré sa vykonávajú ešte pred kompiláciou. Pred samotnými príkazmi je znak #. Príkaz preprocesora #include vkladá do zdrojového textu obsah iných súborov, zvyčajne obsahujúce deklarácie funkcií. Zvyčajne tieto súbory majú označenie .h čo znamená header (hlavička). Volania majú dva možné tvary #include <stdio.h> pre vkladanie systemových súborov umiestnených v aktuálnom adresári, alebo v adresári INCLUDE. #include "defs.f" pre vkladanie užívateľom vytvorených súborov. Príklady:
Ďalší príkaz preprocesora #define slúži na zavádzanie symbolických konštánt.
] Návrat na začiatokDátové objekty - typy dát a ich dĺžka. Čo to je dátový objekt? ZÁKLADNÉ VLASTNOSTI DÁTOVÝCH OBJEKTOV
Zoznam ZÁKLADNÝCH TYPOV DÁT:
Od typu dátového objektu závisia jeho ďalšie vlastnosti - veľkosť t.j. počet byte ktoré v pamäti zaberá, obor hodnôt - celé kladné, celé záporné a kladné, reálne s desatinnou bodkou, povolené operácie s dátovým objektom. Z hľadiska možnosti meniť obsah rozlišujeme v programe
Konštanty v programe predstavujú LITERÁLY (názvy) s pridelenou hodnotou. V programe vytvárajú dvojicu TEXTOVÝ REŤAZEC - HODNOTA. Konštanta sa v programe môže definovať len jeden raz, ale použitie je bez obmedzenia. Hlavný dôvod existencie konštánt je sprehľadniť v programoch použitie konkrétneho čísla alebo reťazca, a možnosť definovať údaj na jedinom mieste. V prípade potreby zmeny stačí obsah zmeniť v tej jedinej definícii na začiatku programového textu a zmena sa prejaví na všetkých miestach kde sa v programe LITERÁL vyskytol. Ak by sme nemali inštitút konštanty, museli by sme si pamätať, kde všade v programe sme použili číselný údaj resp. textový reťazec danej hodnoty - a pri jeho zmene, museli by sme všetky miesta výskytu vyhľadať a zmeniť. Stačilo by v programe prehliadnuť jediný výskyt so starou hodnotou a máme problém! Konštanty sa v programe aplikujú počas prekladu, keď jej hodnota inicializuje premenné, alebo sa využijú na výpočet hodnoty vo výraze ešte v etape kompilácie. Počas behu programu konštanta ako dátový objekt neexistuje. Premenné v programe predstavujú reálne existujúce objekty, ktoré majú v Operačnej pamäti vyčlenený pamäťový priestor kam ukladajú svoj obsah. Meno premennej predstavuje symbolickú adresu pamäťového priestoru. Tento obsah môžeme programovo meniť. Čas existencie premennej v Operačnej pamäti sa môže meniť podľa toho, či ide o statickú alebo dynamickú premennú. Jednotlivé programové bloky v C jazyku môžu používať lokálne premenné, ktoré existujú len počas vykonávania bloku. Pri štarte sa dynamicky premenným pridelí pamäťové miesto a po jeho ukončení sa tento priestor zase vráti do "banky volného priestoru" tzv. heap-u. Naopak statické premenné sa vytvoria pri prvom použití a do konca programu im ich priestor zostane pridelený. Ostatné bloky a funkcie sa môžu na tento priestor odvolávať preto statické premenné sa používajú na predávanie si údajov medzi blokmi a funkciami. Globálne premenné sú statické premenné viditeľné všetkými funkciami a programovými modulmi ktoré ich výskyt prenášajú k sebe cez inštitút externých premenných. V prípade Harwardskej koncepcie mikropočítačov, ktoré majú program uložený v ROM pamäti a dáta v samostatnej RAM pamäti, statická definícia premennej ju okamžite umiestňuje (alokuje) do dátovej oblasti. Naopak dynamické premenné sa ukladajú do nepomenovanej oblasti. V prostredí C jazyka, aplikácia môže pracovať aj s adresou premennej, t.j. nepristupuje k jej obsahu premennej pomocou jej názvu, ale aj cez adresu jej umiestnenia v Operačnej pamäti (Pointer).
Návrat na začiatokOperátory, identifikátory, premenné, konštantyPremenné a konštanty sú základné dátové objekty s ktorými program pracuje. Na ich vytvorenie slúžia deklarácie, ktoré im určia názov, typ a niekedy aj počiatočné hodnoty. Výrazy prideľujú novú hodnotu premennej na základe vyjadrenia pomocou premenných a operátorov. Názvy premenných Názvy sa skladajú z písmen a číslic - písmeno na začiatku (aj znak _ je chápané ako písmeno). Znak _ za používa na sprehľadnenie dlhých názvov v zmysle medzery. Je tradícia používať malé písmená pre premenné a veľké pre konštanty. Jazyk C je citlivý na veľkosť písmen ktoré rozlišuje ako rôzne kódy. Dĺžka mena premennej je štandardne 8 znakov, ale dá sa nastaviť v "menu options (=voľby resp. nastavenie) " v IDE. Štandardné funkcie sa píšu malými písmenami a zvyčajne 8 znakov. Pre externé názvy, ako sú mená funkcií a premenných, niekedy musí počet znakov byť menší kôli rôznym externým assamblerom a zostavovacím programov.
Návrat na začiatokSmerníky a polia.
Návrat na začiatokZákladné kamene jazykaNásledovné riadky majú slúžiť k tomu, aby ste sa krok za krokom naučili používať C jazyk. V žltom nájdete bezchybný zdrojový kód, ktorý sa po skopírovaní do vývojového prostredia C jazyka, dá skompilovať a spustiť. Mimo žlté polia sú vysvetlivky. Zdrojové texty tiež obsahujú komentáre, preto berte si príklad a komentujte si aj VY svoje programy. Začíname z nuly, preto pokročilejší majte strpenie! Čo mám urobiť aby som si mohol programy hneď vyskúšať?
Prvá myšlienka pred začatím tvorby programu - čo urobiť, ak chcem vytvárať program? Vytvárame zdrojový text aplikácie, t.j. vo vývojovom prostredí musím pomocou voľby File - súbor- otvoriť nový súbor a zadať názov zdrojového textu programu (Save as... - Ulož ako ...), t.j. <meno>.C alebo už v modernejšej objektovo orientovanej verzii <meno>.CPP. Čo si môžem dovoliť napísať do zdrojového textu? V prvom rade komentáre. Komentovať musíte, pretože po čase si nebudete pamätať svoje vlastné nápady. Súvislosti, ktoré máte v čase písania programu v hlave sa vám po čase vytratia a ostane len text "v ktorom robíte nepochopiteľné kroky". Ak naviac je postup chybný, vy sa po čase vraciate k algoritmu a zisťujete "čo ste chceli urobiť", tak z vadného algoritmu si už vôbec nespomeniete na váš prvotný zámysel! Komentáre sa píšu dvomi spôsobmi. Klasicky sa poznámka píše medzi dva dvoj-znaky /* a */, a druhý spôsob je poznámka do konca riadku začínajúca //. Dajte pozor na operáciu delenia pointrom typu x= y/*p_xyz. V takomto prípade radšej napíšte x=y/(*p_xyz). Komentáre - texty ktoré kompilátor ignoruje /* texty - ktoré môžu mať aj viac riadkov */ ktoré môžu medzi sebou mať aj niekoľko riadkov. Jednoduchšia verzia je komentár do konca riadka ktorý začíname dvomi lomítkami //. Komentáre do konca riadku // texty - ktoré môžu mať len jeden riadok Komentáre nie sú programom, ale vašimi poznámkami. Kompilátor tento text počas "Compilácie" totálne ignoruje. Komentáre - vaša šanca spomenúť si /* Informácie charakterizujúce program a tvorcu * MENO SÚBORU a VERZIA * KRÁTKY POPIS ČINNOSTI * AUTOR A DÁTUM VYTVORENIA... * Komentáre sú jedinou šancou ako si po čas spomenúť čo ste naprogramovali. Stačí * mesačná pauza a nebudete poznať vlastné kódy, nieto ešte kódy iných! */ // predošlý odsek predstavoval ucelený komentár. <-Toto je jednoriadkový // na ďalšom riadku komentár musí začínať rovnako dvomi lomítkami // do konca riadku už sa píše len komentár .... /* V prvom bloku hviezdičky použité v 2.-5.riadku majú iba dekoratívny účel, zvýrazňujú komentár - nič viac */ /* Tento zdrojový text ešte neobsahuje program - iba komentáre. Použite ponuku v menu File/New - Súbor/nový - a vytvorte nový zdrojový text s názvom <meno súboru>.c resp. <meno súboru>.cpp do ktorého uložíte tento obsah a vyvolajte jeho kompiláciu voľbou Compile v menu (alebo stlačte ALT a súčasne F9) uvidíte tabuľku s nápisom Success - t.j. úspech - a vedľa uvidíte blikať Press any key - t.j. Stlač ľubovoľnú klávesu */ V druhom rade už stačí dorobiť len samotný program - a je to! Sme hotoví. (... len keby to bolo tak jednoduché...) Čo v svojej podstate obsahuje zdrojový text programu? Obsahuje popis objektov s ktorými program narába a popis príkazov, ktoré s objektmi narábajú. Sú príkazy ktoré riadia chod t.j. postupnosť vykonávania príkazov. Nazývajú sa podmienené príkazy a vyhodnocujú výrazy, ktoré sú kombináciou matematických a logických vyjadrení - t.j. používajú algebraické a logické operátory - zátvorky a pod. Základom C jazyka sú však funkcie. Niektoré sú preddefinované a sú súčasťou knižníc dodávaných s vývojovým prostredím, a všetky ostatné vytvárate počas programovania Vy. Každá funkcia má definovaný blok príkazov, ktoré sa vykonajú kedykoľvek sa vo výrazoch použije názov danej funkcie. Názov funkcie je vlastne názvom podprogramu. Funkcie majú návratovú hodnotu ktorá je stotožnená s názvom volanej funkcie. Pre našu predstavu to znamená, že ak niekde vo výraze použijeme meno funkcie, potom jeho názov sa počas behu programu nahradí vo výraze hodnotou ktorú vygeneruje podprogram funkcie. Tak ako algebraické funkcie majú svoje argumenty, majú aj funkcie v C jazyku svoje parametre uvedené v zátvorkách. Mechanizmus zámeny názvu za hodnotu vo výraze je rovnaký či sa použije konštanta, premenná alebo funkcia. Rozdiel je len v tom, ako sa hodnoty k menám priradia. Konštantadostane hodnotu pri deklarácii. Stane sa to raz na začiatku programu a od tej chvíle tento obsah sa použije kdekoľvek sa použije meno konštatnty. Deklarácie jednej konštanty - (neukončuje sa bodkočiarkou - lebo to nie je príkaz) #define MAXLINE 1000 /* výraz vyjadrujúci hodnotu môže obsahovať jedine KONŠTANTY! */ Deklarácia viac konštánt rôznych typov - (neukončuje sa bodkočiarkou) #define PI 3.14 // reálne dekadické číslo #define KONSTANTA2 123.456e-7 /* 123.456e-7 je reálna hodnota dostala by double prezentáciu konštanty */ #define NEZOBRAZITELNYZNAK '\ddd'/*ddd je 8-ková prezentácia 1byte*/ Príklad: #define FORMFEED '\014' /* znak "Nová strana" t.j. "\n" vyjadrený 8-kovým kódom - začína 0 t.j. nulou */ /* resp. '0x0D' by bolo v 16 kovom vyjadrení - začína 0x */ /* Znakové konštanty sa uzatvárajú medzi jednoduché apostrofy 'a' */ #define ZNAKNULA '\0' /* Aj keby '0' vyjadruje to same '\0' zvýrazňuje znakový charakter */ Deklarácie konštanty ako inicializovaný typ premennej, ktorej sa hodnota sa priradí len raz (ukončuje sa bodkočiarkou) const unsigned short int MAXLINE=1000 ; /* výraz vyjadrujúci hodnotu môže obsahovať jedine KONŠTANTY! */ Tento príklad deklaruje symbolickú konštantu MAXLINE, ktorej priradí hodnotu, ale a naviac je priradí aj typ ( v tomto prípade bezznamienkové krátke celé číslo). Táto metóda má viac výhod hlavne v tom, že robí programový kód jednoduchší na obsluhu a predchádza chybám, kedže kompilátor môže zbezpečiť kontrolu použitia konštanty v súlade s jej typom. Typ premennej obsahujúci vymenovaný obor konštatných hodnôtTáto forma umožňuje vytvoriť užívateľský typ premennej ktorý bude nadobúdať diskrétne hodnoty. Tieto hodnoty budú predstavovať symbolické konštanty. Príkladom je typ TDNI v nasledovnom príklade. Obor hodnôt typu sú názvy Napríklad môžete deklarovať typ TDNI s týmto oborom vymenovaných hodnôt NEDELA, PONDELOK, UTOROK, STREDA, STVRTOK, PIATOK, SOBOTA. enum TDNI { NEDELA, PONDELOK, UTOROK, STREDA, STVRTOK, PIATOK, SOBOTA }; Syntax: enum menotypu { zoznam prvkov } Príkaz enum rieši súčasne dve úlohy:
Každý prvok typu s vymenovaným oborom hodnôt má hodnotu integer - celé číslo. Hodnoty sú prideľované v poradí zľava doprava počnúc hodnotou 0 a následne zvyšované o +1. Toto implicitné pravidlo môžeme zmeniť explicitným priradením inej hodnoty, ktorá sa stáva základom pre implicitné hodnoty nasledovných konštánt u ktorých by sa hodnota neuviedla. Nastavenie konkrétnych hodnôt enum FARBA { CERVENA=100, MODRA, ZELENA=500, BIELA, CIERNA=700 }; modrá bude 101 a biela 501. Premennáje potencionálny nositeľ hodnoty, ktorej obsah sa môže meniť - preto sa volá premenná. Pri deklarovaní premennej sa vytvorí len pamäťové miesto pre budúci obsah. Deklarácie a definície premennej int i ; /* Deklarácia premennej typu Integer - celé čísla */ char c, ch ; /* Deklarácia premennej pre znaky */ float f,g ; /* Deklarácia reálnej premennej - číslo s desatinnou bodkou */ Deklarácie premennej dávajú programu na vedomie, že v programe rezervujeme pamäťové miesto reprezentované názvom premennej. Túto činnosť zabezpečujú príkazy. Príkazy sú výrazy ukončené bodkočiarkou ; . Znamená to vykonaj. Deklarácia premennej obsahuje identifikátor typu premennej oddeleného medzerou od zoznamu názvov premenných oddelených oddeľovačom - čiarkou. Na konci je bodkočiarka ukončujúca príkaz. Odteraz môžeme premennú použiť vo výrazoch (algebraických aj logických) a vždy tam kde sa použijú ich mená pracuje sa s ich obsahom t.j. s ich hodnotou. Rôzne deklarácie jednej premennej /*podtrhovník v názvoch je považovaný za platný znak */ int cele_cislo ; /* */ short int kratke_celecislo ; long int dlhe_celecislo ; unsigned int vzdy_kladné_cislo_int ; char znak_1byte; float realne_cislo; /* reálne čísla t.j. s desatinnou bodkou, prípadne aj ako "vedecke" čísla napr. 0.125e-3 */ double realne_cislo_dvojnasobnej_velkosti ; Vzor deklarácie viacero premenných jedným príkazom int cislo1, cislo2, cislo3; Vzor deklarácie s priradením hodnoty - jav nazývaný Inicializácia char backslash='\\'; // prvé spätné lomítko je riadiace ktoré zruší int i=0; // riadiacu funkciu druhého lomítka = znak float eps=1.0e-5; /* číslo zapísané vo "vedeckej notácii" */ Funkcia
svoj obsah získava za chodu od programu (správne podprogramu),
ktorý funkcia prezentuje. Funkcia - základný stavebný prvok jazyka C /* najmenší program bez praktickej činnosti bude pozostávať z jedinej * funkcie main. Zdrojový text bude uložený v súbore s názvom * súboru <menosub>.c resp. <menosub>.cpp */ void main (void) /* Definícia hlavnej funkcie main programu */ { } Ako vidno najmenší spustiteľný program v C -jazyku je zápis definície hlavnej funkcie - main ( ) . Každý program má svoj začiatok. Programy v C jazyku majú svoj začiatok presne na prvej inštrukcii ktorá nasleduje za otváracou zloženou zátvorkou { . Každá otváracia zátvorka v C-jazyku má aj svoju uzatváraciu zátvorku } a spoločne vytvárajú príkazový blok. Zložený príkaz alebo Blok príkazov (obdoba begin end; ) { } /* zložené zátvorky ohraničujú svet dnu od sveta von. Vo vnútri platia lokálne zákony. Navonok blok vystupuje ako jeden príkaz. Preto tam, kde môžeme použiť jeden príkaz, môžeme miesto neho použiť blok príkazov. V bloku môžeme definovať aj lokálne premenné ktoré vonkajší svet neuvidí. */ Slovo void na začiatku funkcie oznamuje že funkcia nebude vracať návratovú hodnotu. Ak miesto void uvedieme identifikátor typu premennej alebo neuvedieme nič, potom funkcia bude vracať uvedený typ premennej alebo implicitne typ integer - celočíselná premenná. Napríklad v jazyku Pascal existuje pojem funkcia a pojem procedúra. Funkcia vracia návratovú hodnotu a procedúra nie. V C jazyku procedúra neexistuje, ale existuje jej náhrada vo forme funkcie typu void, ktorá definuje funkciu bez návratovej hodnoty. Hlavný program void main(void) { } //len jedna a žiadna iná funkcia nesmie mať názov main Názvy konštánt, funkcií a premenných sa používajú vo výrazoch ako ich poznáme z matematiky. Meno funkcie však naviac musí mať za sebou pár okrúhlych zátvoriek ( ). Zátvorky sú povinné - charakterizujú funkciu - a musia sa uvádzať, aj keby ich obsah mal ostať prázdny. Do týchto zátvoriek sa zapisujú v programe parametre funkcie (Pozn.: analogicky matematicky argumenty funkcie) - sú to premenné ktoré sú k dispozícii pre vnútorné využitie v rámci bloku príkazov funkcie. Naučme drobčeka rozprávať sa!#include<iostream.h> /* bez tohto riadku by program nepoznal príkazy cin a cout ktoré teraz použijeme na komunikáciu */ void main (void) { char znak ; cout<< "Ahoj! Ako sa mas?" << endl; cin>> znak; // forma ako zastaviť program pred ukončením } Aký vzťah má program k operačnému systému a ich vzájomná komunikácia. Programová komunikácia Von t.j. smerom ku Operačnému systému = chybové hlásenie /* * Vložte ho do súboru pokus1.c resp. pokus1.cpp */ unsigned short int main (void) /* Definícia hlavnej funkcie main programu */ { return (0); } Tento program si zasluhuje pozornosť a bližšie vysvetlenie. Predtým použité "záslepky" typu void urobil program voči okoliu hluchým a slepým. Takto doplnený program už vie komunikovať s Operačným systémom a odovzdávať mu chybové stavové slovo. Typ funkcie definuje komunikačnú bránu programu von a argumenty funkcie main - t.j. parametre definované v okrúhlych zátvorkách - predstavujú cestu komunikácie smerom do programu. Najprv vysvetlíme, ako komunikuje program von smerom ku Operačnému systému. V uvedenom príklade program má jedinú funkciu main, ktorá predstavuje vlastné telo programu. Hlavička obsahuje popis typu návratovej hodnoty int ale jej obsah by nemal prevýšiť hodnoty od 0 do 255. To je presne typ údaja ktorú potrebuje dostávať systemová premenná operačného systému DOS s názvom ERRORLEVEL. Táto slúži programom na odovzdávanie stavu ukončenia programu. Ak program skončil bezchybne ERRORLEVEL bude obsahovať 0. Ak skončil s chybou bude obsahovať hodnotu chyby. Využitie systémovej premennej ERRORLEVEL je napríklad v dávkových súboroch .BAT, kde sa takto môže vyhodnotiť stav, ako skončil program spustený na predošlom riadku dávkového súboru. (Pozn.: Súčasťou knižničných súborov rôznych nástrojov na tvorbu programou sú funkcie, ktoré umožňujú spustiť externý program a po jeho ukončení vyhodnotiť systémovú premennú ERRORLEVEL) Na odovzdanie hodnoty funkcii slúži príkaz return (0); . Po jeho uvedení program skončí. Program môže mať viac koncov s return príkazmi - a v každom iné chybové číslo. Komunikácia programu s Operačným systémom smerom dnu - štartovanie programu a odovzdanie parametrov programu. /* * Vložte ho do súboru pokus1.c resp. pokus1.cpp */ void main (int argc, char *argv[]) /* Definícia hlavnej funkcie main programu */ { /* V tele programu môžeme pracovať s lokálnou premennou argc obsahujúcou počet prvkov poľa argv[0] - názov programu argv[1] - obsah 1. parametra argv[2] - obsah 2. parametra ... argv[orgc-1] - obsah posledného parametra (indexy sú číslované od 0) */ } Klasicky štartovaný program v príkazovom riadku má na začiatku uvedenú cestu k programu, za tým názov štartovaného programu a za názvom 0 a viac parametrov oddelených medzerami. Program odštartovaný s parametrami môže takto dostať základné pracovné informácie, ktoré okamžite môžu usmerniť ďalší priebeh činnosti. Len na okraj spomeniem, že program môže dáta dostať aj zo súborov, alebo v priamej komunikácii s obsluhou cez klávesnicu. Táto metóda používa dva argumenty funkcie main - historicky vžité pod kožu programátorov - z ktorých prvé argc predstavuje počítadlo počtu vstupných parametrov a druhé obsahuje pole kde každý prvok poľa obsahuje jeden z argumentov. S problematikou poľa sa budeme zaoberať neskôr, ale už teraz spomeňme, že pole má svoj názov argv a k jednotlivým prvkom sa pristupuje cez indexy - poradové čísla uzatvorené v hranatých zátvorkách: argv[0], argv[1], argv[2], ..., argv[argc-1] Príklad: Majme program nazvaný pokus.exe spustený príkazom: pokus param1 param2 Po spustení programu sa reťazce spúšťacieho riadku oddelené oddeľovačom medzera uložili ako reťazce "pokus", "param1", "param2". Aplikácia t.j. program pokus.exe môže s nimi pracovať ako s údajmi argc == 3
..... počet reťazcov Presvedčíme sa o tom v nasledovnom programe v ktorom zavedieme aj komunikáciu s užívateľom . Príklad použitia vymenovaných konštánt. #include <iostream.h> int main(void) { enum Dni { Nedela, Pondelok, Utorok, Streda, Stvrtok, Piatok, Sobota }; Dni DenDovolenky; int x; cout << "Ktorý deň beriete na dovolenku(0-6)? "; cin >> x; DenDovolenky = Dni(x); // pretypovanie int x na typ Dni x if (DenDovolenky == Nedela || DenDovolenky == Sobota) cout << "\nDovolenka cez víkend - to je chyba!!!\n"; else cout << "\nOK! Je to pracovný deň!\n"; return (0); } Komunikácia programu s operačným systémom a s užívateľom. Na to aby program mohol komunikovať musíme k základnému programu pripojiť knižnicu s komunikačnou funkciou. Použijeme na to hlavičkový súbor iostream.h obsahujúci funkcie cout a cin. Jeden zabezpečuje výstup a druhý vstup. /* * Vložte ho do súboru .c resp. .cpp */ #include <iostream.h> // pripoj externú knižnicu s komunikačný softvérom #include <conio.h> #include <stdio.h> unsigned short int main (int argc, char *argv[]) /* Definícia hlavnej funkcie main programu */ { cout << "Vitaj Ty tam.\n"; cout << "Tu je výpis 5: " << 5 << "\n"; cout << "Manipulátor endl vypíše nový riadok na obrazovku." << endl; cout << "Tu je veľmi veľké číslo:\t" << 70000 << endl; cout << "Tu je suma z 8 a 5:\t" << 8+5 << endl; cout << "Tu je podiel:\t\t" << (float) 5/8 << endl; cout << "A teraz veľmi veľké číslo:\t" << (double) 7000 * 7000 << endl; cout << "Nezabudni sem napísať svoje meno Janko Hraško ...\n"; cout << "Janko Hraško je programátor v C++ !\n"; cout << "Pri štartovaní programu som našiel " << (int) argc << " parametrov " ; cout << "Názov programu je :" << argv[0] ; getch(); return (0); } Program bude vypisovať nasledovné hlásenia: Vitaj Ty tam. Spôsob použitia návratovej hodnoty funkcie main Nasedlovný program Vracia návratovú hodnotu načítanú pred koncom. /* * Program s nastaviteľnými návratovými hodnotami */ #include <iostream.h> // cout, a cin #include <conio.h> // #include <stdio.h> unsigned short int main (int argc, char *argv[]) /* Definícia hlavnej funkcie { int Vysledok=0; clrscr(); cout << "Program použil " << (int) argc << " parametrov " << endl; cout << "Bol spustený program:" << argv[0] << endl; cout << "Program ma tieto parametre" << endl; for (int i=1; i< argc; i++) cout << "Parameter " << i <<" je: " << argv[i] << endl; cout << "Udaj návratovú stavovú hodnotu:" ; cin >> Vysledok; cout << "Nacital som "<< Vysledok ; getch(); return (Vysledok); } Ukážka je zavolá funkciu aj s parametrami z .bat súboru. Program sa môže vrátiť so stavom 0- bezchybné ukončenie resp.1- chybové ukončenie. @ECHO OFF cls echo. echo. pokus param1 param2 echo. if errorlevel 0 goto SPRAVA0 if errorlevel 1 goto SPRAVA1 GOTO QUIT :SPRAVA0 echo. echo Program skoncil bez chyby echo. pause GOTO QUIT :SPRAVA1 echo. echo Program skoncil s chybou číslo 1 echo. pause :QUIT echo Koniec dávky echo. Jednoduchý príkaz: - priraďovací výraz ktorý sa vykoná ako príkaz Premenná = Výraz ; // priraďovací výraz - nie je to rovnica! (Premenná = Výraz); // rovnaký priraďovací výraz Na výrazy musíme nazerať ako na vyjadrenie hodnoty. Priraďovací výraz má dve funkcie, jednak vyjadruje hodnotu a jednak priraďuje hodnotu premennej naľavo od operátora = . Priraďovací príkaz má tri časti. Na ľavej strane je premenná, v strede operátor priradenia a napravo Výraz. Výraz sa vyhodnotí a priradí sa premennej naľavo. Spojená ľavá a pravá časť vytvárajú dokopy priraďovací výraz. Bodkočiarka na konci z neho robí príkaz. Priraďovací výraz uzatvorený v zátvorkách vracia hodnotu rovnajúcu sa pravej strane priraďovacieho výrazu vo vnútri zátvorky. Obe verzie priraďovacích výrazov v ukážke sú úplne rovnocenné. Spomenutá vlastnosť umožňuje viacnásobné reťazové priradenie. Hromadné priradenie rovnakej hodnoty Premenn1 = Premenná2 = ... PremennáN= Výraz ; /* Príkazy sa vykonávajú Ešte raz vezmite na vedomie: Vlastnosťou výrazu v C-jazyku (hoci aj priraďovacieho) je, že ako celok vracia hodnotu. Túto hodnotu môžeme použiť uzavretú medzi okrúhlymi zátvorkami. Môžu takto vzniknúť kuriózne kombinácie spojenia operácií: Kombinovaný výraz - načítanie znaku pri súčasnom porovnaní na jeho obsah ((c=getchar()) != '*') // načítanie znaku do C a vyhodnotenie na nerovnosť so znakom * // getchar je funkcia načítania 1 znaku z klávesnice // to isté rozpísané do dvoch výrazov c=getchar(); // načítanie znaku do C ( c != '*' ) // vyhodnotenie na nerovnosť so znakom * Výraz v zátvorke obsahuje dve rôzne akcie. Priraďovací príkaz c=getchar() číta jeden znak z klávesnice. Načítaný znak sa vloží do premennej C, ale výraz ako celok uzavretý v zátvorkách (c=getchar()) vyjadruje načítaný znak, ktorý porovnáme s hviezdičkou pomocou operátora nonekvivalencie != (nerovná sa). Výsledkom porovnania je hodnota 0 alebo hodnota 1. Toto je ukážka ako v C jazyku vieme elegantne združiť dve činnosti do jednej. Program s definovanými premennými /* * Vložte ho do súboru pokus1.c resp. pokus1.cpp */ int A=10,B=20,C=30; // globálne premenné platné počas celého behu programu unsigned short ing main (void) /* Definícia hlavnej funkcie main programu */ { int A; // lokálna premenná dočasného trvania static int B; // lokálna statická premenná existujúca počas celého behu programu // lokálne premenné zatienia globálne premenné A=5; // a tým ich ochránia pred prepísaním! B=A*1.5*C; // funkcia pracuje s globálnou premenou priamo a toto // v programátorskej praxi nie je bezpečná činnosť return (0); }
Program v C jazyku použil definície premenných. Tu treba spomenúť fakt, že existujú 4 oblasti ktoré využíva každý program na umiestnenie kódu programu, konštánt a premenných. Oblasti sú dané existenciou tzv. index registrov, ktoré sa podieľajú na hrubom adresovaní, určovaním oblasti v rámci ktorej iné registre nastavujú adresu jemne. Kombináciou dvoch registrov vzniká absolútna adresa v operačnej pamäti. Vďaka týmto registrom poznáme tieto 4 základné oblasti:
V tomto programe sú dve skupiny definícií premenných. Prvá skupina definuje
Vzťah premenných s funkciou - odovzdávanie hodnôt a práca s globálnymi premennými. Funkcie majú svoj špeciálny spôsob odovzdávanie dát pomocou parametrov. Hovoríme tomu odovzdávanie hodnotou. Program s funkciami /* * Vložte ho do súboru pokus2.c resp. pokus2.cpp */ int A=10,B=20,C=30; // globálne premenné platné počas celého behu programu long int vynasob (int X, int Y) ; // deklarácia premennej vynásob - prototyp unsigned short int main (void) /* Definícia hlavnej funkcie main programu */ { int A; // lokálna premenná dočasného trvania static float B; // lokálna statická premenná existujúca počas celého behu programu // lokálne premenné zatienia globálne premenné A=5; // a tým ich ochránia pred prepísaním! B=A*1.5*C; B= vynasob(A,C) * 1.5; // volanie funkcie s použitím skutočných parametrov return (0); } long int vynasob (int X, int Y) // definícia funkcie aj s definíciou formálnych parametrov { return ( X*Y); } V programe je použitá funkcia vynásob ktoru sme v časti pred funkciou main deklarovali a v časti za funkciou main definovali. V definícii funkcie vidno v okrúhlych zátvorkách aj definíciu formálnych parametrov. Tieto sa počas volania funkcie vytvoria na začiatku vykonávania bloku príkazov funkcie, ako lokálne premenné, a umiestnia sa do oblasti pamäte STACK. Hodnota sa im priradí skopírovaním dát z adries skutočných parametrov. Princíp spočíva v tom, že obsah premenných, konštánt alebo iných funkcií sa priradí formálnym parametrom akoby priraďovacím príkazom. Všetky zmeny formálnych parametrov počas práce programu v bloku funkcie zostanú pre vonkajší programový priestor neviditeľné. Premenné typu pole a pointer. V programátorskej praxi je častou potrebou pracovať s veľkým množstvom dát. Ak sú to dáta toho istého typu, zbytočné by bolo dávať im individuálne názvy. Jednoduchšie je im priradiť jedno meno a pristupovať k nim pomocou indexu - t.j. poradového čísla. Defnícia poľa int a[10]; // pole premenných typu integer pre uchovaie 10 čísel a[0], a[1], ... a[9] Pole sa v Operačnej pamäti ukladá ako jedna súvislá postupnosť vyčlenených adresných priestorov, z ktorých veľkosť každého elementu zodpovedá definovanému typu premennej. Jednotlivé prvky sú dostupné adresovaním poľa s uvedeným indexom v hranatej zátvorke. Ich číslovanie začína od 0. V príklade uvedené pole má prvý prvok a[0] a posledný prvok a[9]. Defnícia poľa spojená s inicializáciou hodnôt #define MAX 10 // definovanie konštanty MAX veľkosti poľa int b[MAX]={1,2,3,4,5,6,7,8,9,10}; // veľkosť poľa možno definovať len konštantou int a[MAX + 1]={1,2,3,4,5,6,7,8,9,10,11}; // výraz obsahujúci konštanty je konštanta Využitie poľa pri bublinovom triedení - príklad pre odlaďovanie pomocou F9,F8 a F7 /* * 1. Program je demonštráciou činnosti pri bublinovom triedení prvkov * poľa celých čísel. * 2. Je ukážkou deklarovania a inicializácie prvkov poľa * 3. Je ukážkou odovzdávania parametrov typu pole funkcii, ktorá sa * sprava ako procedúra nad externým prvkom - polom int čísel. * */ #include <iostream.h> // prototypy pre cin a cout (! v .cpp) #include <conio.h> // prototypy pre clrscr // zoznam prototypov programu void vypisIntPole (int pole[],int pocet); // výpis poľa na obrazovku void zotriedIntPole (int pole[],int pocet); // zatriedenie poľa // vytvorenie poľa v oblasti GLOBÁLNYCH PREMENNÝCH const unsigned short int MAX=10; // konštanta veľkosti poľa MAX int a[MAX] ={4,3,2,1,10,9,8,7,6,5} ; // pole čísel ktoré zotriedime void main (void) { clrscr(); // vymaž obrazovku vypisIntPole(a,MAX); // výpis pred zotriedenim zotriedIntPole(a,MAX); // bublinové triedenie vypisIntPole(a,MAX); // výpis po zotriedeni // getch(); - počkaj na zatlačenie znaku a až potom ukonči program // príkaz getch(); pri krokovaní nepotrebujeme } /* bublinové triedenie - zotriedujuce obsah tabuľky od najmenšieho * prvku k najväčšiemu. Pre "počet" prvkov sa uskutoční v "pocet-1" * cyklov, lebo v každom cykle nájde jeden prvok tabuľky svoju pozíciu. * Keď sa umiestni predposledný prvok určí tým polohu posledného. * Prvky sa usporiadajú od konca tabuľky tak, že najväčšie čísla * "klesnú" na koniec a najmenšie "vyplávajú" na začiatok. * * program je upravený na sledovanie pri krokovaní pomocou F8 */ void zotriedIntPole (int pole[],int pocet) { int i,j,pomPamat,test; // pomocne pracovne premenne for (j=(pocet-1); j> 0 ; j--) // počítadlo cyklov súčasné určuje počet { // porovnávaných prvkov od začiatku tabuľky for (i=0 ; i<j ; i++) { test=(pole[i]>pole[i+1]); // ak väčší prvok predchádza menší ... if (test) { // potom ich vymeníme navzájom pomPamat=pole[i+1]; pole[i+1]=pole[i]; pole[i]=pomPamat; }// else ; ich necháme bez zmeny } } } void vypisIntPole (int pole[],int pocet) { // vypis prvkov pola cisel typu int for (int i=0 ; i<pocet ; i++) cout<< pole[i]<<" "; cout<<endl; } Defnícia viacrozmerného poľa int a[10][3]; // viacrozmerné pole premenných typu integer a[0][0], a[0][1], a[0][2] a[1][0], a[1][1], a[1][2] ... a[9][0], a[9][1], a[9][2] Pojednanie o polohe uloženia prvku. !!!!! Reťazec písmen " znaky " Špeciálne znaky používané v reťazci písmen - niektoré nahradzujú riadiace znaky keď ich chceme použiť len ako znaky
Návrat na začiatokZdroje informácií
Návrat na začiatok.Nové pojmyR Návrat na začiatok.Otázky
Návrat na začiatok. |