Tohle jsou řešené úlohy z učebnice céčka. Určitě je skoro vždycky víc správných řešení,
někdy i lepších. Programy používají spíše krkolomné zápisy, abyste si na to zvykali :-)
Všechno (skoro) jsem to kompiloval v MSVC++, takže by tam neměly být chyby a mělo by to
jít zkompilovat skoro všude. (až na jeden z posledních příkladů na fixed-point, protože
LCCčko a myslím ani MinC_Gw neznají typ __int64 to se pak musí použít pomalejší double,
nebo něco o stejné délce (obyč long nestačí, přeteče už při 2 na druhou)) Tož do toho :

                                   === Kapitola 4 ===

1) Napište program, který vytiskne :
    James Bond "Agent 007" \ # 150 % záruka # /
    spol. s.r.o.

#include <stdio.h>

void main()
{
    printf("James Bond \"Agent 007\" \\ # 150 %% záruka # / \nspol. s.r.o. \n");
    getchar();
}

2) Napište program, který přečte znak a vytiskne znak s hodnotou o 1 vyšší :
    vstup : A
    výstup : B (ASCII 66)

#include <stdio.h>

void main()
{
    char c;

    c = getchar();
    putchar(c + 1);
}

nebo

#include <stdio.h>

void main()
{
    char c;

    c = getchar();
    printf("%c (ASCII %d)\n", c + 1, c + 1);
}

3) Napište program, který přečte celé číslo a vytiskne jako hexadecimální :
    vstup : 127
    výstup : 7FH

#include <stdio.h>

void main()
{
    int i;

    scanf("%d", &i);
    printf("%xH \n", i);
}

4) Napište program, který připočítává 25% daň :
    vstup : Zadej cenu bez daně : 100
    výstup : Cena s daní : 125

#include <stdio.h>

void main()
{
    int i;

    scanf("%d", &i);
    printf("%d bez dane, %d s dani \n", i, (i * 125) / 100);
}

5) Napište program, který vypočítá obsah obdélníka :
    vstup : Zadej delku a sirku : 5 4
    výstup : Obsah obdelnika o delce 5 a sirce 4 je 20

#include <stdio.h>

void main()
{
    int i, j;

    printf("Zadej delku a sirku : ");
    scanf("%d %d", &i, &j);
    printf("Obsah obdelnika o delce %d a sirce %d je %d \n", i, j, i * j);
}

6) Napište program, který načte reál. číslo a vypíše jeho celou část :
    vstup : Zadej reál. číslo : 3.1415928
    výstup : Celá část : 3

#include <stdio.h>

void main()
{
    float f;

    scanf("%f", &f);
    printf("%.0f \n", f);
}

7) Napište program, který přečte 3 malá písmena a tiskne je jako 3 velká :
    vstup : Zadej 3 mala pismena : a b c
    výstup : ABC

#include <stdio.h>

void main()
{
    char a, b, c;

    printf("Zadej 3 mala pismena :");
    scanf("%c %c %c", &a, &b, &c);
    printf("%c %c %c \n", a + 'A' - 'a', b + 'A' - 'a', c + 'A' - 'a');
}

8) Napište program, který přečte 3 velká písmena a tiskne 3 malá obráceně :
    vstup : Zadej 3 velka pismena : ABC
    výstup : cba

#include <stdio.h>

void main()
{
    char a, b, c;

    printf("Zadej 3 velka pismena :");
    scanf("%c %c %c", &a, &b, &c);
    printf("%c %c %c \n", c - 'A' + 'a', b - 'A' + 'a', a - 'A' + 'a');
}

9) Napište program, který vyzkouší následující výrazy, jsou-li definice
    int a = 2, b = 2, c = 1, d = 0, e = 4; (vypíše hodnotu) Tím si ozkoušíte
    jek funguje ++ operátor :
    výrazy :
        a) a++ / ++c * --e
        b) --b * c++ - a
        c) -b - --c
        d) ++a - --e
        e) e / --a * b++ / c++
        f) a %= b = d = 1 + e / 2

    výstup :
        Pro výraz XXX a=x b=x c=x d=x e=x, po výrazu a=x b=x c=x d=x e=x

#include <stdio.h>

void main()
{
    int a = 2, b = 2, c = 1, d = 0, e = 4;
    int hodn;

    printf("Testuji vyraz a++ / ++c * --e\n");
    printf("a = %d, b = %d, c = %d, d = %d, e = %d\nPo vyrazu :\n", a, b, c, d, e);

    hodn = a ++ / ++ c * -- e;

    printf("a = %d, b = %d, c = %d, d = %d, e = %d\nHodnota vyrazu : %d\n", a, b, c, d, e, hodn);
}

10) Napište program, který pískne

#include <stdio.h>

void main()
{
    putchar('\a');
}






                                   === Kapitola 5 ===

1) - Napište pomocí ternárního operátoru program, který rozhodne které
     ze tří zadaných čísel je největší.

#include <stdio.h>

void main()
{
    int a, b, c;
    int x;

    printf("Zadej tri cisla : ");
    scanf("%d%d%d", &a, &b, &c);

    x = (a > b)? ((a > c)? a : c) : ((b > c)? b : c);
    // pro prehlednost (jinak to mohlo byt primo v printf
    // a nemuselo tu byt zadne x)

    printf("Nejvetsi je %d !\n", x);

    getchar();
}

2) - Napište program, který seřadí tři zadaná čísla vzestupně.

#include <stdio.h>

void main()
{
    int a, b, c; // zadane
    int x, y, z; // serazene

    printf("Zadej tri cisla : ");
    scanf("%d%d%d", &a, &b, &c);

    x = (a > b)? ((a > c)? a : c) : ((b > c)? b : c);
    z = (a < b)? ((a < c)? a : c) : ((b < c)? b : c);

    if((b > a && a > c) || (c > a && a > b))
        y = a;
    else if((a > b && b > c) || (c > b && b > a))
        y = b;
    else /*if((b > c && c > a) || (a > c && c > b))*/
        y = c;
    // prostredni je slozitejsi

    printf("Sestupne : %d, %d, %d !\n", x, y, z);

    getchar();
}

3) - Napište program, který zjistí zda je zadané číslo liché (použijte modulo %)

#include <stdio.h>

void main()
{
    int a;
    
    printf("Zadej cislo : ");
    scanf("%d", &a);

    if(a % 2) // po deleni dvema zustane zbytek
        printf("Liche !\n");
    else
        printf("Sude !\n");

    getchar();
}

4) - Napište program, který vytiskne "+" / "-" pokud je zadané číslo sudé nebo liché.

#include <stdio.h>

void main()
{
    int a;
    
    printf("Zadej cislo : ");
    scanf("%d", &a);

    putchar((a % 2)? '-' : '+');

    getchar();
}

5) - Napište program, který zjistí zda zadané číslo je 1 nebo 3 nebo 5 a vypíše "A",
     nebo zda je 2 nebo 4 nebo 6 a vypíše "B" nebo vypíše "nevím" (použijete case)

#include <stdio.h>

void main()
{
    int a;
    
    printf("Zadej cislo : ");
    scanf("%d", &a);

    switch(a) {
    case 1:
    case 3:
    case 5:
        printf("A \n");
        break;
    case 2:
    case 4:
    case 6:
        printf("B \n");
        break;
    default:
        printf("Nevim \n");
    }

    getchar();
}

6) - Napište program, který se zeptá na počet chyb a vypíše :
     - pokud počet piv je nula - "Nic si nepil"
     - větší než nula a menší (rovno) než tři - "Pohodička"
     - větší než tři a menší (rovno) než pět - "V náladě"
     - větší než pět a menší nebo deset - "Pod stůl"
     - větší než deset - "Jako puma !"

#include <stdio.h>

void main()
{
    int a;
    
    printf("Zadej pocet piv : ");
    scanf("%d", &a);

    if(a <= 0)
        printf("Nic si nepil\n");
    else if(a <= 3)
        printf("Pohodicka\n");
    else if(a <= 5)
        printf("V nalade\n");
    else if(a <= 10)
        printf("Pod stul\n");
    else /*if(a > 10)*/
        printf("Jako puma !\n");

    getchar();
}






                                   === Kapitola 6 ===

