This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| et:programming:c:crashcourse [2013/03/26 23:15] – external edit 127.0.0.1 | et:programming:c:crashcourse [2020/07/20 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== C keele kiirkursus ====== | ||
| + | ===== Programmi ülesehitus ===== | ||
| + | |||
| + | Põhimõtteliselt võib C-keele programmi kirjutada ükskõik mis kujul, kas või üherealisena, | ||
| + | |||
| + | <code c> | ||
| + | /* Päisefailide kaasamine */ | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | /* Makro-deklaratsioonid */ | ||
| + | #define PI 3.141 | ||
| + | |||
| + | /* Andmetüübid */ | ||
| + | typedef struct | ||
| + | { | ||
| + | int a, b; | ||
| + | } | ||
| + | element; | ||
| + | |||
| + | /* Globaalsed muutujad */ | ||
| + | element e; | ||
| + | |||
| + | /* Funktsioonid */ | ||
| + | int main(void) | ||
| + | { | ||
| + | // Lokaalsed muutujad | ||
| + | int x; | ||
| + | |||
| + | // Programm | ||
| + | printf(" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Kommentaarid ===== | ||
| + | |||
| + | Programmi saab kirjutada teksti, mida ei kompileerita ja mis on programmeerijale abiks selgitamisel või märkmete tegemisel. Samuti saab kommentaare kasutada programmilõikude ajutiseks täitmisest kõrvaldamiseks. Näide kahte liiki kommentaaridest: | ||
| + | |||
| + | <code c> | ||
| + | // Üherealine kommentaar. | ||
| + | // Kommentaariks loetakse kahe kaldkriipsu järel olevat teksti | ||
| + | |||
| + | /* | ||
| + | Mitmerealine kommentaar | ||
| + | Kommentaari algus ja lõpp määratakse kaldkriipsude ja tärnidega | ||
| + | */ | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | |||
| + | ===== Andmed ===== | ||
| + | |||
| + | ==== Andmetüübid ==== | ||
| + | |||
| + | C-keele baasandmetüübid: | ||
| + | |||
| + | ^ Tüüp | ||
| + | | (signed) char | -128 | 127 | 8 | 1 | | ||
| + | | unsigned char | 0 | 255 | 8 | 1 | | ||
| + | | (signed) short | -32768 | ||
| + | | unsigned short | 0 | 65535 | 16 | 2 | | ||
| + | | (signed) long | -2147483648 | 2147483647 | 32 | 4 | | ||
| + | | unsigned long | 0 | 4294967295 | 32 | 4 | | ||
| + | | float | -3.4< | ||
| + | | double | ||
| + | |||
| + | Sulgudes olevat sõna " | ||
| + | |||
| + | AVR mikrokontrolleril //int// = //short// \\ | ||
| + | PC arvutil //int// = //long// \\ | ||
| + | |||
| + | C-keeles puudub spetsiaalne teksti-andmetüüp. Selle asemel kasutatakse //char// tüüpi massiive (nendest edaspidi) ja ASCII " | ||
| + | |||
| + | ==== Muutujad ==== | ||
| + | |||
| + | Programmis saab kasutada kindlat andmetüüpi mälupesasid - muutujaid. Muutujate nimed võivad sisaldada ladina tähestiku tähti, numbreid ja alakriipsu. Nimi ei tohi alata numbriga. Muutuja deklareerimisel kirjutatakse selle ette andmetüüp. Väärtuse omistamiseks muutujale kasutatakse võrdusmärki (=). Näide muutujate kasutamisest: | ||
| + | |||
| + | <code c> | ||
| + | char c; // char tüüpi muutuja c deklareerimine | ||
| + | |||
| + | c = 65; // Muutujale c väärtuse omistamine. | ||
| + | c = ' | ||
| + | |||
| + | // int tüüpi muutuja i20 deklareerimine ja algväärtustamine | ||
| + | int i20 = 55; | ||
| + | |||
| + | // Mitme unsigned short tüüpi muutuja deklareerimine | ||
| + | unsigned short x, y, test_variable; | ||
| + | </ | ||
| + | ==== Konstandid ==== | ||
| + | |||
| + | Konstante deklareeritakse samamoodi nagu muutujaid, kuid ette lisatakse //const// võtmesõna. Konstantide väärtust ei saa programmi käigus muuta. Näide kasutamisest: | ||
| + | <code c> | ||
| + | const int x_factor = 100; // int tüüpi konstandi määramine | ||
| + | </ | ||
| + | |||
| + | ==== Struktuurid ==== | ||
| + | |||
| + | Baasandmetüüpidest saab //struct// võtmesõnaga struktuure koostada. Struktuur on justkui kombineeritud andmetüüp. Tüüpi deklareeritakse //typedef// võtmesõnaga. Näide struktuurist andmetüübi loomise ja kasutamise kohta: | ||
| + | |||
| + | <code c> | ||
| + | // Uue punkti andmetüübi deklareerimine | ||
| + | typedef struct | ||
| + | { | ||
| + | // x ja y koordinaat ning värvikood | ||
| + | int x, y; | ||
| + | char color; | ||
| + | } | ||
| + | point; | ||
| + | |||
| + | // Punkti muutuja deklareerimine | ||
| + | point p; | ||
| + | |||
| + | // Punkti koordinaatide määramine | ||
| + | p.x = 3; | ||
| + | p.y = 14; | ||
| + | </ | ||
| + | |||
| + | ==== Massiivid ==== | ||
| + | |||
| + | Andmetüüpidest võib koostada massiive (jadasid). Massiiv võib olla ka mitmemõõtmeline (tabel, kuup, jne). Näide ühe- ja kahemõõtmelise massiivi kasutamisest: | ||
| + | |||
| + | <code c> | ||
| + | // Ühe- ja kahemõõtmelise massiivi deklareerimine | ||
| + | char text[3]; | ||
| + | int table[10][10]; | ||
| + | |||
| + | // Teksti moodustamine märgimassiivist | ||
| + | text[0] = ' | ||
| + | text[1] = ' | ||
| + | text[2] = 0; // Teksti lõpetamise tunnus (null-bait) | ||
| + | |||
| + | // Tabeli ühe elemendi muutmine | ||
| + | table[4][3] = 1; | ||
| + | </ | ||
| + | |||
| + | ===== Avaldised ===== | ||
| + | |||
| + | Muutujate, konstantide ja väärtust tagastavate funktsioonidega saab koostada avaldisi (tehteid). Avaldise väärtusi saab omistada muutujatele, | ||
| + | |||
| + | ==== Aritmeetilised ==== | ||
| + | |||
| + | C-keeles toetatud aritmeetilised tehted on liitmine (+), lahutamine (-), korrutamine (*), jagamine (/) ja mooduli võtmine (%). Näited aritmeetiliste tehete kasutamisest: | ||
| + | |||
| + | <code c> | ||
| + | int x, y; | ||
| + | |||
| + | // Mooduli võtmine, korrutamine ja väärtuse omistamine, x saab väärtuse 9 | ||
| + | x = (13 % 5) * 3; | ||
| + | |||
| + | // Liitev-omistav operaator, x väärtuseks saab 14 | ||
| + | x += 5; | ||
| + | |||
| + | // Ühe lahutamise kiirmeetod, x väärtuseks saab 13 | ||
| + | x--; | ||
| + | </ | ||
| + | |||
| + | ==== Loogilised ==== | ||
| + | |||
| + | Loogilised tehted on eitus (!), loogiline korrutamine (&& | ||
| + | |||
| + | <code c> | ||
| + | bool a, b, c; | ||
| + | |||
| + | // Algväärtustamine | ||
| + | a = true; | ||
| + | b = false; | ||
| + | |||
| + | // Eitus | ||
| + | // c väärtus tuleb väär sest tõest eitati | ||
| + | c = !a; | ||
| + | |||
| + | // Loogiline korrutamine | ||
| + | // c väärtuseks tuleb väär, sest üks operandidest on väär | ||
| + | c = a && b; | ||
| + | |||
| + | // Loogiline liitmine | ||
| + | // c väärtus tuleb tõene, sest üks operandidest on tõene | ||
| + | c = a || b; | ||
| + | </ | ||
| + | |||
| + | **NB!** //bool// andmetüüp on pärit C++ keelest ja C-keeles see tegelikult puudub, sest selle asemel on kasutusel täisarvud, kus 0 tähistab väära ja iga muu arv tõest väärtust. Kuid mugavuse pärast on //bool// Kodulabori teegis siiski kasutusel ja see on defineeritud kui //unsigned char//. Konstant //true// tähistab seal väärtust 1 ja //false// väärtust 0. | ||
| + | |||
| + | ==== Võrdlused ==== | ||
| + | |||
| + | Arvude väärtuste võrdlemisel saadakse loogilised väärtused. Võrdlustehted on samaväärsus (==), erinevus (!=), suurem (>), suurem-võrdne (> =), väiksem (<) ja väiksem-võrdne (< =). Näide kasutamisest: | ||
| + | |||
| + | <code c> | ||
| + | int x = 10, y = 1; | ||
| + | |||
| + | // Suurem-kui võrdlustehe, | ||
| + | // Tehte ümber on sulud vaid selguse pärast | ||
| + | bool b = (5 > 4); | ||
| + | |||
| + | // Erinevuse tehe | ||
| + | // Tehte tulemus on väär | ||
| + | b = (4 != 4); | ||
| + | |||
| + | // Aritmeetiline, | ||
| + | // b tuleb väär, sest esimene loogilise korrutise operand on väär | ||
| + | b = (x + 4 > 15) && (y < 4); | ||
| + | </ | ||
| + | |||
| + | ==== Bititehted ==== | ||
| + | |||
| + | Bititehted on andmetega binaarses arvusüsteemis tegelemiseks. Neid saab rakendada kõigi täisarv-tüüpi andmetega. Bititehted sarnanevad loogiliste tehetega, kuid erinevad selle poolest, et tehe teostatakse iga bitiga eraldi, mitte kogu arvuga. C keeles on bititeheteks inversioon (~), konjunktsioon (&), disjunktsioon (|), antivalentsus (^), nihe vasakule (<<) ja nihe paremale (>>). | ||
| + | |||
| + | <code c> | ||
| + | // Märgita 8-bitise char-tüüpi muutuja deklareerimine | ||
| + | // Muutuja väärtus on kümnendsüsteemis 5, kahendsüsteemis 101 | ||
| + | unsigned char c = 5; | ||
| + | |||
| + | // Muutuja c disjunktsioon arvuga 2 (kahendsüsteemis 010) | ||
| + | // c väärtuseks saab 7 (kahendsüsteemis 111) | ||
| + | c = c | 2; | ||
| + | |||
| + | // Bitinihe vasakule 2 võrra | ||
| + | // c väärtuseks saab 28 (kahendsüsteemis 11100) | ||
| + | c = c << 2; | ||
| + | </ | ||
| + | |||
| + | Bititehted on hädavajalikud mikrokontrollerite registrite kasutamisel. Täpsemalt tutvustab neid AVR registrite peatükk. | ||
| + | |||
| + | ===== Funktsioonid ===== | ||
| + | |||
| + | Funktsioon on programmilõik, | ||
| + | |||
| + | <code c> | ||
| + | // Kahe int tüüpi parameetriga funktsioon, mis tagastab int-tüüpi väärtuse | ||
| + | int sum(int a, int b) { | ||
| + | // Kahe arvu liitmine ja summa tagastamine | ||
| + | return a + b; | ||
| + | } | ||
| + | |||
| + | // Ilma parameetrite ja tagastatava väärtuseta funktsioon | ||
| + | void power_off(void) { | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Funktsiooni kasutamiseks tuleb see välja kutsuda. Funktsioon peab programmikoodis olema deklareeritud enne välja kutsumise kohta. Näide liitmisfunktsiooni väljakutsumisest. | ||
| + | |||
| + | <code c> | ||
| + | int x; | ||
| + | int y = 3; | ||
| + | |||
| + | // Liitmisfunktsiooni väljakutsumine, | ||
| + | x = sum(y, 5); | ||
| + | |||
| + | // Väljalülitamise funktsiooni väljakutsumine, | ||
| + | power_off(); | ||
| + | </ | ||
| + | |||
| + | C-keele programmi täitmist alustatakse //main// nimelisest funktsioonist, | ||
| + | |||
| + | |||
| + | ===== Laused ===== | ||
| + | |||
| + | ==== Tingimuslause ==== | ||
| + | |||
| + | Tingimuslause võimaldab vastavalt sulgudes oleva avaldise tõesusele täita või mitte täita tingimusele järgnevat lauset või programmilõiku. Tingimuslause võtmesõna on //if//. Näide kasutamisest: | ||
| + | |||
| + | <code c> | ||
| + | // Avaldis on tõene ja lause täidetakse, | ||
| + | // sest 2 + 1 on suurem kui 2 | ||
| + | if ((2 + 1) > 2) x = 5; | ||
| + | |||
| + | // Kui x on 5 ja y on 3, siis täidetakse järgnev programmilõik | ||
| + | if ((x == 5) && (y == 3)) | ||
| + | { | ||
| + | // Suvaline tegevus | ||
| + | y = 4; | ||
| + | my_function(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Tingimuslause võib olla pikem ja sisaldada ka lauset või programmilõiku, | ||
| + | |||
| + | <code c> | ||
| + | // Kas x on 5 ? | ||
| + | if (x == 5) | ||
| + | { | ||
| + | // Suvaline tegevus | ||
| + | z = 3; | ||
| + | } | ||
| + | // Kui x ei olnud 5, kas siis x on 6 ? | ||
| + | else if (x == 6) | ||
| + | { | ||
| + | // Suvaline tegevus | ||
| + | q = 3; | ||
| + | } | ||
| + | // Kui x ei olnud 5 ega 6... | ||
| + | else | ||
| + | { | ||
| + | // Suvaline tegevus | ||
| + | y = 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Valikulause ==== | ||
| + | |||
| + | Kui on vaja võrrelda avaldist mitme erineva väärtusega, | ||
| + | |||
| + | <code c> | ||
| + | int y; | ||
| + | |||
| + | // Tingimuslause y võrdlemiseks | ||
| + | switch (y) | ||
| + | { | ||
| + | // y on 1 ? | ||
| + | case 1: | ||
| + | // Suvaline tegevus | ||
| + | function1(); | ||
| + | break; | ||
| + | |||
| + | // y on 2 ? | ||
| + | case 2: | ||
| + | // Suvaline tegevus | ||
| + | function2(); | ||
| + | break; | ||
| + | |||
| + | // Kõik muud juhtumid | ||
| + | default: | ||
| + | // Suvaline tegevus | ||
| + | functionX(); | ||
| + | // break lauset pole vaja, | ||
| + | // kuna võrdlemine lõpeb nagunii | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Tsüklid ===== | ||
| + | |||
| + | Tsüklitega saab programmilõiku täita mitmeid kordi. | ||
| + | |||
| + | ==== while ==== | ||
| + | |||
| + | //while// võtmesõnaga tähistatud programmilõiku täidetakse seni, kuni sulgudes olev avaldis on tõene | ||
| + | |||
| + | <code c> | ||
| + | int x = 0; | ||
| + | |||
| + | // Tsükkel kestab seni, kuni x on väiksem kui 5 | ||
| + | while (x < 5) | ||
| + | { | ||
| + | // x suurendamine ühe võrra | ||
| + | x++; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== for ==== | ||
| + | |||
| + | //for// võtmesõnaga tsükkel sarnaneb //while// tsüklile, kuid lisaks on sulgudes ära määratud enne tsüklit täidetav lause ja iga tsükli ajal täidetav lause | ||
| + | |||
| + | Näide: | ||
| + | <code c> | ||
| + | int i, x = 0; | ||
| + | |||
| + | // Algul määratakse i nulliks. Tsüklit täidetaks seni, kuni | ||
| + | // i on vähem kui 5. Iga tsükli lõpus suurendatakse i ühe võrra | ||
| + | for (i = 0; i < 5; i++) | ||
| + | { | ||
| + | // x suurendamine 2 võrra | ||
| + | x += 2; | ||
| + | } | ||
| + | |||
| + | // Siinkohal tuleb x väärtuseks 10 | ||
| + | </ | ||
| + | |||
| + | ==== Tsüklis liikumine ==== | ||
| + | |||
| + | //while// ja //for// tsüklitest saab erandkorras väljuda //break// võtmesõnaga. // | ||
| + | |||
| + | <code c> | ||
| + | int x = 0, y = 0; | ||
| + | |||
| + | // Lõputu tsükkel, kuna 1 on loogiline tõesus | ||
| + | while (1) | ||
| + | { | ||
| + | // Tsüklist väljutakse, | ||
| + | if (x >= 100) break; | ||
| + | |||
| + | // x suurendamine, | ||
| + | x++; | ||
| + | |||
| + | // Kui x on 10 või vähem, siis alustatakse järgmist tsüklit | ||
| + | if (x <= 10) continue; | ||
| + | |||
| + | // y suurendamine | ||
| + | y++; | ||
| + | } | ||
| + | |||
| + | // Siinkohal on y väärtus 90 | ||
| + | </ | ||
| + | |||
| + | ===== Tekstitöötlus ===== | ||
| + | |||
| + | Tekstitöötlusfunktsioone on mikrokontrolleri puhul vaja eelkõige teksti kuvamiseks LCD ekraanile ja selle saatmiseks/ | ||
| + | |||
| + | ==== sprintf ==== | ||
| + | |||
| + | sprintf funktsioon toimib sarnaselt C-keeles üldlevinud printf funktsiooniga. Erinevuseks on funktsiooni tulemuse väljastamine puhvrisse (märgimassiivi), | ||
| + | |||
| + | Näide 1: | ||
| + | <code c> | ||
| + | #include < | ||
| + | |||
| + | char buffer[20]; | ||
| + | int a = 1, b = 2; | ||
| + | int len = sprintf(buffer, | ||
| + | |||
| + | // Tulemuseks on tekstistring "1 pluss 2 on 3" | ||
| + | </ | ||
| + | |||
| + | Näiteks kirjutab sprintf funktsioon märgimassiivi //buffer// teksti, mis on koostatud kolmest argumendist ja on vormindatud vastavalt formaadi tekstistringile. Formaadi tekstistringis tähistab marker (inglise keeles // | ||
| + | |||
| + | Näide 2: | ||
| + | <code c> | ||
| + | #include < | ||
| + | |||
| + | char x[20]; | ||
| + | sprintf(x, "%s on %d aastat vana", " | ||
| + | |||
| + | // Sama tulemuse saaksime ka konstantselt defineerida: | ||
| + | char x[] = "Juku on 10 aastat vana"; | ||
| + | </ | ||
| + | |||
| + | Teise näite formaadi tekstistringis asendatakse marker %s esimese teksti-tüüpi argumendiga ja %d teise täisarv-tüüpi argumendiga. Niipalju, kui on markereid, peab olema ka argumente ning nende tüübid peavad klappima. Samuti peavad argumendid esitatud samas järjekorras nagu markerid. Erinevat tüüpi argumentide jaoks on olemas vastavad formaadi markerid: | ||
| + | |||
| + | ^ Marker | ||
| + | | %c | Tähemärk | ||
| + | | %i või %d | Täisarv | ||
| + | | %f | Murdarv | ||
| + | | %s | Tekst | " | ||
| + | | %X | Heksadetsimaalarv| 0x3F | | ||
| + | |||
| + | Standardteegi päisefailides stdio.h, stdlib.h ja string.h on veel terve hulk erinevaid funktsioone erinevate teksti-operatsioonide teostamiseks. Näiteks on võimalik nendega teksti muundada arvudeks, tekste liita ja võrrelda, tekstist märke otsida jpm. | ||
| + | |||
| + | ===== Juhuarvud ===== | ||
| + | |||
| + | Juhuarvude genereerimine ei olegi AVR kontrolleril väga lihtne. Esmalt tuleb juhunumbrigeneraator seemendada arvuga, mille alusel genereeritakse suvaliste numbrite jada. Sama numbri järgi genereeritakse alati sama jada, seega suurema juhuslikkuse saavutamiseks on kasulik seemendus teha arvuga, mis ei ole alati sama - näiteks kasutada selleks kellaaega või lahti ühendatud ADC sisendist väärtust. | ||
| + | |||
| + | Näide, juhuarvu genereerimiseks vahemikus 1 kuni 16 (kaasa arvatud). | ||
| + | <code c> | ||
| + | #include < | ||
| + | |||
| + | srand(100); // Suvaline seemendusarv | ||
| + | int x = 1 + (rand() % 16); | ||
| + | </ | ||