Programmeerimiskeel C/Print

Vikiraamatud esitlevad:
Programmeerimiskeel C



Sisukord muuda

  1. Sissejuhatus
    1.    Kompilleerimine
      Tähendus, selle osad ja kompilleerimine kompillaatoritega: GCC, Bloodshed Dev C++, Visual C++ 2005 Express
    2.    Struktuur ja stiil
      Seletus
  2. Sisu
    1.    Põhilised keelereeglid
      keelereeglid, koodi järjekord, funktsiooni ülessehitus
    2.    Muutujad, -klassifikatsioon, -mälu
      muutujad ja nende jaotus/iseloomustus, kommentaarid, eeskujulik kood
    3.    Muutujate deklareerimine
      muutujate -deklareerimine, -väärtustamine, -nimede keelereeglid
    4.    Operaatorite tabel
      operaatite kirjeldus ja näited risttabelis
    5.    Standartne sisend-väljund
      funktsioonid, nende kasutamise kirjeldus ja eriatribuudid
    6.    Põhilised keelestruktuurid
      tsüklid a la silmused ja voo jaotus valik(ud)
    7.    Massiivid
      staatiline massiiv, deklareerimine, väärtustamine, stringid
    8.    Harjutused
      Sissejuhatus
    9. Lisa:
      Koodinäited
 

Kompileerimine muuda

Kompileerimine on tõlgendav protsess. Protsess, mis C koodi tõlgib masinkoodi, mis on binaarkeeles ja arusaadav arvutitele. Kuigi protsess on keerulisem, annab see põhimõtte kompileerimisest.