1) - Napište program, který vytiskne násobky tří od tří do dvaceti.
     Nepopužívejte % (dělení modulo)

#include <stdio.h>

void main()
{
    int i;
    
    for(i = 3; i < 20; i += 3)
        printf("%d \n", i);

    getchar();
}

2) - Napište program, který vytiskne ascii tabulku (znaky od 32 do 128)

#include <stdio.h>

void main()
{
    int i;

    printf("Ascii tabulka \n");
    
    for(i = 32; i <= 128; i ++) {
        printf("%c ", i);
        if((i - 32) % 16 == 0)
            printf("\n");
    }

    getchar();
}

3) - Napište program, který čte čísla, dokud nezadáte 999 a potom
     vytiskne jejich průměr.

#include <stdio.h>

void main()
{
    int cislo, pocet, soucet;

    cislo = 0;
    pocet = -1;
    soucet = 0;
    // dulezite

    do {
        pocet ++;
        soucet += cislo;

        scanf("%d", &cislo);
    } while(cislo != 999);
    // takhle tam ta 999 nebude zapocitana

    /*
    pocet = 0;
    soucet = 0;
    // dulezite

    do {
        scanf("%d", &cislo);

        pocet ++;
        soucet += cislo;
    } while(cislo != 999);
    // takhle by tam byla zapocitana
    */

    printf("Prumer je %d\n", soucet / pocet);

    getchar();
}

4) - Napište program, který vytiskne posloupnost čísel 1 5 13 29 od
     1 do 500 (vždycky další číslo je (předchozí * 2) + 3)

#include <stdio.h>

void main()
{
    int i;
    
    for(i = 1; i < 500; i = i * 2 + 3)
        printf("%d \n", i);

    getchar();
}

5) - Napište program, který vypíše tabulku prvočísel od 1 do 100.
     Použijte % (dělení modulo)

#include <stdio.h>

void main()
{
    int i, j;
    
    for(i = 1; i < 100; i ++) {
        for(j = 2; j <= i; j ++) {
            if((i % j) == 0)
                break;
        }
        // pokud je necim delitelne, vyskoci z cyklu
        
        if(j == i)
            printf("%d, ", i);
        // husty, co ? pokud je to prvocislo, dojde j az do i !!

        if(i == 50)
            putchar('\n');
    }

    getchar();
}

6) - Napište program, vytisknuvší tabulku mocnin zadaného čísla od 0 do 10

#include <stdio.h>

void main()
{
    int i, n, m;

    printf("Zadej cislo : ");
    scanf("%d", &n);
    
    for(i = 0, m = 1; i <= 10; i ++, m *= n)
        printf("%d ^ %d = %d \n", n, i, m);

    getchar();
}






                                   === Kapitola 4b ===

1) Napište program, kopírující obsah souboru a.txt do b.txt

#include <stdio.h>

void main()
{
    FILE *fr, *fw;
    int c;

    fr = fopen("a.txt", "r");
    fw = fopen("b.txt", "w"); // otevreme pro zapis
    if(fr == NULL || fw == NULL) {
        printf("Soubor nejde otevrit !\n");

        if(fr != NULL)
            fclose(fr);
        if(fw != NULL)  // před koncem programu musíme
            fclose(fw); // uzavřít všechny soubory

        getchar();
        return;
    }

    while((c = fgetc(fr)) != EOF)
        fputc(c, fw);
    // kopíruje až do konce

    fclose(fr);
    fclose(fw);

    getchar();
}

2) Zkuste napsat program, který spočítá mezery v souboru Text.txt

#include <stdio.h>

void main()
{
    int c, n_mez;
    FILE *fr;

    fr = fopen("Test.txt", "r");

    if(fr == NULL) {
        printf("Soubor Test.txt nejde otevrit !\n");

        getchar();
        return;
    }

    n_mez = 0;
    // důležité !

    while((c = fgetc(fr)) != EOF) {
        if(c == ' ')
            n_mez ++;
    }
    // počítá mezery

    fclose(fr);

    printf("V souboru Test.txt je %d mezer\n", n_mez);

    getchar();
}

3) Napište program, který spočítá slova v souboru Text.txt

#include <stdio.h>

void main()
{
    int c, c_predch, n_slov;
    FILE *fr;

    fr = fopen("Test.txt", "r");

    if(fr == NULL) {
        printf("Soubor Test.txt nejde otevrit !\n");

        getchar();
        return;
    }

    c_predch = ' ';
    n_slov = 0;
    // důležité !

    while((c = fgetc(fr)) != EOF) {
        if((c == ' ' || c == '\n') && (c_predch != ' ' && c_predch != '\n'))
            n_slov ++;
        c_predch = c;
    }
    // počítá slova

    if(c_predch != ' ' && c_predch != '\n')
        n_slov ++;
    // spocita posledni slovo za kterym je EOF a ne mezera

    fclose(fr);

    printf("V souboru Test.txt je %d slov\n", n_slov);

    getchar();
}

4) Pokuste se o program, který spočítá samohlásky v souboru Text.txt

#include <stdio.h>

void main()
{
    int c, n_sam;
    FILE *fr;

    fr = fopen("Test.txt", "r");

    if(fr == NULL) {
        printf("Soubor Test.txt nejde otevrit !\n");

        getchar();
        return;
    }

    n_sam = 0;
    // důležité !

    while((c = fgetc(fr)) != EOF) {
        if(c >= 'A' && c <= 'Z')
            c += 'a' - 'A';
        // převede píseny na maly

        switch(c) {
        case 'a':
        case 'e':
        case 'i':
        case 'o':
        case 'u':
        case 'y':
            n_sam ++;
        }
    }
    // počítá samohlásky

    fclose(fr);

    printf("V souboru Test.txt je %d samohlasek\n", n_sam);

    getchar();
}






                                   === Kapitola 7 ===

1) - Napište program, který pomocí makra zjistí pokud je zadané číslo liché.

#include <stdio.h>

#define Liche(num) ((num) % 2)

void main()
{
    int n;

    printf("Zadej cislo : ");
    scanf("%d", &n);
    
    if(Liche(n))
        printf("Liche \n");
    else
        printf("Sude \n");

    getchar();
}

2) - Napište makro, které vybere prostřední ze tří zadaných čísel (velikostně)

#include <stdio.h>

#define Mid(a,b,c) ((((b) > (a) && (a) > (c)) || ((c) > (a) && (a) > (b)))? (a) \
                 : ((((a) > (b) && (b) > (c)) || ((c) > (b) && (b) > (a)))? (b) : (c)))
// at zije zmatek v zavorkach !!!

void main()
{
    int a, b, c;

    printf("Zadej tri cisla : ");
    scanf("%d%d%d", &a, &b, &c);

    printf("Prostredni : %d!\n", Mid(a, b, c));

    getchar();
}

3) - Napište které zjistí zda znak je malé písmeno. (hodnota bude větší
     nebo rovno 'a' a menší nebo 'z')

#include <stdio.h>

#define SmallChar(chr) ((chr) >= 'a' && (chr) <= 'z')

void main()
{
    char c;

    scanf("%c", &c);

    if(SmallChar(c))
        printf("Male\n");
    else
        printf("Inaci (velke nebo cislo nebo cokoli)\n");

    getchar();
}

4) - Napište makro pro třetí mocninu (x * x * x). Vyzkoušejte na :
     - na_treti(10);
     - na_treti(i + 10);
     - na_treti(i * 10);
     - na_treti(i * j - 3);
     (i a j jsou zadaná čísla)

#include <stdio.h>

#define NaTreti(x) ((x) * (x) * (x))

void main()
{
    int n;

    scanf("%d", &n);

    printf("%d ^ 3 = %d\n", n, NaTreti(n)); // nekce se mi to vsecko psat :-)

    getchar();
}

