Procedurálne programovanie: 10 prednáška Gabriela Kosková
Obsah Opakovanie v príkladoch
getchar a scanf int i; ... i = getchar(); int i; char c; ... getchar() - na načítavanie znakov, nie čísel! int i; ... i = getchar(); int i; char c; ... c = getchar(); scanf("%c", &c); scanf("%d", &i); Načítanie znaku aj pomocou getchar, aj pomocou scanf
scanf a & int i; char c, str[10], *r; r = (char *) malloc(5*sizeof(char)); scanf("%d", &i); scanf("%c", &c); scanf("%s", str); scanf("%s", r); scanf očakáva adresy premenných, do ktorých má zapísať načítanú hodnotu vo funkcii scanf sa vytvorí lokálna premenná ako kópia parametra - adresa, tam sa zapíše načítaná hodnota keď skončí funkcia, zabudne sa lokálna kópia, teda zabudne sa adresa, no na tej adrese zostane načítaná hodnota i - premenná, &i - adresa premennej, c - premenná, &c - adresa premennej, str - statická adresa poľa (reťazca znakov) r - adresa poľa (reťazca znakov)
Vrátenie hodnoty cez parameter funkcie char najcastejsie_pismeno(char *str, int *pocet) { int hist['Z'-'A'+1], i, i_max; for (i=0; i<'Z'-'A'+1; i++) hist[i] = 0; for (i=0; i<strlen(str); i++) hist[toupper(str[i])-'A']++; i_max = 0; if (hist[i]>hist[i_max]) i_max = i; *pocet = hist[i_max]; return (i_max + 'A'); } char str[10], pismeno; int pocet; ... pismeno = najcastejsie_pismeno(str, &pocet);
& a && x = 11; y = 4; if (x && y) printf("*"); if (x & y) printf("+"); Čo vypíše táto časť programu? Pomôcka: 11 = (1011)2 4 = (100)2 x = 11; y = 4; if (x && y) printf("*"); if (x & y) printf("+"); Logický súčin (&&): nenulové čísla sú PRAVDA, 11, 4 sú nenulové, preto výsledok je PRAVDA vypíše sa * Bitový súčin (&): súčin po bitoch 0: NEPRAVDA + sa nevypíše Vypíše sa *
Reálne delenie dvoch celých čísel. Typová konverzia Reálne delenie dvoch celých čísel. #include <stdio.h> int main(void) { int i = 5, j = 2; float f; f = (float) i / j; printf("Typova konverzia: 1. moznost: %lf\n", f); f = i / (float) j; printf("Typova konverzia: 2. moznost: %lf\n", f); f = (float) i / (float) j; printf("Typova konverzia: 3. moznost: %lf\n", f); f = (float) (i / j); printf("Explicitna typ. konverzia - chybne: %lf\n", f); f = i / j; printf("Implicitna typ. konverzia - chybne: %lf\n", f); return 0; }
Čítanie čísel, ktoré predchádza niekoľko hviezdičiek Vrátenie znaku Čítanie čísel, ktoré predchádza niekoľko hviezdičiek #include <stdio.h> int main(void) { FILE *fr; int c, cislo, suma = 0; if ((fr = fopen("cisla.txt", "r")) == NULL) { printf("Subor cisla.txt sa nepodarilo otvorit\n"); return 1; } while (1) { while ((c = getc(fr)) == '*') /* citanie znakov '*' */ ; if (c == EOF) break; ungetc(c, fr); /* vratenie znaku spat do suboru */ fscanf(fr, "%d\n", &cislo); suma += cislo; printf("Sucet cisel je: %d\n", suma); if (fclose(fr) == EOF) printf("Subor sa nepodarilo uzavriet.\n"); return 0;
Ukazovatele Premenné obsahujúce adresy Definícia ukazovateľa: int *p; Nikdy nepracujte s ukazovateľom, ktorý ste predtým nenasmerovali na nejakú zmysluplnú adresu! Ak potrebujeme zaistiť, aby ukazovateľ neukazoval na konkrétne miesto priradíme mu hodnotu NULL
Ukazovatele int **p, *q, r; p = &q; q = &r; r = 5; & - vráti adresu premennej Ukazovatele bez operátora - hodnota premennej (ak je hodnotou adresa, tak je to adresa) int **p, *q, r; p = &q; * - vráti hodnotu premennej vezme ako adresu a z tej adresy vráti hodnotu q = &r; r = 5; printf("%p %p %p %p %p %d %p %d %d", &p, &q, &r, p, q, r, *p, *q, **p); 17 51 67 51 67 5 67 5 5 p: ukazovateľ na ukazovateľ na int q: ukazovateľ na int r: int 51 67 5 17 51 67
q: statický ukazovateľ na int Ukazovatele a polia int *p, q[5], i=0; for (i=0; i<5; i++) q[i] = i; p = q; p = q+2; /* to iste ako p = &q[2] */ i = *(q+2); /* to iste ako i = q[2] */ q: statický ukazovateľ na int p: ukazovateľ na int q[0]: int i: int q[1]: int q[4]: int 57 61 5 0 1 2 3 4 2 19 57 59 61 63 65 103
Ukazovatele &pole[0] pole+0 pole &pole[i] pole+i pole[i] *(pole+i) Adresa začiatku poľa &pole[0] pole+0 pole &pole[i] pole+i pole[i] *(pole+i) pole[0]=10; *pole=10; pole[10]=70; *(pole+10)=70; Adresa i-teho prvku poľa Hodnota i-teho prvku poľa Priradenie do 1. prvku poľa Priradenie do 10. prvku poľa
Kartotéka v knižnici Názov knihy Hlava XXII Meno autora Joseph Heller položky jednoho záznamu Názov knihy Meno autora Rok Hlava XXII Joseph Heller 1961 jeden záznam o jednej knihe (obsahujúci všetky položky) zoznam záznamov o knihách (pole)
Príklad: Kartotéka v knižnici Program načíta celé číslo n, následne načíta n záznamov o knihách a uloží ich do poľa. Potom ponúkne používateľovi menu, kde môže pridávať záznam na koniec, zmazať ktorýkoľvek záznam a ukončiť program.
Kartotéka v knižnici: implementácia #include <stdio.h> #include <stdlib.h> #include <conio.h> #define N 50 /* dlzka retazcov znakov */ #define K 50 /* max. pocet prvkov v kartoteke */ typedef struct { char meno[N]; char priezvisko[N]; } AUTOR; char nazov[N]; AUTOR autor; int rok; } KNIHA;
/* nacitanie a pridanie zaznamu na koniec zoznamu*/ void pridaj(KNIHA kniznica[], int *n); /* nacitanie indexu zaznamu a jeho zmazanie */ int zmaz(KNIHA kniznica[], int n); /* vypis zoznamu */ void vypis(KNIHA kniznica[], int n); int main() { int i, n; char c; KNIHA kniznica[K]; printf("Zadajte pocet knih: "); scanf("%d", &n); if (n > K) return 1; i = 0; /* nacitanie zaznamov do zoznamu */ while (i < n) pridaj(kniznica, &i);
do { vypis(kniznica, n); printf("p: pridanie\nz: zmazanie\nk: koniec\n"); c = tolower(getch()); switch(c) { case 'p': pridaj(kniznica, &n); break; case 'z': n = zmaz(kniznica, n); break; } } while (c != 'k'); return 0;
void pridaj(KNIHA kniznica[], int *n) { if ((*n+1) > K) { printf("Kniznica je plna.\n"); return; } else { printf("Zadajte nazov knihy, autora (meno, "); printf("priezvisko) a rok vydania:\n"); scanf("%s %s %s %d", kniznica[*n].nazov, kniznica[*n].autor.meno, kniznica[*n].autor.priezvisko, &kniznica[*n].rok); (*n)++;
int zmaz(KNIHA kniznica[], int n) { int i; printf("Zadajte index zaznamu na zmazanie: "); scanf("%d", &i); if (i < 0 || i >= n-1) { printf("Prvok sa v poli nenachadza.\n"); return n; } while (i < n-2) { kniznica[i] = kniznica[i+1]; i++; return n-1;
void vypis(KNIHA kniznica[], int n) { int i; printf("\nKNIZNICA\n\n"); for (i=0; i<n; i++) printf("%s %s: %s (%d)\n", kniznica[i].autor.meno, kniznica[i].autor.priezvisko, kniznica[i].nazov, kniznica[i].rok); printf("\n\n"); }
Námety na precvičenie kartotéka ako spájaný zoznam: typedef struct kniha{ char nazov[N]; AUTOR autor; int rok; struct kniha *dalsia; } KNIHA;
Príklad: Zlomky oddelený preklad: modul zlomky: zlomky.c a zlomky.h modul hlavny: hlavny.c
zlomky.h typedef struct { int citatel; int menovatel; } ZLOMOK; extern ZLOMOK *spocitaj(ZLOMOK *a, ZLOMOK *b); extern void vypis(ZLOMOK a);
zlomky.c #include <stdio.h> #include "zlomky.h" ZLOMOK *spocitaj(ZLOMOK *a, ZLOMOK *b) { int n; ZLOMOK *z = (ZLOMOK *) malloc(sizeof(ZLOMOK)); z->citatel = a->citatel* b->menovatel + b->citatel * a->menovatel; z->menovatel = a->menovatel * b->menovatel; n = nsd(z->citatel, z->menovatel); z->citatel /= n; z->menovatel /= n; return z; } void vypis(ZLOMOK *a) { printf("%d / %d\n", a->citatel, a->menovatel); static int nsd(int a, int b) { /* o chvilu... */
hlavny.c #include <stdio.h> #include "zlomky.h" int main() { ZLOMKY *x, *y, *z; x = (ZLOMOK *) malloc(sizeof(ZLOMOK)); y = (ZLOMOK *) malloc(sizeof(ZLOMOK)); printf("Zadajte dva zlomky: "); scanf("%d %d", &x->citatel, &x->menovatel); scanf("%d %d", &y->citatel, &y->menovatel); z = spocitaj(x, y); printf("Sucet zlomkov je: "): vypis(z); return 0; }
zlomky.h hlavny.c zlomky.c typedef struct { int citatel; int menovatel; } ZLOMOK; extern ZLOMOK *spocitaj(ZLOMOK *a, ZLOMOK *b); extern void vypis(ZLOMOK a); zlomky.h #include <stdio.h> #include "zlomky.h" ZLOMOK *spocitaj(ZLOMOK *a, ZLOMOK *b) { int n; ZLOMOK *z = (ZLOMOK *) malloc(sizeof(ZLOMOK); z->citatel = a->citatel + b->citatel; z->menovatel = a->menovatel + b->menovatel; n = nsd(z->citatel, z->menovatel); z->citatel /= n; z->menovatel /= n; } void vypis(ZLOMOK *a) { printf("%d / %d\n", a->citatel, a->menovatel); static int nsd(int a, int b) { #include <stdio.h> #include "zlomky.h" int main() { ZLOMKY *x, *y, *z; x = (ZLOMOK *) malloc(sizeof(ZLOMOK)); y = (ZLOMOK *) malloc(sizeof(ZLOMOK)); printf("Zadajte dva zlomky: "); scanf("%d %d", &x->citatel, &x->menovatel); scanf("%d %d", &y->citatel, &y->menovatel); z = spocitaj(x, y); printf("Sucet zlomkov je: "): vypis(z); return 0; } hlavny.c zlomky.c
NSD a NSN program načíta dve celé čísla a vypíše ich najväčší spoločný deliteľ (NSD) a najmenší spoločný násobok (NSN).
NSD platí algorimtus: NSD(0, 0) = 0 NSD(a, b) = NSD(b, a) NSD(a, b) = NSD(-a, b) NSD(a, 0) = ABS(a) budeme uvažovať len nezáporné čísla algorimtus: Eukleidos popísal tento algoritmus v knihe Základy (okolo r. 300 p.n.l.). Algoritmus je založený na platnosti rekurzívneho vzťahu: NSD(a, b) = NSD(b, a % b)
Dôkaz algoritmu Predpokladajme, že: a, b - čísla, ktorých NSD chceme nájsť zvyšok po delení a/b je t, teda a = qb + t Potom každý spoločný deliteľ a a b delí t bezo zvyšku (lebo t = a - qb) podobne, každý spoločný deliteľ b a t tiež delí a Potom aj najväčší spoločný deliteľ a a b je tiež najväčším spoločným deliteľom b a t Potom sa dá ďalej pokračovať s b a t namiesto a a b. Keďže t je menšie v absolútnej hodnote, pokým t nedosiahne 0
NSD int nsd(int a, int b) { int pom; do { if (a < b) { pom = a; } a %= b; } while (a); return b;
NSN najmenšie kladné číslo, ktoré je násobkom čísel a, b algorimtus: vychádza zo vzťahu: a * b = NSD(a, b) * NSN(a, b) int nsn(int a, int b) { return a * b / nsd(a, b); }
NSD a NSN #include <stdio.h> int nsd(int a, int b); int nsn(int a, int b); void main(void) { int m, n; scanf("%d %d",&m,&n); printf("NSD(%d,%d) = %d\n",m, n, nsd(m, n)); printf("NSN(%d,%d) = %d\n",m, n, nsn(m, n)); }
Príklad rozvrh Program načíta zo súboru údaje o hodinách v rozvrhu a vypíše rozvrh na obrazovku Po Ut St Št Pi So Ne Matematika Mrkvička 3 hodiny dvojrozmerné pole práca so súborom štruktúra parametre funkcie main
Vstupný súbor a štruktúra vyuč. hodina: 4 riadne hodiny 4 záznamy: MAT Maly 1 1 1 MAT Maly 4 2 3 FYZ Velky 2 3 2 ANG Pekna 3 3 3 TEL Vesely 10 5 3 SJ Zeleny 1 Súbor: deň hodina skratka predmetu meno učiteľa počet hodín Štruktúra: predmet ucitel cast: -1: voľno 0: začiatok vyuč. hodiny 1: stred alebo koniec vyuč.hodiny Námet na precvičenie: Rozvrh ako pole spájaných zoznamov
Rozvrh: príklad výstupu ----------------------------------------------------------------------- | Pondelok| MAT, Maly | | | Utorok| | | FYZ,Velky | | | Streda| | ANG,Pekna| TEL,Vesel | | Stvrtok| | | | | | | Piatok| | | SJ,Zelen| | | | Sobota| | | | | | | Nedela| | | | | |
#include <stdio.h> #include <string.h> #define N 6 /* pocet pismen v slove (5 znakov) */ #define ND 7 /* pocet dni */ #define NH 5 /* pocet hodin */ #define SUBOR "subor.txt" /* default nazov subora */ typedef enum { pondelok, utorok, streda, stvrtok, piatok, sobota, nedela }; typedef struct { char predmet[N]; char ucitel[N]; int cast; /* -1 volno, 0 zaciatok, 1 stred,koniec */ } HODINA; char *dni[] = {"Pondelok", "Utorok", "Streda", "Stvrtok", "Piatok", "Sobota", "Nedela"};
void inicializuj(HODINA rozvrh[][NH]); int nacitaj(HODINA rozvrh[][NH], char subor[]); void vypis(HODINA rozvrh[][NH]); int main (int argc, char *argv[]) { HODINA rozvrh[ND][NH]; char subor[N]; if (argc == 2) strcpy(subor, argv[1]); else strcpy(subor, SUBOR); inicializuj(rozvrh); if (nacitaj(rozvrh, subor)) { return 1; } vypis(rozvrh); return 0;
void inicializuj(HODINA rozvrh[][NH]) { int i, j; for(i=0; i<ND; i++) for(j=0; j<NH; j++) rozvrh[i][j].cast = -1; }
/* nacitanie rozvrhu zo subora */ int nacitaj(HODINA rozvrh[][NH], char subor[]) { int i, den, hodina, dlzka; FILE *f; if ((f = fopen(subor, "r")) == NULL) { printf("Nepodarilo sa otvorit subor %s.\n", subor); return 1; } while(!feof(f)) { fscanf(f, "%d %d", &den, &hodina); den--; hodina--; fscanf(f, "%s", rozvrh[den][hodina].predmet); if (strlen(rozvrh[den][hodina].predmet) > 5) rozvrh[den][hodina].predmet[5] = '\0'; /*5 zn.*/ fscanf(f, "%s", rozvrh[den][hodina].ucitel); if (strlen(rozvrh[den][hodina].ucitel) > 5) rozvrh[den][hodina].ucitel[5] = '\0'; /*5 zn.*/ fscanf(f, "%d", &dlzka); rozvrh[den][hodina].cast = 0; /*zaciatok vyuc. h.*/
/* ak ma vyuc.hod. viac ako 1 hodinu, naplnia sa dalsie zaznamy */ if (dlzka > 1) { for (i=1; i<dlzka && hodina+i < NH; i++) { rozvrh[den][hodina+i] = rozvrh[den][hodina]; rozvrh[den][hodina+i].cast = 1; } if(fclose(f) == EOF) printf("Subor sa nepodarilo zatvorit.\n"); return 0;
void vypis(HODINA rozvrh[][NH]) { int i, j; printf("\nROZVRH\n\n"); for(i=0; i<ND; i++) { /* horna ciara + ciary oddelujuce dni */ for(j=0; j<NH*12+1+10; j++) putchar('-'); printf("\n|%9s", dni[i]); /* oznacenie dna */
/* riadok */ for(j=0; j<NH; j++) { if (j == 0 || rozvrh[i][j].cast < 1) putchar('|'); /* ciara pred vyuc. hod. */ else putchar(' '); /* vo vnutri v.h. ' ' */ if (rozvrh[i][j].cast == 0) /* vypis udajov */ printf("%5s,%5s", rozvrh[i][j].predmet, rozvrh[i][j].ucitel); printf(" "); /* medzery */ if (j == NH-1) putchar('|'); /* koniec dna */ } putchar('\n'); /* prechod na dalsi riadok-den */ /* dolna ciara */ for(j=0; j<NH*12+1+10; j++) putchar('-'); printf("\n");
Binárne operácie #include <stdio.h> int main(){ printf("1 << 1 = %d\t%x\n", 1 << 1, 1 << 1); printf("1 << 7 = %d\t%x\n", 1 << 7, 1 << 7); printf("1024 >> 9 = %d\t%x\n",1024 >> 9,1024 >>9); printf("13 & 6 = %d\t%x\n", 13 & 6, 13 & 6); printf("13 | 6 = %d\t%x\n", 13 | 6, 13 | 6); printf("13 ^ 6 = %d\t%x\n", 13 ^ 6, 13 ^ 6); printf("2 & 1 = %d\t%x\n", 2 & 1, 2 & 1); printf("2 | 1 = %d\t%x\n", 2 | 1, 2 | 1); printf("2 ^ 1 = %d\t%x\n", 2 ^ 1, 2 ^ 1); return 0; } 128 = 27 1024 = 210 13: 1101 6: 110 1: 01 2: 10 1 << 1 = 2 0x2 1 << 7 = 128 0x80 1024 >> 9 = 2 0x2 13 & 6 = 4 0x4 13 | 6 = 15 0xf 13 ^ 6 = 11 0xb 2 & 1 = 0 0 2 | 1 = 3 0x3 2 ^ 1 = 3 0x3
Binárne operácie vytvori cislo s 1 na pozícii i, ostatne su 0 #include <stdio.h> #define vytvorit_cislo(i) (1 << (i)) #define rad(x, i) (((x) >> (i)) & 1) unsigned invert(unsigned x, int i, int n) { unsigned j; for (j=i; j < i+n; j++) { if (rad(x, j) == 0) x = x | (vytvorit_cislo(j)); else x = x & (~(vytvorit_cislo(j))); } return x; void vypis(unsigned x) { if (x > 0) { vypis(x >> 1); printf("%d", x & 1); vrati cislicu i-teho radu cisla x Rekurzívny výpis
Vyhľadávanie v usporiadanom poli program načíta do poľa usporiadanú postupnosť čísel a hodontu, ktorú chce v postupnosti (v poli) vyhľadať (nájsť jej index): použije sekvenčné a binárne vyhľadávanie
Sekvenčné vyhľadávanie najjednoduchšie vyhľadávanie: od začiatku poľa postupne zväčšuje index pokým nepríde na hodnotu, korá je väčšia alebo rovná alebo pokým nepríde na koniec poľa neefektívne
Sekvenčné vyhľadávanie int sekvencne(int pole[], int n, int x) { int i=0; while(i < n && pole[i] < x) i++; if(pole[i] == x) return i; return -1; }
Binárne vyhľadávanie nájdenie stredu intervalu - ak je hľadaná hodnota menšia ako hodnota stredného prvku hľadanie v ľavej polovici, inak v pravej polovici 1 2 3 4 5 6 7 8 9 10 11 12 0 1 2 3 4 5 6 7 8 9 10 11 hľadáme pozíciu hodnoty 7
int binarne(int pole[], int n, int x) { int m, l = 0, r = n-1; while (l <= r) { m = (l + r) / 2; if (x == pole[m]) return m; if (x < pole[m]) r = m - 1; else l = m + 1; } if (pole[m] == x) return -1;
#include <stdio.h> #include <stdlib.h> int sekvencne(int pole[], int n, int x); int binarne(int pole[], int n, int x); int main() { int p[100], i, n, x, vysl; char c; printf("Zadaj pocet prvkov pola (<100): "); scanf("%d", &n); if (n >= 100) { printf("Prilis velky pocet prvkov...\n"); return 1; } for (i=0; i<n; i++) { printf("p[%d]: ", i); scanf("%d", &p[i]);
printf("Zadajte hodnotu, ktora sa ma vyhladat: "); scanf("%d", &x); while(getchar() != '\n'); printf("Vyhladavat Binarne alebo Sekvencne? [b/s]: "); c = getchar(); printf("%c\n", c); if ((c = tolower(c)) == 's') vysl = sekvencne(p, n, x); else if (c == 'b') vysl = binarne(p, n, x); else { printf("Zadali ste nespravnu hodnotu.\n"); return 1; } if (vysl > -1) printf("Index hladanej hodnoty je %d.\n",vysl); else printf("Hladana hodnota sa v poli nenachadza.\n"); return 0;
Koľko písmen treba doplniť do slova aby vznikol palindrom? program načíta slovo (pole znakov) a zistí koľko najmenej písmen treba do slova doplniť tak, aby sme z neho dostali palindrom
Čo je to palindrom? slovo, ktoré je rovnaké keď sa číta odpredu aj odzadu napr. radar, ťahať, jelenovipivonelej, kobylamamalybok
funkcia palindrom Pre dĺžku menšiu ako 1, je výsledok 0 Inak: Ak sa prvé písmeno rovná poslednému v slove, rekurzívne volaj funkciu palindrom so skráteným slovom bez 1. a posl. písmena Inak je potrebné pridať jedno písmeno (buď na začiatok to posledné, alebo na koniec to prvé). Ktorá z týchto možností je lepšia nevieme, preto treba vyskúšať obe možnosti: m1 je výsledok rekurzívneho volania palindrom so slovom s bez prvého písmena, m2 je výsledok rekurzívneho volania minlength so slovom s bez posledného písmena. výsledok je potom 1 + min(m1, m2)
funkcia palindrom int palindrom(char p[], int n) { if (n <= 1) return 0; if (p[0] == p[n-1]) return palindrom(&p[1], n-2); return 1 + min(palindrom(&p[0], n-1), palindrom(&p[1], n-1)); }
#include <stdio.h> #define min(x, y) (x<y ? x : y) #define N 100 int palindrom(char p[], int n); int main() { int n = 0; char c, p[N]; printf("Zadajte slovo: "); while((c = getchar()) != '\n') p[n++] = c; printf("Na palindrom je potrebne doplnit %d pismen.\n", palindrom(p, n)); return 0; }
Hodnota polynómu v danom bode program načíta koeficienty polynómu a hodnotu premennej x a vypočíta hodnotu polynómu v bode x.
Hodnota polynómu v danom bode Efektívny algoritmus znižujúci na minimum počet násobení je známy ako Hornerova schéma: a0 + a1x + a2x2 + ... + an-1xn-1 + anxn = a0 + x (a1 + x (a2 + x (... + x (an-1 + anx)...))) polynóm stupňa N tak môže byť vyhodnotený len s použitím: N-1 operácií násobenia, N operácií sčítania
#include <stdio.h> #include <stdlib.h> float horner(float p[], int n, float x); void nacitaj(float p[], int n); int main() { int n, i; float x, *p; printf("Zadajte stupen polynomu: "); scanf("%d", &n); n++; if ((p = (float *) malloc(n * sizeof(float))) == NULL) { printf("Nepodarilo sa alokovat pol.\n"); return 1; } nacitaj(p, n); printf("Zadajte hodnotu premennej x: "); scanf("%f", &x); printf("hodnota polynomu je: %f\n", horner(p, n, x)); return 0;
Hodnota polynómu v danom bode: Hornerova schéma float horner(float p[], int n, float x) { int i; float v = p[n-1]; for (i = n-2; i >= 0; i--) v = x * v + p[i]; return v; } void nacitaj(float p[], int n) { int i; for (i=0; i<n; i++) { printf("p[%d]: ", i); scanf("%f", &p[i]); }
Prevod rímskych číslic do desiatkovej sústavy program do poľa načíta rímske číslo a prevedie ho na desiatkové
Prevod rímskych číslic do desiatkovej sústavy premenné: digit: rímska číslica prevedená na desiatkové číslo next_digit: nasledujúca rímska číslica - prevedená na desiatkové číslo decimal: časť prevedeného čísla (inicializovaná na 0) algoritmus: prečíta sa prvé písmeno digit v cykle: nasledujúce písmeno next_digit ak je digit < next_digit: z decimal sa odpočíta digit inak: do decimal sa pripočíta digit digit next_digit
#include <stdio.h> #include <stdlib.h> #define N 10 int skonvertuj_pismeno(char r); int r2d(char roman[], int n); int main() { char c, roman[N]; int n; printf("Zadajte rimske cislo: "); n = 0; while(n < N && (c=getchar()) != '\n') roman[n++] = c; roman[n] = '\0'; printf("%s: %d\n", roman, r2d(roman, n)); return 0; }
Prevod rímskych číslic do desiatkovej sústavy int skonvertuj_pismeno(char r) { switch(toupper(r)) { case 'I': return 1; break; case 'V': return 5; break; case 'X': return 10; break; case 'L': return 50; break; case 'C': return 100; break; case 'D': return 500; break; case 'M': return 1000; break; } printf("Neplatna konverzia znaku %c.\n", r); exit(1);
int r2d(char roman[], int n) { int decimal = 0, i, digit, next_digit; digit = skonvertuj_pismeno(roman[0]); i = 1; while (roman[i] != '\0') { next_digit = skonvertuj_pismeno(roman[i]); if(next_digit > digit) decimal = decimal - digit; else decimal = decimal + digit; digit = next_digit; i++ } return decimal+digit;