Et kompilaator ei peaks iga kord kogu koodi kompileerima, tõlgitakse see esmalt "objekti failiks" (.o - faililaiend)(standard ja oma kirjutatud #include direktiivid on juba .o faililaiendis ja neid ei pea ümber kompileerima). Kui kõik objektifailid on loodud, kogub "viitur" kõik failid kokku ja loob lõpuks käivitatava faili. See tähendab, et kui muudetakse vaid koodifaili, on vaja see vaid uuesti kompileerida ja rakendus üle viidata.

Ilma detailidesse laskumata jaguneb kompileerimisprotsess:

Preprotsessor muuda

Selles staadiumis töödeldakse "preprotsessori direktiive". Need sisaldavad #definene, #includede, makrosid ja #pragma kompilaatori sätestusi. Preprotsessori lõpuks saadakse teksti string.

Süntaksi kontrollimine muuda

See aste kindlustab, et kirjutatud on korrektne kood ja otsustab sellest programmi saamise.

Objektkood muuda

Kompilaator transleerib lähtekoodi objektkoodiks, mis on samaväärne kirjutatud koodiga ja millest linkimise käigus valmib lõplik programm. Transleerimise käigus toimub lähtekoodi korrektsuse kontroll.

Linkimine muuda

Linkimine on protsess, mille käigus linkur moodustab objektkoodi failidest laademooduli faili (kas programmi või dünaamiliselt laaditava teegi (fail laiendiga .dll või .so)). Linkimisel lahendatakse objektkoodis olevad viited teistes objektkoodi failides kirjeldatud funktsioonidele ja muutujatele ning sobitatakse funktsioonide-muutujate aadressid.

Kompileerimis staadiumi peatamis võtmed muuda

-E peatab koodi pärast preprotsessorit. Kõik preprotsessori direktiivid on asendatud tavalise koodiga. Saad täispikka koodi.
-S Peatab peale kompileerimist. Saad assambler koodi
-c peatab assembleri faasis, kuid jätab linkimise vahele. Saad objekti koodi

Erinevad kompilaatorid muuda

Keele C kompilaatoreid on väga palju. Unix'i tüüpi masinatel kompileeritakse tavaliselt terminalis ja MS Windows'il arenduskeskkonnas (IDEs).

GCC (Unix, Linux, Solaris (jne.)) muuda

Lihtkompileerimine muuda

  1. Kui oled valmis kirjutanud koodi, salvesta see ".c" faililaiendisse (selleks võid kasutada koodiredaktorit nt: Scite)
  2. Ava terminal ja liigu kausta, kus fail salvestatud on
  3. Kompileeri kood käsuga
    gcc -o pogramm kood.c
  4. Kui programmi kompileerimisel ei esinenud vigasid, saad antud programmi käivitada käsuga
    ./programm

Lisaks:

cd .. - viib 1 kataloogi võrra juurkaustale lähemale
cd Desktop - sisene kataloogi Desktop
ls - kuva elemendid antud kataloogis

Mitme faili kompileerimine üheks käitatavaks failiks muuda

  • Sama, mis oleks lihtsa kompileerimise puhul, vahega et kompileerides lisad teise kodifaili ka
    gcc -o pogramm kood_1.c kood_2.c

2 võimalus:

  • Kompileeri lähtekoodi failid objektifailideks
    gcc -c -o kood_1.o kood_1.c
    gcc -c -o kood_2.o kood_2.c
  • Lingi objektifailidest käivitatav fail
    gcc -o pogramm kood_1.o kood_2.o

Abi/Manuaali otsimine muuda

Kui sa tahad otsida manuaalist kuidas mingi funktsioon töötab, või mis lisa lipukesi läheb antud teegil kompileeridas vaja, on süsteemi juba alamsüsteemina sisse ehitatud manuaalid. Kui sa tahad otsid kindlat teemat, kirjuta terminali vastavalt:

  • Üldkuju:
    man teema
  • Näide:
    man printf

Otsida võid ka teemasid mis sisaldavad teatud sõna:

  • Üldkuju:
    man -k teemas_sisalduv_sõna
  • Näide:
    man -k math.h

Bloodshed Dev-C++ muuda

NB: Bloodshed Dev-C++ kompilaator on saadaval ka eesti keelsena ja on tasuta tarkvara.

  1. Salvesta kood faililaiendiga ".c", mitte "cpp" mida pakutakse
  2. Vajuta funktsiooni klahvi "f9" või vali menüüst "Execute" -> "Compile&Run"

Microsoft Visual Studio/Express C++ 2005 muuda

Tegemist on küll C++ kompilaatoriga, kuid pärast veidikes modifitseerimist saad kasutada ainult Programmeerimiskeelt C. Selleks tuleb:

  1. Vali uue projekti alustamisel, Win32 console application. Sealt Console application ja Empty project
  2. Lisage iga cpp-faili algusesse lause #pragma warning(disable : 4996).
  3. Ülejääd seadistus peaks paigas olema, kuid kui esineb tõrkeid, tuleks kontrollida kas:
    1. Active solution configuration oleks Debug
    2. Linker – Debugging – Generate debugging info oleks jah
    3. C/C++ - General – Debug information format peab olema Program database for edit and continue /ZI

Kompileerimise kohta:

  1. Kui kood on kirjutatud, salvestad projekt ".cpp" faililaiendiga.
  2. funktsiooni klahv "f5" käivitab kompileerimise ja käivitab loodud programmi
  3. funktsiooni klahv "f9" seab peatuspunkte
  4. funktsiooni klahv "f8"' ga on võimalik projekt sammhaaval läbi käia
  5. funktsiooni klahv "f1"' ga on võimalik avada manuaal

Ülessanded muuda

C struktuur ja stiil muuda

See osa tutvustab põhitõdesid effektiivse koodistruktuuri kirjutamisel Programmeerimisekeeles C. Kirja on pandu põhitõed liigendamisest, kommentaaridest, ja teistest elementidest, mis muudavad C koodi paremini loetavaks. Selle lugemiseks pole vajalik omada eelteadmisi Programmeerimisekeelest C.

Uustulnukad võivad kirjutada oma koodi oma suva järgi, sest lõppudelõpuks on kompillaatori asi koodi tõlkida - see on vale. Hästi disainitud koodi on kogenud programeeriatel kergem lugeda ja redigeerida. Kui luuakse tarkvara, siis tihti mitte ainult effektiivset, vaid esmalt dünaamilist(muudatusi on kerge implementeerida) ja arusaadavat.

Sissejuhatus muuda

Järgnevad kaks koodiblokki on pärast preprotsessori läbikäimist võrdväärsed: Mõlemad sisaldavad täpselt sama koodi, ning pärast kompilleerimist, saab neist täpselt sama programm. Siisiki ühel puhul on eiratud pea kõiki C struktuuri ja stiili reegleid.

Tegemist on võrdlemisi lühikese programmiga, kuid ta annab ülevaate milline vahe võiks olla oma suva järgi küljendatud koodil, ning antud reeglite põhjal kirjutatud koodi, kui seda loeb elukutseline programmeerija

Reegleid eirates:

#include <stdlib.h>
#include <time.h>
int juhuslikArv(void){return rand()%80 + 1;}
int main(void){int i, j;int massiiv[N];srand(time(0));for(i=0;i<20;i++){massiiv[i]=0;}for(i=0;i<20;i++){massiiv[i]=
juhuslikArv();j=i;while(j--){if(massiiv[i]==massiiv[j]){i--;}}}printf("Keno loto numbrid on %d",massiiv[0]);
for(i=1;i<20;i++){printf(",%d",massiiv[i]);}printf("\n");getchar();getchar();return 0;}

Reegleid jälrgides

/*
  Nimi: Harjutus ülessanne 5
  Autor: Margus Martsepp
  Kuupäev: 23.05.07 02:20
  Tööpõhimõte: 
      Koostatud programm, mis pakub välja numbrid osalemaks Keno Lotos. Numbrid on 
  vahemikus vahemikus 1-80, ning ei kordu. Väljastatakse 20 numbrit.
*/
//teegid
#include <stdlib.h>
#include <time.h>

//defineeringud
#define XXX printf("\n");getchar();getchar();return 0
#define MAXgenS 80     //tagatatavate numbrite ülempiirang
#define N 20           //tagastatavate numbrite arv

//prototüüp
int juhuslikArv(void);

//prefunktsioon
int main(void){
    int i,j;
    int massiiv[N];
    srand(time(0)) ;
     
    for(i=0;i<N;i++){//massiivi initsialiseerimine
        massiiv[i]=0;
    }

    for(i=0;i<N;i++){//massiivi väärtustamine
        massiiv[i]=juhuslikArv();
        j=i;
        
        while(j--){//kordus, mis tagab, et arvud ei korduks
            if(massiiv[i]==massiiv[j]){i--;}
        }
    }
    
    printf("Keno loto numbrid on %d",massiiv[0]);

    for(i=1;i<N;i++){
        printf(",%d",massiiv[i]);
    }
    
    XXX;//MS windowsi IDE keskonnas kompilleerides, et programm ei sulguks liiga varakult
}

//teised funktsioonid
int juhuslikArv(void){
    // funktsioon tagastab suvalise täisarvu vahemikus 1-MAXgenS
    return rand()%MAXgenS + 1;  
}

Teises koodiplokis on kasutatud:

  • liigendamist ja rea vahesid, mis märgatavalt koodi loetavust; ilma igasuguse koodi effektiivsuse erinevuseta.
  • kommentaare, mis annavad mõista mida on teha üritatud / tehtud.
  • prototüübe, mis aitavad mõista nii arvutil kui ka inimesel, mis funktsioone ja selle parameetreid on kasutatud ülessande lahendamiseks (ülikiire moodus ülevaate saamiseks).
  • Konstandid võimaldavad muuta koodi parameetreid kiiresti ja mugavalt. Üle pingutades võivad nad hoopis muuta koodi lugemise keeruliseks.

Lisaks:

  • Ka muutujate nimetused mängivad suurt rolli koodist arusaamisel, kuigi ta otseselt reegel ei ole, tuleks nimetada muutujad arusaadavalt.
  • Osad koodiredaktorid juba vaikeväärtustena võimaldavad koodikirjutamist/redigerimist lihtsustada (NT: koodivõtmesõnade värvimine, struktuuride/funktsioonide pakkumine, liigendamine "{" ja "}" märkide põhjal, koodilühendid, veapakkujad jne.)

Järgnevalt seletataksegi need täpsemalt lahti. Tuleks tähele panna, et siin kasutatud kood on vaid küljendamise eesmärgil, ning selle sisust ei pea veel aru saama.

Liigendamine muuda

Reeglid:

  • iga funktsiooni tüüp algab rea vasakust servast
  • "{" on viimane märk reas
    • järgmine rida algab ühe "tabulatsiooni" või 4 tühiku vahega võrreldes eelmisest reast eespool
  • "}" on esimene märk reas
    • kui talle ei järgne "else", siis järgnev koodisegment algab uuelt realt
    • ta algab ühe "tabulatsiooni" või 4 tühiku vahega võrreldes eelmisest reast tagapool
  • ";" lõpetab rea
    • Erandiks on tingimused nt: for korduses

Seega:

#include <stdio.h>
int main(){int i=0;printf("Tere Maailm!");for(i=0;i<1;i++){printf("\n");break;}return(0);}

- saab:

#include <stdio.h>
int main(){
    int i=0;
    printf("Tere Maailm!");
    for(i=0;i<1;i++){
        printf("\n");
        break;
    }
    return(0);
}

Lisaks

Paljud koodiredaktorid liigendavad ainult "enteri" vajutuse peale juba, kuigi tihti pole protses täisautomaatne, aitab see märgatavalt kaasa.

Reavahed muuda

Kood jaotub osadeks ja nende osade vahele on sobilik panna ka tühikud. Korrektne oleks ka kommenteerida iga osa (nt: mis tehakse, mida deklareeritakse, mis kogumikuga on tegemist jne.).

Koodist:

#include <stdio.h>
int main(){
    int i=0;
    printf("Tere Maailm!");
    for(i=0;i<1;i++){
        printf("\n");
        break;
    }
    return(0);
}

- saab:

#include <stdio.h>

int main(){
    int i=0;

    printf("Tere Maailm!");

    for(i=0;i<1;i++){
        printf("\n");
        break;
    }

    return(0);
}

Kommentaarid muuda

Kommentaarid, jagunevad oma ülessannetelt mitmeks. Koodi tuleks võtta kui tehnilist ettekannet, kus kommentaarid on seletav tekst.

Üherealised muuda

Üherealised kommentaarid märgivad koodibloki algust, ning peamiselt kirjeldavad muutujate ja kordajate kasutusviise.

Märgistus:

// - tähistab üherealise kommentaari algust reas
  • Kuni koodirea lõpuni on tegemist kommentaariga

Koodist:

#include <stdio.h>

int main(){
    int i=0;

    printf("Tere Maailm!");

    for(i=0;i<1;i++){
        printf("\n");
        break;
    }

    return(0);
}

- saab:

//vajalikud teegid
#include <stdio.h>

//peafunktsioon
int main(){
    //deklareerin muutujad
    int i=0;   //universaalne tsükli kordaja

    printf("Tere Maailm!");

    //tsüklel, mis väljastab reavahetusi ekraanile
    for(i=0;i<1;i++){
        printf("\n");
        break; //pärast esimest reavahetuse väljutakse
    }

    //väljun programmist
    return(0);
}

Mitmerealised muuda

Võimalus pikemalt kirjeldada, mida programm/funktsioon teeb. Pole harv juhus, kui korraliku kommentaari kirjutamisele kulub rohkem aega, kui pärst seda kulub programmi/funktsiooni koostamisele. Mis veelkord näitab, kui vajalik on neid kirjutada. Koodi tähtsamad kommentaarid ümbriteksetakse tärni(*) kastiga, mille parem pool on avatud.

Märgistus:

/* - tähistab mitmerealise kommentaari algust
*/ - tähistab mitmerealise kommentaari lõppu
  • kõik koodisegmendid ja tekst, mis vahele jääb on kommentaar

Kood:

//vajalikud teegid
#include <stdio.h>
 
//peafunktsioon
int main(){
    //deklareerin muutujad
    int i=0;   //universaalne tsükli kordaja
 
    printf("Tere Maailm!");
 
    //tsükel, mis väljastab reavahetusi ekraanile
    for(i=0;i<1;i++){
        printf("\n");
        break; //pärast esimest reavahetuse väljutakse
    }
 
    //väljun programmist
    return(0);
}

- pärast:

/*******************************************************************************
*  
*   Nimi:     Näiteülessane 1 (n2ide_1.c)
*   Autor:    Margus Martsepp
*   Kuupäev:  10.06.07 19:37
*   Tööpõhimõte: 
*      Tuua näide ühest lihtsast funktsioonist, mis lõpuks saab korralikult
*   küljendatud.
*      Funktsioon kuvab ekraanile stringi "Tere Maailm", läbib korduse, millest
*   kuvatakse ekraanile reavahetus. Pärast seda lõpetab programm oma töö.
*
*******************************************************************************/

//vajalikud teegid
#include <stdio.h>
 
//peafunktsioon
int main(){
    //deklareerin muutujad
    int i=0;   //universaalne tsükli kordaja
 
    printf("Tere Maailm!");
 
    //tsükel, mis väljastab reavahetusi ekraanile
    for(i=0;i<1;i++){
        printf("\n");
        break; //pärast esimest reavahetuse väljutakse
    }
 
    //väljun programmist
    return(0);
}

Prototüübid muuda

Konstandid muuda

Muutuja nimetused muuda

Kuigi nüüd omavad muutujad kommentaare oma kasutusviisidest, siis siiski oleks soovitatav nimetada muutujad ja massiivid võimalikult nende kasutusala järgi.

Näiteks:

int g; //Eksami hinne 1-10 palli skaalal
int z; //Eksami katse, arv mis sümboliseerib, mitu korda on seda eksamit tehtud

- võiks soovitatavalt olla:

int eksam_hinne; //Eksami hinne 1-10 palli skaalal
int eksam_katse; //Eksami katse, arv mis sümboliseerib, mitu korda on seda eksamit tehtud

Ülessanded muuda

Viited muuda

Keelereeglid muuda

Kiirülevaade peamistest reeglitest:

  1. C programm kirjutatakse väiketähtedes
    • erandiks on konstantid
    • erandiks on defineeritud makrode nimed
  2. C ei nõua koodi treppimist, vaid on vaba kujundusega
    • Koodi küljendamata jättes on teda raske lugeda
    • Oskust koodi küljendada peab valdama iga elukutseline programmeerija
  3. Lausendi/koodisegmendi lõppu kirjeldab semikoolon (;)
  4. Suur- ja väiketähti eristatakse!

Lisaks:

C programmis on vajalik, et struktuur või kasutatav funktsioon, selle prototüüp oleksid kompilleerija poolt enne sisse loetud, kui seda on vaja kasutada. Siin on vaid erandiks rekrusiivsed funktsioonid ja struktuurid mis viitavad iseendale.

Näide enesele viitavast struktuurist:

Omadeklareeritud struktuur omab viita sturktuurile, mida pole veel deklareeritud. Kompilleerija on võimeline seda kompilleerima, kuna viida puhul ei deklareerita otsest väärtust mälus.
struct P2is{
   struct Sisu *pSisu;
   struct P2is *pViitJ2rgmisele;
};

C kood omab järgnevat ülessehitust: muuda

Kommentaar muuda

Kommentaarid on sisukirjeldused, tarkvarale mida püüti realiseerida, kui ka ääremärkused ja seletused. Kommentaarid jagunevad kaheks:

  • ühe realine
    • Kommentaari tähis on //
  • mitme realine
    • Kommentaari algus tähis on /*
    • Kommentaari lõpu tähis on */

- nt: Osa või täis nimetus, kes kirjutas, millal kirjutati ja mida kirjutas; nt:

/*******************************************************************************
*  Nimi: Harjutus ülessanne 1 
*  Autor: Margus Martsepp
*  Kuupäev: 22.05.07 22:34
*  Tööpõhimõte: 
*      Koosta algoritm ja kirjuta programm, mis teostab konverteerimise Eesti 
*      kroonidest eurodeks ning vastupidi täpsusega kaks kohta peale koma 
*      (näiteks Y EUR = xxx.xx EEK, yy EEK= xx.xx EUR).
*******************************************************************************/

Teegid muuda

- päisesse lisatakse funktsioonide prototüübid; nt:

/* preprotsessori korraldus, mis lisab koodi päisesse teegis sisalduvad funktsiooni kirjeldavad protatüüpid*/
#include <stdlib.h> //standard funktsioonid
#include <string.h> //sisaldab sõne/stringi manipuleerimiseks funktsioone
#include <stdio.h> //sisaldab sisend&väljund funktsioone
#include <math.h> //sisaldab matemaatika funktsioone
#include <conio.h> //sisaldab tüübikinnitus funktsioone

Defieeringud muuda

Defineeringud võimaldavad kasutada preprotsessorit loomaks tuntud tüübile alias. Ennem kompilleerimist asendatakse defineeringud konstantidega, mida nad defineerisid.

  • võimaldavad koodikokkuhoidu
  • võimaldavad kiiresti muuta teatud tüüpi väärtuseid
    • massiivi ulatus
    • kindlad väärtused nt: hinnad
// preprotsessori korraldus, mis asendab enne koodi kompilleerimist kõik pii'd  3.14...'ga
#define pii 3,1415926535897932384626433832795
#define JA &&
#define V6I ||   
#define ON ==
//järgmistel ridadel on kirjeldatud funktsioonid, kasutades if-funktsiooni lühikest varianti 
#define MIN(a,b) ((a)>(b)?(b):(a))
#define MAX(a,b) ((a)<(b)?(b):(a))

Lisaks:

  • defineerida võib makrosid, mis kompilleeritakse vaid teatud tingimustel nt: kui tegemist on Win_32 keskonnaga

Struktuurid muuda

- omadeklareeritud struktuurid ja tüübid

 
typedef String *char;
struct V2rvid { 
   int Punane;
   int Roheline;
   int Sinine;
};
typedef RGB V2rvid;

Globaalsed muutujad muuda

Vaid deklareerimise asukoht, teeb neist globaalsed muutujad. Väärtused on ligipääsetavad kõigis funktsioonides.

 
RGB v2rv1;

Prototüübid muuda

Prototüüp on funktsioonide parameetrite tüüpide kirjeldus.

Näide mõnes prototüübist:

int taida_massiiv(KAUP *, int *);
int kuva(KAUP *, int);
int sordi(KAUP *, int);
int kuva2(KAUP *, int);
int kuvax(KAUP *, int);
void vaheta(KAUP *, KAUP *);

Peafunktsioon muuda

- kordineerib funktsioonide tööd, tema sees deklareeritakse lokaalsed muutujad, mida läbi parameetrite antuna saab jagada teiste funktsioonidega. Andmeid võib funktsioonidaga jagada väärtusparameetrite (ByVal[ue]) või viidaparameetrite (ByRef[erence])kaudu.

  1. ByRef puhul antakse viit mälu kohale kus asub muutuja väärtus, ning pärast väärtuse muutmist funktsioonis on tema väärtus muudetud jäädavalt
  2. ByVal puhul antakse üle koopia mälus olnud väärtusest, ning fuktsiooni kestel väärtust muutes ei muudeta algset väärtust

Funktsioonid muuda

Funktsioonid - algandmete põhjal tagastatakse väärtus või teostatakse tegevus. Andmete analüüsimiseks võivad funktsioonid deklareerida lokaalsed muutujad (mille väärtust hoitakse mälus kuni funktsiooni lõpuni) või dünaamilised muutujad, mis jääksid mittekoristamisel mällu ka pärast peaprogrammi lõppu.

Funktsiooni ülesehitus muuda

Programeerimiskeel C on funktsioonipõhine. Igale korduvale ülessandele on võimalik algandmete(parameetrite) põhjal leida lahend. Kõik funktsioonid omavad järgnevat ülesehitust:

  
funktsiooni_poolt_tagastatava_vastuse_andmetüüp funktsiooni_nimi(parameetri_tüüp parameeter){
    funktsiooni_sisu;
    return tagastatav_funktsiooni_väärtus;
}

Alati käivitatakse esimesena pea funktsioon "main". Peafunktsiooni poolt tagastatakse kombe kohaselt veakood, mis on täisarvu tüüpi (tüübitunusega - int), ning mis on 0 kui programmis ei esinenud vigasid. Kui funktsioonil puuduvad parameetrid, täidetakse parameetrite sulgud võtmesõnaga "void" või jäetakse sulud tühjaks. Seega võiks peafunktsioon välja näha:

   
int main(void){
    funktsiooni_sisu;
    return 0;
}

Funktsioonide vaheline andmevahetus muuda

Funktsioonide vahel toimub andmevahetus läbi:

  • parameetrite(andmed muutujates)
  • funktsiooni nime(tagastatakse käsuga "return funktsiooni_tüübile_vastav_muutuja_väärtus")
  • alternatiivse mälu(nt: andmed failis mis asub kõvakettal)
  • globaalsete muutujate

Et andmeid töödelda, peavad andmed olema mälus.

Andmeid on kahte laadi:

  • väärtusparameeter
  • viidaparameeter

Andmed on mälus 2'nd koodis, ning vastavalt andmetüübile on eraldatud vastav arv bitte. Läbi vormingu kuvatakse kasutajale imitatsioon, nagu oleks tegemist arvude, tekstiga või suvalise sisuga.

Muutujad muuda

Muutuja on koht mälus, kus saab väärtuseid hoida. Muutujale mälu reserveerimis protsessi nimetatakse deklareerimiseks. Muutujaid iseloomustab paindlikus, tüüp&struktuur, kogus, skoop ja väärtus.

Skoop muuda

muutuja eluiga/ligipääs, mis on kas

  1. lokaalne - piirdub deklareeritud fuktsiooni eluajaga ja deklareeritakse funktsiooni sees.
  2. globaalne - piirdub programmi eluajaga, ning on ligipääsetav igast funktsioonist ja deklareeritakse funktsiooni väljas.

Lisaks C++ toob veel erinevad skoope juurde, nagu üleklassiline, korduse sisene jne.

Kogus muuda

Koguse alusel jaotuvad andmed

  1. muutuja - andmetüübist ja arhidektuurist sõltuvalt teatud bittid, kuhu salvestatakse väärtused
  2. dimensioone omavad muutujad ehk massiivid - kogumik muutujaid. Massiivid omavad ühte kindlat andmetüüpi ja andes dimensioonile järjekorranumbri ehk indeksi, pääsetakse ligi andmetele, mis on eraldatud mäluväljale kirjutatud. Massiivi, mis omab ühte dimensiooni nimetatakse vektoriks ja kahte dimensiooni maatriksiks.

Andmetüübid muuda

Lihtsad andmetüübid on:

  1. tähemärk
    ( char )
    
  2. täisarv
    ( int, short, long, long long )
    
  3. ujukomaarv
    ( float, double, long double)
    

Tähemärgid ja täisarvud on kas märgiga (signed) või märgita (unsigned). Vaikimisi on nad märgiga. Olgu öeldud, et tähemärki on võimalik salvestada ka täisarve.

Lihtsad andmetüübid võimaldavad kirjeldada kombineeritud andmetüüpe. Viimasteks on:

  1. Massiivid
  2. Kirjed
  3. Ühendid

Kombineeritud andmetüübid võivad põhineda ka juba kirjeldatud kombineeritud andmetüüpidel. Teksti (sõne e. stringi) hoidmiseks kasutatakse tähemärkide massiivi. Eraldi vastavat andmetüüpi ei ole. Kirjed on ühest või enamast väljast koosnevad andmekogumid. Ühendid on erinevad kirjetest sellega, et nende mälukasutus vastab ainult suurimalt väljale.

Võtmesõnaga typedef saab anda igale andmetüübile uue nime.

Näited muuda

/* Täisarvu tüüpi muutuja */
int t2isarv;

/* Algväärtustatud lühike täisarv */
short lyhike_t2isarv = 42;

/* Algväärtusega lühike märgita täisarv */
unsigned short lyhike_m2rgita_t2isarv = 65535;

/* Ujukoma arv */
float ujukomaarv;

/* Algväärtustatud topelttäpsusega ujukomaarv */
double pii = 3.14159285;

/* Pikkade t2isarvude massiiv 100-st elemendist */
long massiiv[100];

/* Algväärtustatud tähtede massiiv kuni 250 tähemärgi hoidmiseks */
unsigned char string[250] = "String";

/* Uus andmetüüp nimi, mis on massiiv sajast märgita tähemärgist */
typedef unsigned char nimi[100];

/* Isikut kirjeldav struktuur */
struct isik
{
    nimi eesnimi;
    nimi perenimi;
    float pikkus;        /* meetrites */
    unsigned int vanus;  /* sekundites */
    char sugu;
};
/* ja massiiv 12 isiku andmete salvestamiseks */
struct isik isikud[12];

/* Ühendi kirjeldamine */
union yhend
{
    char c;
    short s;
    int i;
    long l;
    float f;
    double d;
};
/* Ühendi muutuja loomine. See muutuja võtab sama palju mälu kui väli d. */
union yhend yhendi_n2ide;

Väärtus muuda

Väärtuse alusel jaotuvad muutujad:

  1. konstantideks - programmi kestel muutumatu väärtust andmed (võtmesõna "const" on deklareerimisel muutuja tüübi ees). Konstandi deklareerimisel tuleb ta väärtustada. Konstandid on koodi kirjutatud arvud, tekst(kiri mis asetseb jutumärkide vahel), tähemärk(märk mis paikneb apostroofide vahel).
    const double pii=3.14;
    
    Lisaks:
    • Konstandid on ka erimärgid (nagu: \t - tabulatsion; \n - reavahetus).
    • Kõik muutujad mida saab konstantidena märkida, tuleks seda teha
  2. Muutujateks - programmi kestel oma väärtusi hoidev mälu. Muutujatele on iseloomulike programmi kestel om väärtust muuta, kui nad seda ei tee, tuleks nad deklareerida kui konstatnidena. Nenede algväärtustamine on võimalik, kuid see pole kohustuslik.
    double ostud_summa_kokku=0.0;
    

Paindlikus muuda

Paindlikuse alusel jagunevad andmed staatilisteks ja dünaamilisteks andmeteks:

  1. Staatilised on kõik andmed, millele on kompileerimise hetkeks teada andmete skoop ja mälu eraldatakse. Staatilise mälu vabastamise peale skoobi lõppu ehk prügikoristuse eest hoolitseb programm ise.
  2. Dünaamilised on andmed, millele pole kompileerimise hetkeks teada andmete skoop ja muutujatele eraldatakse mälu programmi käigus. Dünaamiliste andmete puhul tuleb organiseerida ise mälu prügikoristus. Dünaamiliseks nimetatakse ka enesepoole pöörduvaid ehk rekrusiivseid funktsioone.

Muutujad muuda

Muutujad on nimed, mille kaudu viitame teatud kohale mälus, mis hoiab väärtuseid. Olles kui väärus, oleks muutuja i, mis oleks arvväärtustatud 4'ga kasutatav tehetes, ning i+1 annaks väärtuseks 5.

Muutuja loomiseks on vaja eraldada mälu, kus hakatakse hoidma muutuja väärtuseid. Protseduuri, mis kirjeldab funktsioonis vajatud muutujate arvukust, nimetusi ja mäluvajadust - nimetatakse deklareerimiseks. Kõik muutujad tuleb deklareerida ja omavad kindlat tüüp.

Muutujate deklareerimine, algväärtustamine ja väärtustamine muuda

Meeldetuletuseks: koodisegmendi lõppu tähistatakse semikooloniga ";"

int mingi_t2isarvv22rtus;
  • deklareeritakse muutuja nimega mingi_t2isarvv22rtus mis on täisarvu tüüpi.
int num1,num2,num3;
  • deklareeritakse 3 muutujat ühes koodisegmendis, mis on kõik täisarvutüüpi
int mingi_t2isarvv22rtus=7;
  • deklareeritakse täisarvutüüpi muutuja mis algväärtustatakse numbriga 7.
mingi_t2isarvv22rtus=7;
  • (ennem deklareeritud) muutuja väärtustatakse arvuga 7.
num1=num2;
  • muutuja num1 väärtuseks saab muutuja num2 väärtus, juhul kui tal seda pole ilmneb viga.
num1=num2=num3=7;
  • muutuja num3 väärtuseks saab 7, muutuja num2 väärtuseks saab muutuja num3 väärtus ja muutuja num1 väärtuseks saab num2 väärtus

Muutujatele nimede määramine muuda

Peamised reeglid mida meeles pidada on:

  1. Muutja võib alata ladinatähestiku suur-, väiketähega või "_"
  2. Muutuja võib sisaldada numbreid, kuid mitte esimese tähena
  3. Tühikud ei ole muutuja sees lubatud
  4. Keele võtmesõnad ei saa olla muutujad
  5. Suur ja väiketähtedel tehakse vahet

Muutuja üleväärtustamine muuda

Kui on deklareeritud muutuja ja ta on väärtustatud, võib olemasolevat väärtust kasutada uue väärtuse leidmiseks.

Näide, mis demonstreerib liitmis & lahutamistehteid, kasutades olemasoleva muutuja väärtust:

#include<stdio.h>

int main(void){
    int a=32;   //a=32
    a+=a++-++a; //a=34
    a-=-a+++23; //a=46
    a+=++a;     //a=94
    
    printf("a=%d",a); //Ekraanile kuvatakse "a=94"
    getchar();
    getchar();
}

Operaatorite tabel muuda

Operaatorid Kirjeldus Näide kasutusest Assotatiivsus
Postfiks - a la järelliite operaatorid Vasakult paremale
() funktsiooni kutsuv operaator vaheta (x, y)
[] massiivi indeks operaator mas [i]
. liikme juurdepääsu operaator
objektile klassi/ühendi tüübis
või selle viitele
obj.liige
-> liikme juurdepääsu operaator
viide objektile klassi/ühendi tüübis
viit->liige

Unaarsed Operaatorid Paremalt vasakule
! loogikalise eituse operaator !eof_j6utud
~ bitikaupa eituse operaator ~mask
+ - unaarne liitmis/lahutamis operaator -num
++ -- post-suurendamis/vähendamis operaator num++
++ -- pre-suurendamis/vähendamis operaator ++num
& aadresseeriv (väärtus viidaks) operaator &andmed
* väärtusel suunav operaator *viit
sizeof sizeof operaator avaldistele sizeof 123
sizeof() sizeof operaator tüüpidele sizeof (int)
(tüüp) vormingutüüpi määrav operaator (float)i

Kordistavad Operaatorid Vasakult paremale
* / % korrutamine, jagamine ja jäägi operaatorid celsius_vahe * 9 / 5

Suurendavad Operaatorid Vasakult paremale
+ - liitmise ja lahutamise operaatorid l6pp - algus + 1

Bitkupa Operaatorid Vasakult paremale
<< vasakule nihke operaator bitid << nihke_pikkus
>> paremale nihke operaator bitid >> nihke_pikkus
& bitikaupa (and)ja operaator bitid & kustutav_mask
^ bitikaupa (xor)välistavvõi operaator bitid ^ ymberp88rav_mask
| bitikaupa (or)või operaator m22ra_mask

Relatsioonilise väärtuslikuse Operaatorid Vasakult paremale
< > <= >= vähem-kui, rohkem-kui, vähem-kui või
võrdne, rohkem-kui või võrdne
operaatorid
i < num_elemente

Relatsioonilise võrdväärtuslikuse Operaatorid Vasakult paremale
== != võrdne, mitte võrdne valik != 'n'

Loogika Operaatorid Vasakult paremale
&& ja operaator arr != 0 && arr->len != 0
|| või operaator arr == 0 || arr->len == 0
Väärtust Määravad Operaatorid Paremalt vasakule
= väärtuse loovutus operaator i = 0
+= -= *= /=
%= &= |= ^=
<<= >>=
lühendatud väärtustavad tehte operaatorid
(muutuja op= väärtus; on sama mis
muutuja = muutuja op väärtus;)
num /= 10

Operaatorite tabel märkused muuda

  • Korduste sees, on vahe kas kirjutada pre- või post- suurendamist/vähendamist! Esimesel juhul vähendataks/suurendataks muutuja väärtust kohe, teisel juhul vähendatakse/suurendatakse muutuja väärtust alles eimesel ületäitmisel.
  • Väärtustamine(=) ja võrdlemine(==) omavad erinevat operaatorit! Ehk tingimuse:
if(opilene->hinne=0){j22bistuma(opilane);}else{l6petas(opilane);}

puhul ei pärita kas hinne on 0, vaid väärtustatakse tingimuses 0'ga, pärast mida muutuks tingimus tõesesks ja kõik õpilased jäetakse istuma!

Vajalik teek muuda

stdio.h


Funktsioonid muuda

Ekraan muuda

printf ja scanf parameetriteks on vorming ja muutujate loend:

printf("vorming", muutuja1, muutuja2, ...);
scanf("vorming", &muutuja1, &muutuja2,...);
puts("väljastatav tekst");

Fail muuda

fprintf ja fscanf parameetriteks on viit failile, vorming ja muutujate loend:

fprintf(faili_viit, "vorming", muutuja1, muutuja2, ...);
fscanf(faili_viit, "vorming", &muutuja1, &muutuja2,...);
fputs("Väljastatav tekst", faili_viit);

String muuda

Ka stringi on võimalik lugeda, kui sisestust:

sscanf(string, "vorming", &muutuja1, &muutuja2,...);

Eriatribuutide kirjeldused muuda

Vorming muuda

Vorming - väljastatav tekst, mis võib sisaldada teksti, erimärke ja kuvatavate muutujate tüüpi, ning laadi.

Muutujate vormingu elemendid muuda

%c - tähemärk (char)
%s - tähemärkide massiiv (char[suurus]) ehk tekstistring (*char)
%d - täisarv (int)
%ld – pikk täisarv (long)
%f - murdarv (float)
%lf – pikk murdarv (double)

lisaks on parameetid:

miinusmärk pärast protsendimärki - joondamine vasakule
täisarvul arv enne tüübitunnuse tähti - kuvatava väljundvälja laius
murdarvul arv.teine_arv enne tüübitunnuse tähti - kuvatava väljundvälja laius ja komakohtade arv

lisaks vorming:

%x - väärtus kuueteistkümnendsüsteemis
%o - väärtus kaheksandsüsteemis

Konstant vormingu elemendid muuda

\n - reavahetus
\t - tabulatsioon

Lisaks muuda

(f)scanf() puhul, kui loetakse tähemärkväärtuseid, siis muutuja ette ampersanti ei käi!

Korduvad tegevused (tsükkel, silmus) muuda

Korduseid täidetakse, kuni kordustingimus on tõene. Kordusest saab väljuda segmendiga break;. Programmeerimiskeeles C on 3 tsükli laadi. Sümboolselt i on iteratsiooni märk ja kasutatakse korduses tavaliselt muutujana. Tavaline väljumistingimus on i<mitu.

for tsükkel muuda

Üldkuju:

for(i_alg; tingimus; i_muutus_igal_läbikäikul){sisu;}

Korduste arv on eelnevalt teada. Kasutusele on võetud tsüklimuutujaga kordus.

  1. Täidetakse iteratsioonimuutuja(te) algväärtustamisavaldis(ed), mis tavaliselt on i=0; ;
  2. Kuni tingimus on tõene (mitte arv 0), täidetakse segmenti sisu;, mis tavaliselt on i<mitu;.
  3. Pärast iga tsükli läbikäimist täidetakse avaldis(ed) i_muutus_igal_läbikäikul, mis tavaliselt on i++;.


while tsükkel muuda

Üldkuju:

while(tingimus){sisu;}

Korduste arv selgub programmi töö käigus. Eelkontrolliga kordus.

Segmenti sisu; täidetakse kuni tingimus on tõene, kui üldse.

do while tsükkel muuda

Üldkuju:

do{sisu;}while(tingimus);

Korduste arv selgub programmi töö käigus. Järelkontrolliga kordus. Segmenti sisu; täidetakse vähemalt üks kord.

Segmenti sisu; täidetakse kuni tingimus on tõene

Lisaks muuda

break; muuda

Koodisegment break; võimaldab kordusest väljuda olles tsükli sees.

continue; muuda

Koodisegment continue; võimaldab vool jätkata koheselt tsükli algusest.

Erand pre - suurendamisel/vähendamisel muuda

Pre - suurendamisel/vähendamisel täidetakse avaldis(ed) i_muutus_igal_läbikäikul enne tsükli algust, mis näeks tavaliselt välja ++i.

Tühi operaator muuda

Tühi operaator tähendab, et sisu osa puudub, ning tegevus toimub tingimuses. Seda saab rakendada mõne triviaalse juhtumi lahendamisel, nt: sõne/stringi pikkuse leidmisel.

DO-LOOP analoogia muuda

While kordust kasutatakse ka, kui BASIC'ust tuntud DO-LOOP'ina, selle normaalkuju näeks välja:

while(1){sisu_mis_sisaldab_väljumist;}

Väljumiseks kasutatakse koodisegmenti break;

Valikud muuda

Ühene ja kahene valik muuda

Kui tingimus on tõene (pole arv 0), täidetakse tegevus1, kui mitte täidetakse tegevus2. Pöördtingimuse tühjaks jätmine on sama, mis selle ära jätmine.

if(tingimus){tegevus1;}
if(tingimus){tegevus1;}else{tegevus2;}

Väärtustav kahene valiktingimus a la (iif) muuda

Tegemist on valikuga, mis väärtustab tingimuse alusel. Normaalkuju oleks

muutuja=(tingimus)?(kui_tõene):(kui_väär);

Lisaks: Seda kasutatakse mõne triviaalse juhu lahendamisel, näiteks maksimumi ja miinimumi leidmisel:

MAX = (a > b) ? a : b;
MIN = (a < b) ? a : b;


Mitmikvalik muuda

Switch muuda

Valikuid käiakse läbi kuni sobivas valikus jõutakse käsuni break;, kui ükski valik ei sobinud, täidetakse valik default.

Näiteks tavaliselt näeb mitmik tingimus välja:

switch(tingimus){
  case valik_1: tegevus1; break;
  case valik_2: tegevus2; break;
  case valik_3: tegevus3; break;
  default: tegevus4 break;
}

Meelespea:

  • Kui sobivas valikus täidetakse tegevus(ed), ning puudub segment break; jätkatakse sobivate valikute läbikäimist.
  • Default valik pole kohustuslik
  • Tingimused ja valikud peaksid olema täisarvu tüüpi
    • Tähemärgid on ka täisarvutüüpi! Neid tuleks korduses märkida nt: case('M'):, meeles tuleb pidada, et apostroof(') ei ole jutumärk(") ja suurtel ja väikestel tähtedel tehakse vahet.

Mitmik if muuda

Kuigi parema loetavuse annab arvatavasti switch, on ka if'lausetega võimaliks simureeri switchi. Nüüd ei pea me break'i kasutama, ning see võimalab näiteks breaki kasutada kordusest väljumisel.

 
if(k==0){
    }else if(k==1){
        //sisu
    }else if(k==2){
        //sisu
    }else if((k<6 && k>3)|| k==666 || k--==34){
        //sisu
    }else if(k==2){      
        //sisu
    }else{
        //sisu
}

Selle võimaluse suurimad plussid muutuvad irooniliselt tema miinusteks, kuid leidub olukordi kus tõepoolest ehk oleks ratsionaalne seda varianti kasutada.

Meelespea:

  • koodisegmendiga break; saab kasutada, näiteks väljumiseks tsüklist
  • iga else if võib sisaldada täiesti uut tingimust
  • tingimused võivad olla ka keerulised algoritmid
  • tingimused ei pea olema sama muutujaga
  • tingimused võivad muuta läbikäimisel väärtusi
    • NT: näites tähendakse see, kui k=3, siis esimese tingimusel k==2 olek vastus väär, kuid k--=34 vähendab k väärtust ja teisel tingimusel k==2 olek vastus tõene! (See teeb koodi raskest loetavaks)
  • Viimane }else{ tingimus täidetakse, kui eelnevalt olid kõik võimalused väärad, põhimõtteliselt on sama mis default swich'i puhul

Voo järje oma suva järgi muutmine kasutades goto koodisegmenti muuda

Tegemist on väga lihtsa ja traditsioonilise voo jaotus mehhanismiga, mida välditakse, kuna ta võib muuta koodi lugemise ülikeeruliseks. Goto ütleb millise goto lipiku juurest jätkata.

Üldkuju:

goto lipik_1;
   //sisu; 
lipik_1:
   //sisu;

Kui seda ülde reaalselt kasutatakse, siis olles tingimuses, mis märgib viga ja juhendab voo vigade tingimusplokki.

Lisaks muuda

  • Kui korduse või tingimuse sisu on 1 koodisegmendine, pole vaja teda ümbritseda "{" ja "}" märkidega.
  • C++'is on võimalik deklareerida muutuja skoop ka korduse siseselt! See aga tähendab, et korduse standardmuutuja i deklareerimine ülefunktsioonilise skoopiga on halb komme.

Programmeerimist ei õpita raamatust, vaid õpitakse proovides ja lahendades reaalseid ülessandeid. Vahest ehk kõige paremini õpetavabki oma loodud vigane kood, mis saab pärast mõttetööd iseseisvalt lahendatud.

Sissejuhatus muuda

See osa veel ei eelda otsest koodikirjutamise oskust, kuid tegemist on protseduuride/teadmistega mida peab valdama iga C programmeerija.

Harjutus 1 muuda

  • Loo kaust kuhu salvestada fail
  • Lisa sinna kausta fail tere.c, mille sisu on
#include <stdio.h>

int main(void) { 
  printf("Tere maailm!");
  return 0; 
}
  • Kompilleeri & käivita see fail

Harjutus 2 muuda

  • Küljenda antud koodilõik vastavalt C stiilile (selle hulgas kirjuta kommentaarid)
#include <stdlib.h>
#define XXX printf("\n");getchar();getchar();return 0

int main(void){int ex=3,nr=0,i=0,t=0,p=0;printf("Sisesta palju täisarve soovid sisestada: ");scanf("%d", &nr);
while(ex!=0 && ex!=1 && i!=nr){i++;printf("Sisesta täisarv: ");scanf("%d", &ex);switch(ex % 2){case 0: t++; break;
case 1: p++; break;default: ex=1; break;}} printf("Sisestasi %d paaris ja %d paaritut arvu.",t,p); XXX;}

Harjutus 3 muuda

  • Küljenda antud koodilõik vastavalt C stiilile (selle hulgas kirjuta kommentaarid ja prototüübid)
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#define XXX printf("\n");getchar();getchar();return 0
#define VIGA printf("- Programmi töös ilmnes viga! -");
#define maxkirjed 20
typedef struct kaup{char nimetus[25];double hind;} KAUP;
int main(void){KAUP kirje[maxkirjed];int pole=0,i=0;if(taida_massiiv(kirje,&i)!=pole){if(i!=pole){kuva(kirje,i);
sordi(kirje,i);kuva2(kirje,i);}else{VIGA}}else{VIGA}XXX;}
int taida_massiiv(KAUP *kirje, int *j){FILE *andmed, *fopen();char andmefail[]="andmed.txt";int kkk;int i=0;
if ((andmed = fopen(andmefail, "r")) == NULL){printf("Andmefaili andmete laadimisel ilmes viga!\n");kkk=0;
}else{while(!feof(andmed) || i==maxkirjed){fscanf(andmed,"%s", kirje[i].nimetus);fscanf(andmed,"%lf", 
&kirje[i].hind);i+=1;}kkk=1;}*j=i-1;int fclose(FILE *andmed);return kkk;}
int kuva(KAUP *arvuti, int i){int j;double x;for(j=1;j<i;j++){printf("\nSee pakkumine on eelmisest ");
x=arvuti[j-1].hind-arvuti[j].hind;if(x>0){printf("soodsam %6.2lf EEKi",x);}else{printf(" kallim %6.2lf EEKi",-x);}}}
int sordi(KAUP *kirje, int i){int pass, counter,k=i;while(k--){for (pass = 0; pass < i-1;pass++){
if(kirje[pass].hind>kirje[pass+1].hind){vaheta(&kirje[pass],&kirje[pass+1]);}else{}}}}
int kuva2(KAUP *arvuti, int i){printf("\n\nParim pakkumine tehti ");printf("arvutiga %s hinnaga %6.2lf EEK.",
 arvuti[0].nimetus, arvuti[0].hind);printf("\nParimuselt 2 pakkumine tehti ");   
printf("arvutiga %s hinnaga %6.2lf EEK.", arvuti[1].nimetus, arvuti[1].hind);}
void vaheta (KAUP *v1, KAUP *v2){KAUP temp;temp= *v1;*v1 = *v2;*v2 = temp;}

Muutujad muuda

Nimetamine muuda

  1. Kas muutuja nimi võib alata numbriga?
  2. Kas muutuja nimi võib alata tüpograafilise sümboliga (nagu #, *, _)?
  3. Too mõni näide C muutja nimest mis ei oleks sobilik. Miks see ei ole sobilik?

Andmetüübid muuda

  1. Nimeta vähemalt 3 andmetüüpi C's
    1. Kui palju sinu arvutil, igaüks neist mälu nõuab?
  2. Kas võime kasutada andmetüüpide nimetusi (nagu 'int', 'float') muutjate nimedena?

Väärtustamine muuda

  1. Kuidas sa deklareeriksid ja väärtustaksid muutujale 3.14, kui muutuja nimi on pii?
  2. Too näide, kas on võimalik väärtustada int tüüpi väärtus otse tüübile double?
    1. Kas vastupidine on võimalik?

Refereerimine muuda

  1. Sul on vaja muutuja "pi1" väärtusega väärtustada muutuja "pi2"?
    1. Milline oleks sellele korrektne koodisegment?
    2. Mida see tähendaks tagurpidi? Kas tegemist on lubatud/korrektse C koodisegmendiga? (isegi, kui see annab õige vastuse)?
    3. Mis oleks, kui sooviksid väärtustada muutuja "pi2" konstantse väärtusega (nagu 3.1415)
      a. Milline näeks korrektne koodisegment välja?
      b. Kas tagurpidi oleks tegemist lubatud või mitte lubatud C koodisegmendiga?

  Spiraal muuda

#include <stdio.h>
#include <stdlib.h>
#define loe if(i>=arv){break;}else{a[rida][veerg]=m[i]; i++;}//kokkuhoid
#define d 9      
#define pole_viga 0
#define on_viga 1

//globaalmuutuja
int rand_seed=10;

//prototüübid
void kuva_massiiv(int [][d]);	        
void taida_massiiv(int [][d], int*, int);   
int rand();

//funktsioonid
int main(void){
     //Muutujate deklareerimine
    int rida=d, veerg=d, arv=40, i;
     //Massiivi deklareerimine
    int m[rida*veerg];
     //2-dimensioonilise massiivi deklareerimine
    int a[rida][veerg]; 
//1)    
    //Masiivi väärtustamine                    
    for (i=0; i < arv; i++){
        m[i]=1;
    }

    //Massiivi initsialiseerimine 
    while(rida-->0){while(veerg-->0){a[rida][veerg]=0;}veerg=d;}
    
    taida_massiiv(a,m,arv);
    kuva_massiiv(a);
    
    //Massiivi initsialiseerimine 
    while(rida-->0){while(veerg-->0){a[rida][veerg]=0;}veerg=d;}
//2)
    //Kuva kahe maatriksi vahele rida
    printf("\nNende suvaliste arvudega täidetakse maatriks:");
    //Muudame genereeritavate arvude pikkust
    arv=65;
        
    //Masiivi väärtustamine                    
    for (i=0; i < arv; i++){
        m[i]=rand();
        printf(" %d,",m[i]);
    }
    printf("\n");
    
    taida_massiiv(a,m,arv);
    kuva_massiiv(a);
    
    //windowsi puhul kommenteeri järgmine rida välja
    //getchar(); getchar();  
    return pole_viga;                       //Funktsiooni edukuse tagastamine
}
/* Kirjutanud K&R
   - ragastab suvalise arvu 0 ja 32767 vahel.*/
int rand(){
    rand_seed = rand_seed * 1103515245 +12345;
    return (unsigned int)(rand_seed / 65536) % 10;
}

void taida_massiiv(int a[d][d], int *m, int arv){
    int i = 0;
    int x=0, y=d, rida=0, veerg=0;
    
    while(1>0){
        for(veerg=x;  veerg<y;  veerg++){rida=x;loe}    //Vasakult paremale read
        for(rida=x+1; rida<y;   rida++){veerg=y-1;loe}  //Ülevalt alla veerud
        for(veerg=y-2; veerg!=x; veerg--){rida=y-1;loe} //Paremalt vasakule read
        for(rida=y-1;  rida!=x;  rida--){veerg=x;loe}   //Alt üles veerud
            
        if(i>=arv){break;}else{x++;y--;}                                                   
    }                                                               
}

void kuva_massiiv(int a[d][d]){
    int rida=d, veerg=d;

    while(rida-->0){                               //Massiivi initsialiseerimine
       while(veerg-->0){
          printf("| %d ",a[rida][veerg]);
       }
       
       veerg=d;
       printf("|\n");
    }  
}

  Vaheta muuda

#include <stdio.h>

/*Prototüüp*/
void vaheta(int*, int*);

/*Programm testimiseks*/
int main(void){
	int a[]={0,0};

	printf("A=");scanf("%d", &a[0]);
	printf("B=");scanf("%d", &a[1]);

    printf("\nEnne\nA=%d\nB=%d", a[0], a[1]);
	vaheta(&a[0],&a[1]);
	printf("\nP2rast\nA=%d\nB=%d", a[0], a[1]);
	
    //windowsi puhul kommenteeri järgmine rida välja
    //getchar(); getchar(); 
    return 0;
}

/*funktsioon*/
void vaheta (int* v1, int* v2){
	int temp;

	temp = *v1;
	*v1 = *v2;
	*v2 = temp;
}