5) - Napište makro pro výpis chybové hlášky a čekání
     na stisk klávesy.

#include <stdio.h>

#define Chyba { printf("Nekde nastala chyba, sefe ! \n"); getchar(); }

void main()
{
    printf("neco dela ...\n");

    Chyba;

    printf("... neco dela\n");

    getchar();
}






                                   === Kapitola 8 ===

Tady mě nic na cvičení nenapadá. Zkuste napsat makra, zaokrouhlující
dolů, nahoru a zaokrouhlující (větší než 0.5 nahoru, jinak dolů)

#include <stdio.h>

#define Okolo(x) ((int)((x) + 0.5))
#define Dolu(x) ((int)(x))
#define Nahoru(x) (((int)(x) - (x) == 0)? (int)(x) : (int)(x) + 1)

void main()
{
    double f;

    for(f = 0; f <= 2; f += 0.1)
        printf("%f, %d, %d, %d\n", f, Dolu(f), Okolo(f), Nahoru(f));

    getchar();
}






                                   === Kapitola 9 ===

1) - Napište funkci, která rekurzivně spočítá mocninu reálného čísla

double Mocnina(double cislo, int kolik)
{
    if(!kolik)
        return 1;

    return (cislo * Mocnina(cislo, kolik - 1));
}
// jednoduche, ze ?

2) - Napište funkci Max_Tri, která vrátí největší ze tří čísel

int Max_Tri(int a, int b, int c)
{
    if(a > b) {
        if(a > c)
            return a;
        else
            return c;
    } else {
        if(c > b)
            return c;
        else
            return b;
    }

    return a;
    // nektere kompilatory muzou rvat, ze
    // ne vsechny moznosti maji navratovou hodnotu
    // (tak blbej je myslim jen borland)
}

3) - Napište funkci, zjišťující zda je parametr prvočíslo a podle toho vrátí 1 nebo 0

int Prvocislo(int n_cislo)
{
    int i;

    for(i = 2; i < n_cislo; i ++)
        if((n_cislo % i) == 0)
            return 0; // pokud je necim delitelne, vraci 0

    return 1;
}

4) - Napište funkci pro převod malých znaků na velké a naopak (v jednom)

char Zmrv_Ho(char c)
{
    if(c >= 'a' && c <= 'z')
        return (c + 'A' - 'a');

    if(c >= 'A' && c <= 'Z')
        return (c - 'A' + 'a');

    return c;
}

5) - Napište funkci, která vypočítá rovnici : x = 7a + 41b - 56c + 14
     (a, b, c jsou parametry a x je výsledek)

float Divna_Rov(float a, float b, float c)
{
    return 7 * a + 41 * b - 56 * c + 14;
    // zavorky tam byt nemusi (nemusely byt snad ani v tech predchozich)
}

6) - Napište modul pro výpočet obsahu a obvodu kružnice (v .h použijte guarda)

/* Kruh.h */

#ifndef KRUH_INCLUDED
#define KRUH_INCLUDED

#define PI (3.141592653579893238462643383279502884)

float Obsah(float f_radius);

#endif //KRUH_INCLUDED



/* Kruh.c */

#include "Kruh.h"

float Obsah(float f_radius)
{
    return f_radius * f_radius * PI;
}



/* Main.c */

#include <stdio.h>
#include "Kruh.h"

void main()
{
    printf("Kruh o polomeru %f ma obsah %f.2\n", 5.71, Obsah(5.71));
    // lehke, co ?

    getchar(); // ceka na klavesu
}






                                   === Kapitola 10 ===

1) - Napište program, který čte čísla a postupně je ukládá do pole. (musí
     se postupně realokovat) Potom když uživatel zadá 999 (to už v poli nebude)
     program potom prohodí pořadí čísel a pole vytiskne.

#include <stdlib.h>
#include <stdio.h>

void main()
{
    int pocet, cislo;
    int *pole;
    int i, z;
    
    pocet = 0;
    // dulezite

    while(1) {
        scanf("%d", &cislo);
        // nacte cislo

        if(cislo == 999)
            break;
        // u 999 skonci

        if(pocet ++)
            pole = (int*)realloc(pole, pocet * sizeof(int));
        else
            pole = (int*)malloc(sizeof(int));
        if(pole == NULL) {
            printf("Nedostatek pameti !\n");
            getchar();
            // pokud je tady takova hlaska po ktere program
            // hned spadne, je docela slusnost pockat az si
            // to uzivatel precte aby potom nemusel zkoumat
            // proc to vlastne spadlo (jako m$ windows :-))

            return;
        }
        // zvetsi pole

        pole[pocet - 1] = cislo;
        // zapise cislo
    }

    for(i = 0; i < pocet; i ++)
        printf("%d ", pole[i]);
    printf("\n");
    // vytiskne pole

    for(i = 0; i < pocet / 2; i ++) {
        z = pole[i];
        pole[i] = pole[pocet - 1 - i];
        pole[pocet - 1 - i] = z;
    }
    // prohodi poradi

    for(i = 0; i < pocet; i ++)
        printf("%d ", pole[i]);
    printf("\n");
    // vytiskne pole

    free((void*)pole);
    // uvolni pamet

    getchar();
}

2) - Napište program, který v poli seřadí čísla v poli (zadává se jako minule)
     vzestupně. Na to jsou metody :

Bublinková - pole se prochází od začátku až do konce a pokud
    se najde číslo které je větší než následující, prohodí se s ním.
    Tohle se opakuje dokud není pole seřazené (takhle se seřadí vzestupně)

Shake sort - jako bublinková, jenže pole se prochází tam a zpátky

Sentinell - zarážka. to je proměnná, nastavená na velikost pole.
    Pole se pokaždé projde od začátku k zarážce a najde se největší číslo.
    To se potom prohodí s posledním. Potom se zarážka sníží a celý proces
    se opakuje dokud není zarážka nula

Quick Sort - Jedna z nejrychlejších metod. Vezmou se dvě proměnné
    a jedna se nastaví na začátek a druhá na konec. Potom se určí tzv. pivot.
    To je střední hodnota pole. Normálně se to dělá tak že se vybere hodnota
    prostředního čísloa mezi proměnnými. Potom se jedna zvyšuje a druhá snižuje
    a hledají se hodnoty, které jsou na špatné straně (menší než pivot napravo
    a větší nalevo) ty se pak vzájemně prohodí. Takhle se postupuje dokud se ukazatele
    nesetkají. Potom se to samé zavolá pro obě půlky pole - je to rekurzivní metoda
    a z tohohle jste ji asi nepochopili :-) bude v řešení

#include <stdlib.h>
#include <stdio.h>

void Bubble(int *p_pole, int n_pocet)
{
    int i, z, b_change;

    do {
        b_change = 0;
        // zmena = 0

        for(i = 1; i < n_pocet; i ++) {
            if(p_pole[i - 1] > p_pole[i]) {
                b_change ++;
                // zmena !

                z = p_pole[i - 1];
                p_pole[i - 1] = p_pole[i];
                p_pole[i] = z;
            }
        }
        // zkusi zda je pole setridene / probublava ...
    } while(b_change);
}

void Shake(int *p_pole, int n_pocet)
{
    int i, z, b_change;

    do {
        b_change = 0;
        // zmena = 0

        for(i = 1; i < n_pocet; i ++) {
            if(p_pole[i - 1] > p_pole[i]) {
                b_change ++;
                // zmena !

                z = p_pole[i - 1];
                p_pole[i - 1] = p_pole[i];
                p_pole[i] = z;
            }
        }
        // zkusi zda je pole setridene / probublava tam ...

        if(!b_change)
            break;
        // testuje zmeny (pokud nejsou, pole je serazene !)

        for(i = n_pocet - 1; i > 0; i --) {
            if(p_pole[i - 1] > p_pole[i]) {
                b_change ++;
                // zmena !

                z = p_pole[i - 1];
                p_pole[i - 1] = p_pole[i];
                p_pole[i] = z;
            }
        }
        // zkusi zda je pole setridene / probublava zpatky ...
    } while(b_change);
}

