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();
}