void Sentinell(int *p_pole, int n_pocet)
{
    int i, z, max, sentinell;

    sentinell = n_pocet;
    // zarazka ukazuje na posledni prvek pole

    do {
        max = 0;
        for(i = 1; i < sentinell; i ++) {
            if(p_pole[i] > p_pole[max])
                max = i;
        }
        // najde maximum

        z = p_pole[max];
        p_pole[max] = p_pole[sentinell - 1];
        p_pole[sentinell - 1] = z;
        // prohodi prvky
    } while(-- sentinell);
    // nez zarazka dojde na zacatek...
}

void QSort_Rec(int bottom, int top, int *p_pole)
{
    int i, j, pivot, z;

    i = bottom;
    j = top;
    pivot = p_pole[(bottom + top) / 2];
    // urci pivot (jsou i lepsi algorytmy)

    do {
        while(p_pole[i] < pivot)
            i ++;
        while(p_pole[j] > pivot)
            j --;
        if(i <= j) {
            z = p_pole[i];
            p_pole[i] = p_pole[j];
            p_pole[j] = z;
            // prohodi prvky

            i ++;
            j --;
        }
    } while(i <= j);
    // qsortink !

    if(bottom < j)
        QSort_Rec(bottom, j, p_pole);
    if(i < top)
        QSort_Rec(i, top, p_pole);
    // rekurzuje useky pole
}

void QuickSort(int *p_pole, int n_pocet)
{
    QSort_Rec(0, n_pocet - 1, p_pole);
    // vola se trochu jinak
}

void main()
{
    int pocet, cislo;
    int *pole;
    int i;
    
    pocet = 0;
    // dulezite

    while(1) {
        scanf("%d", &cislo);
        // nacte cislo

        if(cislo == 999)
            break;
        // u 999 skonci

        if(pocet ++)
            pole = (int*)realloc(pole, pocet * sizeof(int));
        else
            pole = (int*)malloc(sizeof(int));
        if(pole == NULL) {
            printf("Nedostatek pameti !\n");
            getchar();
            // pokud je tady takova hlaska po ktere program
            // hned spadne, je docela slusnost pockat az si
            // to uzivatel precte aby potom nemusel zkoumat
            // proc to vlastne spadlo (jako m$ windows :-))

            return;
        }
        // zvetsi pole

        pole[pocet - 1] = cislo;
        // zapise cislo
    }

    for(i = 0; i < pocet; i ++)
        printf("%d ", pole[i]);
    printf("\n");
    // vytiskne pole

    //Bubble(pole, pocet);
    //Shake(pole, pocet);
    //Sentinell(pole, pocet);
    QuickSort(pole, pocet);
    // seradi pole

    for(i = 0; i < pocet; i ++)
        printf("%d ", pole[i]);
    printf("\n");
    // vytiskne pole

    free((void*)pole);
    // uvolni pamet

    getchar();
}

3) - Napište program, který vytiskne počet a hodnotu parametrů se kterými
     je volán. Zkuste různé kombinace... (z příkazové řádky)

#include <stdio.h>

void main(int argc, char **argv)
{
    int i;

    printf("%d parametru !\n", argc);
    for(i = 0; i < argc; i ++)
        printf("%s \n", argv[i]);

    getchar();
}

4) - Napište funkci Swap(int *a, int *b), která prohodí hodnoty integerů
     a a b. (Volat se bude Swap(&a, &b);)

void Swap(int *a, int *b)
{
    int z;

    z = *a;
    *a = *b;
    *b = z;
}

pomocí odkazů by to vypadalo takhle :

void Swap(int &a, int &b)
{
    int z;

    z = a;
    a = b;
    b = z;
}

A volá se Swap(a, b);






                                   === Kapitola 11 ===

1) - Napište program, který bude mít strukturu Kocka s věkem a cenou.
     Uživatel zadá počet koček a ceny a stáří koček. Program je potom seřadí
     podle ceny a podle věku a vytiskne (napřed podle ceny a potom podle věku)

#include <stdlib.h>
#include <stdio.h>

struct Cat {
    char s_name[256]; // jméno
    int n_age;        // věk
    int n_price;      // cena
};

/*
typedef struct {
    char s_name[256];
    int n_age;
    int n_price;
} Cat;
// Non - C++ struktura (MincGW, LCC)
*/

#define CAT_SORT_BYAGE     0
#define CAT_SORT_BYPRICE   1

void Tisk(Cat *p_cat, int cat_num)
{
    int i;

    for(i = 0; i < cat_num; i ++) {
        printf("%3d - %8s, %5d let, %5d $\n", i + 1, p_cat[i].s_name,
            p_cat[i].n_age, p_cat[i].n_price);
    }
}
// tiskne kocky

void Sentinell(Cat *p_cat, int n_pocet, int sort_by)
{
    int i, max, sentinell;
    Cat z;

    sentinell = n_pocet;
    // zarazka ukazuje na posledni prvek pole

    do {
        max = 0;
        if(sort_by == CAT_SORT_BYAGE) {
            for(i = 1; i < sentinell; i ++) {
                if(p_cat[i].n_age > p_cat[max].n_age)
                    max = i;
            }
        } else {
            for(i = 1; i < sentinell; i ++) {
                if(p_cat[i].n_price > p_cat[max].n_price)
                    max = i;
            }
        }
        // najde maximum

        z = p_cat[max];
        p_cat[max] = p_cat[sentinell - 1];
        p_cat[sentinell - 1] = z;
        // prohodi prvky
    } while(-- sentinell);
    // nez zarazka dojde na zacatek...
}
// seradi kocky

void main(int argc, char **argv)
{
    int cat_num;
    Cat *p_cat;
    int i;

    printf("Zadej pocet kocek, bastarde : ");
    scanf("%d", &cat_num);
    // přečte počet koček

    if((p_cat = (Cat*)malloc(cat_num * sizeof(Cat))) == NULL) {
        printf("Nedostatek pameti RAM !\n");
        getchar();

        return;
    }
    // naalokuje paměť pro kočky

    for(i = 0; i < cat_num; i ++) {
        printf("%d. kocka - zadej jmeno, cenu a stari. \n", i + 1);
        scanf("%s%d%d", p_cat[i].s_name, &p_cat[i].n_price, &p_cat[i].n_age);
    }
    // precte kocky

    printf("\nKocky :\n");
    Tisk(p_cat, cat_num);
    // vytiskne kocky

    getchar();

    Sentinell(p_cat, cat_num, CAT_SORT_BYAGE);
    // seradi kocky dle veku

    printf("\nKocky podle stari :\n");
    Tisk(p_cat, cat_num);
    // vytiskne kocky

    getchar();

    Sentinell(p_cat, cat_num, CAT_SORT_BYPRICE);
    // seradi kocky dle ceny

    printf("\nKocky podle ceny :\n");
    Tisk(p_cat, cat_num);
    // vytiskne kocky

    free((void*)p_cat);
    // uvolni pamet

    getchar();
}

2) - Napište program pro evidenci pokojů v hotelu. Bude struktura pokoj, která
     má číslo pokoje (0 - 50) a je obsazená nebo volná. To bude výčtový typ.
     Hotel bude mít 5 pokojů a program bude umět zobrazit zabrané a volné pokoje
     a zadat / uvolnit pokoj.

#include <stdio.h>

enum Room_Status {
    Free,                 // volno
    Busy                  // obsazeno
};

struct Room {
    int n_id;             // číslo
    Room_Status r_status; // stav
};

/*
typedef enum {
    Free,                 // volno
    Busy                  // obsazeno
} Room_Status;

typedef struct {
    int n_id;             // číslo
    Room_Status r_status; // stav
} Room;

// Non - C++ struktury (MincGW, LCC)
*/

void Tisk(Room *p_room, int room_num)
{
    int i;

    for(i = 0; i < room_num; i ++) {
        printf("Pokoj cislo %2d - %s\n", p_room[i].n_id,
            (p_room[i].r_status == Free)? "volno" : "obsazeno");
    }
}
// tiskne pokoje

void Init(Room *p_room, int room_num)
{
    int i;

    for(i = 0; i < room_num; i ++) {
        p_room[i].n_id = i + 1;
        p_room[i].r_status = Free;
    }
}
// pripravi pokoje

int Set_Stat(Room *p_room, int room_num, int n_room_id, Room_Status r_stat)
{
    int i;

    for(i = 0; i < room_num; i ++) {
        if(p_room[i].n_id == n_room_id) {
            p_room[i].r_status = r_stat;

            return 1;
        }
    }

    printf("Toz, tendle pokoj tam nejni !\n");

    return 0;
}
// nastavi status pokoje

void main(int argc, char **argv)
{
    Room room[5];
    int n_choice;
    int b_done;

    Init(room, 5);
    // připraví pokoje
    
    Tisk(room, 5);
    // tiskne hotel

    b_done = 1;
    while(b_done) {
        do {
            printf("Rekni co kces ! \n[1 = tiskni pokoje,"
                   " 2 = zadej pokoj, 3 = uvolni pokoj, 4 = exit] : ");
            scanf("%d", &n_choice);
        } while(n_choice < 1 || n_choice > 4);
        // přečte co uživatel chce

        switch(n_choice) {
        case 1:
            Tisk(room, 5);
            break;
        case 2:
            printf("Rekni, kterej pokoj chces zadat : ");
            do {
                scanf("%d", &n_choice);
            } while(!Set_Stat(room, 5, n_choice, Busy));
            break;
        case 3:
            printf("Rekni, kterej pokoj chces uvolnit : ");
            do {
                scanf("%d", &n_choice);
            } while(!Set_Stat(room, 5, n_choice, Free));
            break;
        case 4:
            b_done = 0;
            break;
        
        
        }    
    }

    getchar();
}

3) - Napište program, který bude mít výčtový typ eLumps (na začátku) a vytiskne
     jména a názvy položek typu. Zkuste použít pole pro názvy.

#include <stdio.h>

enum eLumps
{
    kEntities = 0,
    kTextures,
    kPlanes,
    kNodes,
    kLeafs,
    kLeafFaces,
    kLeafBrushes,
    kModels,
    kBrushes,
    kBrushSides,
    kVertices,
    kMeshVerts,
    kShaders,
    kFaces,
    kLightmaps,
    kLightVolumes,
    kVisData,
    kMaxLumps
};

struct {
    char name[32];
    eLumps lump_value;
} lumpname[] = {
    {"kEntities", kEntities },
    {"kTextures", kTextures },
    {"kPlanes", kPlanes },
    {"kNodes", kNodes },
    {"kLeafs", kLeafs },
    {"kLeafFaces", kLeafFaces },
    {"kLeafBrushes", kLeafBrushes },
    {"kModels", kModels },
    {"kBrushes", kBrushes },
    {"kBrushSides", kBrushSides },
    {"kVertices", kVertices },
    {"kMeshVerts", kMeshVerts },
    {"kShaders", kShaders },
    {"kFaces", kFaces },
    {"kLightmaps", kLightmaps },
    {"kLightVolumes", kLightVolumes },
    {"kVisData", kVisData },
    {"kMaxLumps", kMaxLumps} };
// tabulka jmen a souvisejících hodnot

void main(int argc, char **argv)
{
    int i;


    for(i = 0; i <= kMaxLumps; i ++)
        printf("%s = %d\n", lumpname[i].name, lumpname[i].lump_value);
    // takhle to bude fungovat i když budete měnit hodnoty / pořadí enumů

    getchar();
}

4) - Napište program, který bude mít spojový seznam, kde půjde přidávat prvky,
     ubírat prvky (obojí na určitou pozici) Po každé operaci se obsah seznamu
     znovu zobrazí (na jednu řádku)

#include <stdlib.h>
#include <stdio.h>

struct Seznam {
    struct Seznam *prev, *next;
    int id;
};

/*
typedef struct Seznam {
    struct Seznam *prev, *next;
    int id;
} _Seznam;

#define _Seznam Seznam

// Non C++ deklarace (je to trochu složitější)
*/

void Tisk(Seznam *seznam)
{
    if(seznam == NULL) {
        printf("Seznam = [<prazdny>]\n");
        return;
    }

    while(seznam->prev != NULL)
        seznam = seznam->prev;
    // najde první prvek

    printf("Seznam = [");

    while(seznam != NULL) {
        printf("%d%s", seznam->id, (seznam->next == NULL)? "]\n" : ", ");
        seznam = seznam->next;
    }
    // tiskne
}
// velice rafinovaně tiskne seznam

Seznam *Add(Seznam *seznam, int n_index, int b_pred, int n_new_id)
{
    Seznam *_sez;
    Seznam *novy;
    int i;

    if(seznam == NULL) {
        if((seznam = (Seznam*)malloc(sizeof(Seznam))) == NULL)
            return NULL;
        // naalokuje novy prvek

        seznam->id = n_new_id;
        seznam->prev = NULL;
        seznam->next = NULL;

        return seznam;
    }
    // pro pripad prazdneho seznamu

    if(n_index < 0)
        return seznam;

    while(seznam->prev != NULL)
        seznam = seznam->prev;
    // najde první prvek

    _sez = seznam;
    for(i = 0; i < n_index; i ++) {
        if((seznam = seznam->next) == NULL)
            return _sez;
    }
    // posune se na prvek kam se ma clanek pridat

    if((novy = (Seznam*)malloc(sizeof(Seznam))) == NULL)
        return seznam;
    // naalokuje novy prvek

    novy->id = n_new_id;
    // prideli novou hodnotu

    if(b_pred) {
        // prida clanek pred

        novy->prev = seznam->prev;
        if(seznam->prev != NULL)
            seznam->prev->next = novy;
        seznam->prev = novy;
        novy->next = seznam;
        // upravi pointery ...
    } else {
        // prida clanek za

        novy->next = seznam->next;
        if(seznam->next != NULL)
            seznam->next->prev = novy;
        seznam->next = novy;
        novy->prev = seznam;
        // upravi pointery ...
    }

    return seznam;
}

Seznam *Delete(Seznam *seznam, int n_index)
{
    Seznam *z;
    int i;

    if(seznam == NULL)
        return NULL;

    if(n_index < 0)
        return seznam;

    while(seznam->prev != NULL)
        seznam = seznam->prev;
    // najde první prvek

    for(i = 0; i < n_index; i ++) {
        if((seznam = seznam->next) == NULL)
            return 0;
    }
    // posune se na prvek kam se ma clanek pridat

    z = NULL;
    if(seznam->prev != NULL) {
        seznam->prev->next = seznam->next;
        z = seznam->prev;
    }
    if(seznam->next != NULL) {
        seznam->next->prev = seznam->prev;
        z = seznam->next;
    }
    // obnovi spojeni

    free((void*)seznam);
    // uvolni pamet

    return z;
}

void main(int argc, char **argv)
{
    Seznam *seznam;
    int n_choice;
    int n_place;
    int n_index;
    int b_exit;

    seznam = NULL;
    // připraví strukturu pro použití

    seznam = Add(seznam, 0, 0, 1);
    seznam = Add(seznam, 0, 1, 0);
    seznam = Add(seznam, 1, 0, 2);
    // cvicne prida par hodnot

    b_exit = 0;
    while(!b_exit) {
        Tisk(seznam);
        // tiskne seznam

        do {
            printf("\nCo po mne vlastne chcete ? \n[1 - pridej, 2 - uber, 3 - exit] :");
            scanf("%d", &n_choice);
        } while(n_choice < 1 || n_choice > 3);
        // zepta se co uzivatel chce

        switch(n_choice) {
        case 1:
            printf("Zadej novou hodnotu, poradi a 1 = pred / 0 = za :\n");
            scanf("%d%d%d", &n_choice, &n_index, &n_place);
            seznam = Add(seznam, n_index, n_place, n_choice); // 1. prvek ma index 0 !
            // prida novy prvek
            break;
        case 2:
            printf("Zadej poradi prvku k smazani : ");
            scanf("%d", &n_index);
            seznam = Delete(seznam, n_index);
            break;
        case 3:
            b_exit = 1;
            break;
        }
        // udela co se po nem chce
    }

    while((seznam = Delete(seznam, 0)) != NULL)
        ;
    // uvolni pamet ;-)

    getchar();
}






                                   === Kapitola 12 ===

1) - Dopsat cheater

2) - Napište funkci, která "odřízne" z adresy poslední zpětné lomítko
     (pokud tam je)

char *Lomcovak(char *str)
{
    if(str[strlen(str) - 1] == '\n')
        str[strlen(str) - 1] = 0;
    // pokud tam je, tak ho odstrani :-) jednoduche !

    return str;
}

3) - Napište program, kterému zadáte jména všech svých přítelkyň,
     ten je uloží do spojového seznamu a seřadí podle jména. Použijte strcmp()

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

struct Seznam {
    struct Seznam *prev, *next;
    char pritelkyne[16];
};

/*
typedef struct Seznam {
    struct Seznam *prev, *next;
    char pritelkyne[16];
} _Seznam;

#define _Seznam Seznam

// Non C++ deklarace (je to trochu složitější)
*/

void Tisk(Seznam *seznam)
{
    if(seznam == NULL) {
        printf("Seznam = [<prazdny>]\n");
        return;
    }

    while(seznam->prev != NULL)
        seznam = seznam->prev;
    // najde první prvek

    printf("Seznam = [");

    while(seznam != NULL) {
        printf("%s%s", seznam->pritelkyne, (seznam->next == NULL)? "]\n" : ", ");
        seznam = seznam->next;
    }
    // tiskne
}
// velice rafinovaně tiskne seznam

Seznam *Add(Seznam *seznam, int n_index, int b_pred, char *n_new_id)
{
    Seznam *_sez;
    Seznam *novy;
    int i;

    if(seznam == NULL) {
        if((seznam = (Seznam*)malloc(sizeof(Seznam))) == NULL)
            return NULL;
        // naalokuje novy prvek

        strcpy(seznam->pritelkyne, n_new_id);
        seznam->prev = NULL;
        seznam->next = NULL;

        return seznam;
    }
    // pro pripad prazdneho seznamu

    if(n_index < 0)
        return seznam;

    while(seznam->prev != NULL)
        seznam = seznam->prev;
    // najde první prvek

    _sez = seznam;
    for(i = 0; i < n_index; i ++) {
        if((seznam = seznam->next) == NULL)
            return _sez;
    }
    // posune se na prvek kam se ma clanek pridat

    if((novy = (Seznam*)malloc(sizeof(Seznam))) == NULL)
        return seznam;
    // naalokuje novy prvek

    strcpy(novy->pritelkyne, n_new_id);
    // prideli novou hodnotu

    if(b_pred) {
        // prida clanek pred

        novy->prev = seznam->prev;
        if(seznam->prev != NULL)
            seznam->prev->next = novy;
        seznam->prev = novy;
        novy->next = seznam;
        // upravi pointery ...
    } else {
        // prida clanek za

        novy->next = seznam->next;
        if(seznam->next != NULL)
            seznam->next->prev = novy;
        seznam->next = novy;
        novy->prev = seznam;
        // upravi pointery ...
    }

    return seznam;
}

Seznam *Delete(Seznam *seznam, int n_index)
{
    Seznam *z;
    int i;

    if(seznam == NULL)
        return NULL;

    if(n_index < 0)
        return seznam;

    while(seznam->prev != NULL)
        seznam = seznam->prev;
    // najde první prvek

    for(i = 0; i < n_index; i ++) {
        if((seznam = seznam->next) == NULL)
            return 0;
    }
    // posune se na prvek kam se ma clanek pridat

    z = NULL;
    if(seznam->prev != NULL) {
        seznam->prev->next = seznam->next;
        z = seznam->prev;
    }
    if(seznam->next != NULL) {
        seznam->next->prev = seznam->prev;
        z = seznam->next;
    }
    // obnovi spojeni

    free((void*)seznam);
    // uvolni pamet

    return z;
}

Seznam *Swap(Seznam *a, Seznam *b)
{
    a->next = b->next;
    b->next = a;
    b->prev = a->prev;
    a->prev = b;
    if(b->prev != NULL)
        b->prev->next = b;
    if(a->next != NULL)
        a->next->prev = a;

    return b;

    /*
    char c[256];

    strcpy(c, b->pritelkyne);
    strcpy(b->pritelkyne, a->pritelkyne);
    strcpy(a->pritelkyne, c);
    // neprilis dokonale, kdyz uz mame spojovy seznam

    return a;
    */
}
// prohodi dva prvky (predpoklada ze jsou vedle sebe, a je pred b)

Seznam *Sort(Seznam *seznam)
{
    Seznam *prvni;
    int b_modify;

    if(seznam == NULL)
        return NULL;

    do {
        b_modify = 0;
        // modify na nulu

        prvni = seznam;
        while(prvni->prev != NULL)
            prvni = prvni->prev;
        // najde první potvoru (pri prohazovani se muze zmeni poradi seznamu)

        while(prvni->next != NULL) {
            if(strcmp(prvni->pritelkyne, prvni->next->pritelkyne) > 0) {
                b_modify = 1;
                prvni = Swap(prvni, prvni->next);
            }
            prvni = prvni->next;
        }
        // bublinkuje
    } while(b_modify);
    // řádí s přítelkyněmi

    return seznam;
}
// pouziva bubble sort ...

void main(int argc, char **argv)
{
    char nova_pritelkyne[16]; // pozor na dlouha jmena !
    Seznam *pritelkyne;

    pritelkyne = NULL;
    // připraví strukturu pro použití

    printf("Zadavej jmena svych pritelkyn, seznam se ukonci jmenem \"-\" \n");

    while(1) {
        scanf("%s", nova_pritelkyne);
        if(strcmp(nova_pritelkyne, "-"))
            pritelkyne = Add(pritelkyne, 0, 0, nova_pritelkyne);
        else
            break;
    }
    // zadavani

    Tisk(pritelkyne);
    // tiskne seznam

    printf("\nSerazene podle abecedy :\n");

    pritelkyne = Sort(pritelkyne);
    // seradi pritelkyne

    Tisk(pritelkyne);
    // tiskne seznam

    while((pritelkyne = Delete(pritelkyne, 0)) != NULL)
        ;
    // uvolni pamet ;-)

    getchar();
}

4) - Napište funkci, která z textu "bla x:10 bla y: 15 bla z:-3 bla .." vytáhne
     hodnoty x, y a z. (výraz se bude číst z klávesnice,
     takže je potřeba ošetřit chyby)

// !!! musíte mít na paměti, že pokud napíšete do stringu mezeru,
// scanf použije jen část před mezerou (muselo by se použít while(getchar() != '\n'))

#include <string.h>
#include <stdio.h>
#include <math.h> // funkce atof()

void Parse_It(char *str)
{
    float x, y, z;
    char *p_chr;
    int n_err;

    p_chr = str;
    while(*p_chr) {
        if(*p_chr >= 'a' && *p_chr <= 'z')
            *p_chr += 'A' - 'a';
        p_chr ++;
    }
    // jen velká písmena

    printf(str);

    n_err = 0;
    // bez chyb

    if((p_chr = strstr(str, "X:")) == NULL) {
        n_err ++;
        x = 0;
    } else
        x = (float)atof(&p_chr[2]);
    // X - zkusí najít "X:" a za ním bude číslo

    if((p_chr = strstr(str, "Y:")) == NULL) {
        n_err ++;
        y = 0;
    } else
        y = (float)atof(&p_chr[2]);
    // Y

    if((p_chr = strstr(str, "Z:")) == NULL) {
        n_err ++;
        z = 0;
    } else
        z = (float)atof(&p_chr[2]);
    // Z

    printf("X = %.2f\nY = %.2f\nZ = %.2f\nZaznamenano %d chyb.\n", x, y, z, n_err);
    // vytiskne výsledek
}

void main(int argc, char **argv)
{
    char str[256];

    scanf("%s", str);
    Parse_It(str);

    getchar();
}

5) - Napište funkci, která najde v zadaném stringu znak "x" a až do konce
     text vyplní tečkami. (x tam zůstane)

#include <string.h>
#include <stdio.h>

void Do_X(char *str)
{
    int trigger;

    trigger = 0; // triger = angl. spouštěč
    while(*str) { // to samý jako str[0] != 0
        if(trigger)
            *str = '.';
        if(*str == 'x' || *str == 'X')
            trigger = 1;
        str ++;
    }
}

void main(int argc, char **argv)
{
    char str[256];

    scanf("%s", str);
    Do_X(str);
    printf("%s\n", str);

    getchar();
}






                                   === Kapitola 13 ===

1) - Napište program pro rotaci bitů (ne posun !) a vytiskněte výsledky.

#include <stdio.h>

// char má 8 bitů - nebude fungovat pro int (muselo by se změnit číslo 0x80)
unsigned char Rotate_Byte_Left(unsigned char c)
{
    if(c & 0x80) { // 80Hex = 10000000Bin
        return (c << 1) | 1;
    } else
        return (c << 1);
}

unsigned char Rotate_Byte_Right(unsigned char c)
{
    if(c & 1) { // 1Dec = 00000001Bin
        return (c >> 1) | 0x80; // 80Hex = 10000000Bin
    } else
        return (c >> 1);
}

void main(int argc, char **argv)
{
    int i;

    printf("Zadej číslo 0-255 : ");
    scanf("%d", &i);
    
    printf("%d - vpravo = %d, vevo = %d\n", i,
        (int)Rotate_Byte_Right((unsigned char)i),
        (int)Rotate_Byte_Left((unsigned char)i));
    // počítá a tiskne výsledky

    getchar();
}

2) - Napište program pro převod čísel mezi soustavama. Bude se vám hodit (i když
     kalkulačka pod win i ta na stole to umí taky :-))

// pro zjednodušení zadáváte jen číslo a program ho prožene
// všema konverzema tam a zase zpátky (nechtělo se mi psát kontroly chyb)
// taky sem to napsal tak, aby převod byl víceméně intuitivní
// a (snad snadno :-) ) pochopitelný

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

char *Dec_to_Bin(int num)
{
    char *tmp;
    int i;

    tmp = (char*)malloc(17);

    tmp[16] = 0;
    for(i = 0; i < 16; i ++)
        tmp[i] = ((num >> (15 - i)) & 1)? '1' : '0';
    // postupně čte jednotlivé bity čísla (16 bitů)

    return tmp;
}

char *Dec_to_Hex(int num)
{
    char *tmp;
    int i, n;

    tmp = (char*)malloc(5);

    tmp[4] = 0;
    for(i = 0; i < 4; i ++) {
        n = (num >> (12 - 4 * i)) & 0xf;
        // odizoluje čtveřici čísel

        if(n < 10)
            tmp[i] = '0' + n;
        else
            tmp[i] = 'A' + n - 10;
        // převede do hexa
    }

    return tmp;
}

char *Hex_to_Bin(char *num)
{
    char *tmp, c;
    int i, l;

    tmp = (char*)malloc(17);

    l = (signed)strlen(num) - 1;
    // délka čísla

    tmp[16] = 0;
    for(i = 0; i < 16; i ++) {
        if(i / 4 > l)
            tmp[i] = 0;
        else {
            c = num[l - i / 4];

            if(c >= '0' && c <= '9')
                tmp[15 - i] = (((c - '0') >> (i % 4)) & 1)? '1' : '0';
            else /*if(c >= 'A' && c <= 'F')*/
                tmp[15 - i] = (((c - 'A' + 10) >> (i % 4)) & 1)? '1' : '0';
        }
    }

    return tmp;
}

char *Bin_to_Hex(char *num)
{
    char *tmp;
    int i, l, j;

    tmp = (char*)malloc(5);

    l = (signed)strlen(num);
    // délka čísla

    tmp[4] = 0;
    for(i = 0; i < 4; i ++) {
        tmp[i] = 0;
        
        for(j = (3 - i) * 4; j < (3 - i + 1) * 4; j ++)
            tmp[i] += ((j < l)? (num[l - j - 1] == '1') : 0) << (j - (3 - i) * 4);
        // načítá čtveřici čísel (i s mocninou dvou)

        if(tmp[i] < 10)
            tmp[i] = '0' + tmp[i];
        else
            tmp[i] = 'A' + tmp[i] - 10;
        // převede do hexa
    }

    return tmp;
}

int Bin_to_Dec(char *num)
{
    int n, i, l;

    l = (signed)strlen(num);
    // délka čísla

    for(i = 0, n = 0; i < l; i ++)
        n += (num[i] == '1') << (l - i - 1);
    // převede (easy :-))

    return n;
}

int Hex_to_Dec(char *num)
{
    int n, i, l;

    l = (signed)strlen(num);
    // délka čísla

    for(i = 0, n = 0; i < l; i ++) {
        if(num[i] >= '0' && num[i] <= '9')
            n += (num[i] - '0') << ((l - i - 1) * 4);
        else /*if(num[i] >= 'A' && num[i] <= 'Z')*/
            n += (num[i] - 'A' + 10) << ((l - i - 1) * 4);
    }
    // převede na dec

    return n;
}

void main(int argc, char **argv)
{
    char *hex, *bin, *b_hex, *h_bin;
    unsigned int i, i_b, i_h;

    printf("Zadej cislo 0-65535 : ");
    scanf("%d", &i);

    hex = Dec_to_Hex(i);
    bin = Dec_to_Bin(i);
    b_hex = Bin_to_Hex(bin);
    h_bin = Hex_to_Bin(hex);
    i_b = Bin_to_Dec(bin);
    i_h = Hex_to_Dec(hex);
    // provede vsechny prevody ...
    
    printf("Hex(%d) = %s\n"
           "Bin(%d) = %s\n"
           "Hex(%s) = %s\n"
           "Bin(%s) = %s\n"
           "Dec(%s) = %d\n"
           "Dec(%s) = %d\n", i, hex, i, bin, bin,
        b_hex, hex, h_bin, bin, i_b, hex, i_h);
    // tiskne výsledky

    free((void*)hex);
    free((void*)bin);
    free((void*)b_hex);
    free((void*)h_bin);
    // uvolní paměť

    getchar();
}

3) - Napište program, vypisující mocniny reálných čísel za použití 16:16 fixed point.

// není to tak moc přesné a při velkých číslech to snadno způsobí
// přetečení (ale pro grafické algorytmy je to jako dělané :-))

#include <stdio.h>

unsigned __int64 Make_FP(float f)
{
    return (unsigned __int64)(f * 65536); // převod na 48:16 fixed point
}

float Make_Float(unsigned __int64 fp_num)
{
    return (float)((signed)(fp_num)) / 65536;
}

int Make_Int(unsigned __int64 fp_num)
{
    return (int)(fp_num >> 16);
}

// funkce na mocniny
unsigned __int64 FP_Pow(unsigned __int64 fp_num, int pow)
{
    if(pow == 1)
        return fp_num;

    return (fp_num * FP_Pow(fp_num, pow - 1)) >> 16;
}

void main(int argc, char **argv)
{
    float f;
    int i;

    printf("Zadej kladne realne cislo : ");
    scanf("%f", &f);
    printf("Zadej kladnou celou mocninu : ");
    scanf("%d", &i);
    // přečte data
    
    printf("%.2f ^ %d = %.2f (%d)\n", f, i,
        Make_Float(FP_Pow(Make_FP(f), i)),
        Make_Int(FP_Pow(Make_FP(f), i)));
    // tiskne výsledky

    getchar();
}

4) - Napište program, který zašifruje zadané slovo podle zadaného hesla pomocí
     xor. (výsledky vypište jako hexa číslice a pak jako text)

#include <string.h>
#include <stdio.h>

void main(int argc, char **argv)
{
    char pwd[256], text[256], crypted[256];
    int i;

    printf("Zadej text : ");
    scanf("%s", text);
    printf("Zadej heslo : ");
    scanf("%s", pwd);
    // přečte data
    
    for(i = 0; i < (signed)strlen(text); i ++)
        crypted[i] = text[i] ^ pwd[i % strlen(pwd)];
    // šifruje pomocí xor - ^

    for(i = 0; i < (signed)strlen(text); i ++)
        printf("0x%X, ", crypted[i]);
    // tiskne hexa

    printf("\n%s \n", crypted);
    // tiskne text

    getchar();
}






                                   === Kapitola 14 ===

1) - Zapište do souboru data v binárním a textovém módu a čtěte je v binárním
     a textovém módu (takže budou čtyři výstupy) Výsledky zobrazte jako hex čísla

#include <stdio.h>

void Read_Hex(char *filename, char *mode)
{
    char c[1];
    FILE *fr;
    long l;

    if((fr = fopen(filename, mode)) == NULL) {
        printf("Soubor nejde otevrit !\n");
        return;
    }

    fseek(fr, 0, SEEK_END);
    l = ftell(fr);
    // najde konec souboru

    fseek(fr, 0, SEEK_SET);
    // vrátí se zase na začátek souboru

    while(ftell(fr) < l) { // přečte celý soubor
        fread(c, sizeof(c), 1, fr); // dá se použít při čtení statických polí ;-)
        printf("0x%X ", ((int)c[0]) & 0xff); // aby to nevypisovalo čísla delší než bajt
    }
    // vytiskne obsah

    printf("\n\n");

    fclose(fr);
}

void Write_Random(char *filename, char *mode)
{
    char data[10] = {0x61, 0x0a, 0x62, 0x0d, 0x63, 0x0a, 0x0d, 0x64, 0x01, 0x0f};
    FILE *fw;

    if((fw = fopen(filename, mode)) == NULL) {
        printf("Soubor nejde otevrit !\n");
        return;
    }

    fwrite(data, sizeof(data), 1, fw);
    // zapíše data

    fclose(fw);
}

void main(int argc, char **argv)
{
    Write_Random("Soubor_txt.txt", "w");
    Write_Random("Soubor_bin.txt", "wb");
    // zapíše binárně a textově

    printf("Textovy cteny textove :\n");
    Read_Hex("Soubor_txt.txt", "r");
    
    printf("Textovy cteny binarne :\n");
    Read_Hex("Soubor_txt.txt", "rb");
    
    printf("Binarni cteny textove :\n");
    Read_Hex("Soubor_bin.txt", "r");
    
    printf("Binarni cteny binarne :\n");
    Read_Hex("Soubor_bin.txt", "rb");

    getchar();
}

2) - Máme strukturu :


struct Pokus {
    char a;
    short b;
    short c;
};


     Zapište ji v binárním módu do souboru, potom ji znovu binárně přečtěte a zobrazte
     výsledek jako hex čísla. Zapište ji napřed celou a potom po částech.

#include <stdio.h>

void Read_Hex(char *filename, char *mode)
{
    char c[1];
    FILE *fr;
    long l;

    if((fr = fopen(filename, mode)) == NULL) {
        printf("Soubor nejde otevrit !\n");
        return;
    }

    fseek(fr, 0, SEEK_END);
    l = ftell(fr);
    // najde konec souboru

    fseek(fr, 0, SEEK_SET);
    // vrátí se zase na začátek souboru

    while(ftell(fr) < l) { // přečte celý soubor
        fread(c, sizeof(c), 1, fr); // dá se použít při čtení statických polí ;-)
        printf("0x%X ", ((int)c[0]) & 0xff); // aby to nevypisovalo čísla delší než bajt
    }
    // vytiskne obsah

    printf("\n\n");

    fclose(fr);
}

struct Pokus {
    char a;
    short b;
    short c;
};

void main(int argc, char **argv)
{
    FILE *fw;
    Pokus p;

    p.a = 0x12;
    p.b = 0x3456;
    p.c = 0x789a;
    // zapíše binárně a textově

    fw = fopen("Cely.txt", "w");
    fwrite(&p, sizeof(p), 1, fw);
    fclose(fw);
    // zapíše celou strukturu

    fw = fopen("Casti.txt", "w");
    fwrite(&p.a, sizeof(char), 1, fw);
    fwrite(&p.b, sizeof(short), 1, fw);
    fwrite(&p.c, sizeof(short), 1, fw);
    fclose(fw);
    // zapíše celou strukturu
    
    printf("Cela :\n");
    Read_Hex("Cely.txt", "rb");

    printf("Po castech :\n");
    Read_Hex("Casti.txt", "rb");

    printf("(velikost struktury je 6, velikost casti je 5 (char = 1 + 2 * short = 4))\n");

    getchar();
}

3) - Zkuste napsat program, který bude šifrovat soubory. (pomocí xor) Porovnejte
     výsledky v textovém a binárním módu.

// funguje samozřejmě jen binární verze, protože při xorování se vyskytnou
// znaky jako 0 a podobně (bylo by potřeba napsat zaměňování těchhle znaků
// za něco jako escape sekvence v céčku - pak to půjde třeba i tisknout..)

#include <string.h>
#include <stdio.h>

void Read_Hex(char *filename, char *mode)
{
    char c[1];
    FILE *fr;
    long l;

    if((fr = fopen(filename, mode)) == NULL) {
        printf("Soubor nejde otevrit !\n");
        return;
    }

    fseek(fr, 0, SEEK_END);
    l = ftell(fr);
    // najde konec souboru

    fseek(fr, 0, SEEK_SET);
    // vrátí se zase na začátek souboru

    while(ftell(fr) < l) { // přečte celý soubor
        fread(c, sizeof(c), 1, fr); // dá se použít při čtení statických polí ;-)
        printf("0x%X ", ((int)c[0]) & 0xff); // aby to nevypisovalo čísla delší než bajt
    }
    // vytiskne obsah

    printf("\n\n");

    fclose(fr);
}

void Cipher(char *file_src, char *file_dest, char *mode, char *modeb, char *pwd)
{
    FILE *fr, *fw;
    char c[1];
    long l;
    long i;

    fw = fopen(file_dest, modeb);
    if((fr = fopen(file_src, mode)) == NULL) {
        printf("Soubor nejde otevrit !\n");
        return;
    }

    fseek(fr, 0, SEEK_END);
    l = ftell(fr);
    // najde konec souboru

    fseek(fr, 0, SEEK_SET);
    // vrátí se zase na začátek souboru

    while((i = ftell(fr)) < l) { // přečte celý soubor
        fread(c, sizeof(c), 1, fr); // dá se použít při čtení statických polí ;-)

        c[0] ^= pwd[i % (signed)strlen(pwd)]; // heslo se pořád opakuje

        fwrite(c, sizeof(c), 1, fw); // zapíše
    }
    // šifruje

    fclose(fr);
    fclose(fw);
}

void main(int argc, char **argv)
{
    FILE *fw;

    fw = fopen("Text.txt", "w");
    fprintf(fw, "Soubor na zašifrování.\nBla bla bla ...\n0123456789\n");
    fclose(fw);
    // zapíše soubor

    Cipher("Text.txt", "Bin.txt", "rb", "wb", "heslo");
    Cipher("Text.txt", "Txt.txt", "r", "w", "heslo");
    // šifruje bin a text (heslo je "heslo")

    Cipher("Bin.txt", "Bin2.txt", "rb", "wb", "heslo");
    Cipher("Txt.txt", "Txt2.txt", "r", "w", "heslo");
    // dešifruje
    
    printf("Text :\n");
    Read_Hex("Txt2.txt", "rb");

    printf("Bin :\n");
    Read_Hex("Bin2.txt", "rb");
    // vypíše výsledky

    getchar();
}