Zadání: Vytvořte pole struktur zaměstnanců školy pomocí struktury typedef struct {char[30] jmeno, int vek, float plat } ZAM;. Data si vezměte z webu školy, věk a výplatu si rozumně vymyslete. Toto pole zaměstnanců setřiďte podle jména, potom podle věku a potom podle výplaty a vytiskněte. Funkci ke třídění pole z minulého úkolu si upravte a můžete ji použít.

Zdroják v C pošlete standardně jako přílohu poštou na moji adresu, nezapomeňte na příponu .c

Řešení Jonáš Erlebach

zamestnanci.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>

#define ARRAY_SIZE 6

typedef struct zamestnanec{
	char jmeno[30];
	uint8_t vek;
	float plat;

} ZAM;

ZAM createZamestnanec(const char* jmeno, uint8_t vek, float plat) {
	// Vytvoří strukturu z dat
	// bez této funkce bych musel dělat proměnout pro každého zaměstnance a potom nastavit index
	ZAM z;
	strncpy(z.jmeno, jmeno, sizeof(z.jmeno) - 1);
	z.jmeno[sizeof(z.jmeno) - 1] = '\0';
	z.vek = vek;
	z.plat = plat;
	return z;
}


void printZamestnanci(ZAM* z, size_t size){
	// Vypíše pěknou tabulku zaměstnanců
	printf("+------------------------------+-----+----------+\n");
	printf("| Jmeno                        | Vek |   Plat   |\n");
	printf("+------------------------------+-----+----------+\n");
	for (size_t i = 0; i < size; i++) {
	    printf("| %-28s | %3d | %8.2f |\n",
	           z[i].jmeno,
	           z[i].vek,
	           z[i].plat);
	}
	printf("+------------------------------+-----+----------+\n");
}

int jmenoCompare(const void* a, const void* b) {
   return strcmp(((ZAM*)a)->jmeno,((ZAM*)b)->jmeno);
}

int vekCompare(const void* a, const void* b) {
   return ((ZAM*)a)->vek - ((ZAM*)b)->vek;
}

int platCompare(const void* a, const void* b) {
   return ((ZAM*)a)->plat - ((ZAM*)b)->plat;
}


int main(){
	ZAM* zamestnanci = malloc(sizeof(ZAM)*ARRAY_SIZE);
	// zamestanci jsou nemeňící se array
	// workingArray je array se kterým se bude pracovat
	ZAM* workingArray = malloc(sizeof(ZAM)*ARRAY_SIZE);

	// kontrola jestli allokace vyšla
	assert(zamestnanci != NULL && "Nepodařilo se allokovat pamět");
	assert(workingArray != NULL && "Nepodařilo se allokovat pamět");

   zamestnanci[0] = createZamestnanec("Lubomir Andrle", 54, 31000);
	zamestnanci[1] = createZamestnanec("Jiri Chraska", 56, 32000);
	zamestnanci[2] = createZamestnanec("Petr Lastovic", 26, 30000);
	zamestnanci[3] = createZamestnanec("Pavel Bedi", 29, 29000);
	zamestnanci[4] = createZamestnanec("Zdenek Gregor", 35, 31500);
	zamestnanci[5] = createZamestnanec("Jan Macek", 28, 29600);

	// kopiruji data do workingArray se kterým se bude pracovat
	memcpy(workingArray, zamestnanci, sizeof(ZAM)*ARRAY_SIZE);

	printf("Zamestnanci:\n");
	printZamestnanci(workingArray, ARRAY_SIZE);

	// seradit podle jmena
	qsort(workingArray, ARRAY_SIZE, sizeof(ZAM), jmenoCompare);
	printf("\n\nSerazeno podle jmena:\n");
	printZamestnanci(workingArray, ARRAY_SIZE);

	// seradit podle veku
	qsort(workingArray, ARRAY_SIZE, sizeof(ZAM), vekCompare);
	printf("\n\nSerazeno podle veku:\n");
	printZamestnanci(workingArray, ARRAY_SIZE);

	// seradit podle platu
	qsort(workingArray, ARRAY_SIZE, sizeof(ZAM), platCompare);
	printf("\n\nSerazeno podle platu:\n");
	printZamestnanci(workingArray, ARRAY_SIZE);

	free(zamestnanci);
	free(workingArray);

	return 0;
}

Funguje to bez chyb. Velmi pěkně napsaný program.

Jediná poznámka: Kontrolu alokace pole funkcí malloc() (řádky 57 až 64) bych prováděl okamžitě.

	// zamestanci jsou nemeňící se array
	ZAM* zamestnanci = malloc(sizeof(ZAM)*ARRAY_SIZE);
	// kontrola jestli allokace vyšla
	assert(zamestnanci != NULL && "Nepodařilo se allokovat pamět");
	// workingArray je array se kterým se bude pracovat
	ZAM* workingArray = malloc(sizeof(ZAM)*ARRAY_SIZE);
	// kontrola jestli allokace vyšla
	assert(workingArray != NULL && "Nepodařilo se allokovat pamět");
Kontrola valgrindem
jirka@vyvoj-OptiPlex-3050:~/vyuka_sspvc/pmp/domaci_ukoly_c/zamestnanci$ valgrind ./zamestnanci
==3317== Memcheck, a memory error detector
==3317== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==3317== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==3317== Command: ./zamestnanci
==3317==
Zamestnanci:
+------------------------------+-----+----------+
| Jmeno                        | Vek |   Plat   |
+------------------------------+-----+----------+
| Lubomir Andrle               |  54 | 31000.00 |
| Jiri Chraska                 |  56 | 32000.00 |
| Petr Lastovic                |  26 | 30000.00 |
| Pavel Bedi                   |  29 | 29000.00 |
| Zdenek Gregor                |  35 | 31500.00 |
| Jan Macek                    |  28 | 29600.00 |
+------------------------------+-----+----------+


Serazeno podle jmena:
+------------------------------+-----+----------+
| Jmeno                        | Vek |   Plat   |
+------------------------------+-----+----------+
| Jan Macek                    |  28 | 29600.00 |
| Jiri Chraska                 |  56 | 32000.00 |
| Lubomir Andrle               |  54 | 31000.00 |
| Pavel Bedi                   |  29 | 29000.00 |
| Petr Lastovic                |  26 | 30000.00 |
| Zdenek Gregor                |  35 | 31500.00 |
+------------------------------+-----+----------+


Serazeno podle veku:
+------------------------------+-----+----------+
| Jmeno                        | Vek |   Plat   |
+------------------------------+-----+----------+
| Petr Lastovic                |  26 | 30000.00 |
| Jan Macek                    |  28 | 29600.00 |
| Pavel Bedi                   |  29 | 29000.00 |
| Zdenek Gregor                |  35 | 31500.00 |
| Lubomir Andrle               |  54 | 31000.00 |
| Jiri Chraska                 |  56 | 32000.00 |
+------------------------------+-----+----------+


Serazeno podle platu:
+------------------------------+-----+----------+
| Jmeno                        | Vek |   Plat   |
+------------------------------+-----+----------+
| Pavel Bedi                   |  29 | 29000.00 |
| Jan Macek                    |  28 | 29600.00 |
| Petr Lastovic                |  26 | 30000.00 |
| Lubomir Andrle               |  54 | 31000.00 |
| Zdenek Gregor                |  35 | 31500.00 |
| Jiri Chraska                 |  56 | 32000.00 |
+------------------------------+-----+----------+
==3317==
==3317== HEAP SUMMARY:
==3317==     in use at exit: 0 bytes in 0 blocks
==3317==   total heap usage: 3 allocs, 3 frees, 1,456 bytes allocated
==3317==
==3317== All heap blocks were freed -- no leaks are possible
==3317==
==3317== For lists of detected and suppressed errors, rerun with: -s
==3317== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Všechno v pořádku.

Řešení David Kučera

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

// Definice struktury pro osobu
typedef struct {
    char jmeno[50];
    int vek;
    double vyplata;
} osoba;


// Porovnávací funkce podle jména
int compare_jmeno(const void *a, const void *b) {
    return strcmp(((osoba *)a)->jmeno, ((osoba *)b)->jmeno);
}

// Porovnávací funkce podle věku
int compare_vek(const void *a, const void *b) {
    return ((osoba *)a)->vek - ((osoba *)b)->vek;
}

// Porovnávací funkce podle výplaty
int compare_vyplata(const void *a, const void *b) {
    double vyplata_diff = ((osoba *)a)->vyplata - ((osoba *)b)->vyplata;
    return (vyplata_diff > 0) - (vyplata_diff < 0); // vrací 1, 0, nebo -1
}


int main(void) {
    osoba lidi[] = {
        {"Lubomír Andrle", 45, 32523},
        {"Pavel Bédi", 25, 31150},
        {"Petr Brandejs", 52, 33000},
        {"Martin Cimfl", 32, 27850},
        {"Oldřich Čermák", 37, 29950},
        {"Michal Dusílek", 47, 5},
        {"Zdeněk Gregor", 30, 32677},
        {"Zdeňka Hejzlarová", 31, 37675},
        {"Irena Hlaváčková", 36, 34356},
        {"Vrastislav Chmelík", 43, 33123},
        {"Jiří Chráska", 53, 37000},
        {"Markéta Janovcová", 49, 36000},
        {"Petr Jarkovský", 38, 31687},
        {"Marian Kubala", 67, 42500},
        {"Petr Laštovic", 23, 33472},
        {"Josef Lejp", 44, 34523},
        {"Jan Macek", 28, 36300},
        {"Jan Macek", 47, 23000},
        {"Radek Mataj", 52, 33333},
        {"Jana Melicharová", 65, 30000},
        {"Josef Rojšl", 53, 37639},
        {"Simona Ruiderová", 33, 28457},
        {"Iveta Rýdlová", 46, 32762},
        {"Aleš Sedláček", 54, 37327},
        {"Sylvie Sedláčková", 50, 36574},
        {"Václav Serbousek", 65, 32563},
        {"Václav Serbousek", 28, 32626},
        {"Ivana Šanovcová", 58, 36373},
        {"Hana Švandová", 68, 36262},
        {"Pavel Tomáš", 45, 35252},
        {"Jakub Tschöpa", 57, 36373},
        {"Petr Voborník", 35, 38526},
        {"Silvie Voborníková Radějová", 47, 37485},
        {"Miloš Zahradník", 56, 37252},
        {"Rudolf Zajac", 68, 32758},
        {"Martin Zelený", 49, 32948}
    };

    // velikost pole
    int count = sizeof(lidi) / sizeof(lidi[0]);

    // seřazení a vypsání pole podle jména
    qsort(lidi, count, sizeof(osoba), compare_jmeno);
    printf("Seřazeno podle jmen:\n");
    for (int i = 0; i < count; ++i) {
        printf("%s\n", lidi[i].jmeno);
    }
    printf("\n");

    // seřazení a vypsání podle věku
    qsort(lidi, count, sizeof(osoba), compare_vek);
    printf("Seřazeno podle věku:\n");
    for (int i = 0; i < count; ++i) {
        printf("%s, %d let\n", lidi[i].jmeno, lidi[i].vek);
    }
    printf("\n");

    // seřazení a vypsání podle výplaty
    qsort(lidi, count, sizeof(osoba), compare_vyplata);
    printf("Seřazeno podle výplaty:\n");
    for (int i = 0; i < count; ++i) {
        printf("%s, %.2f Kč\n", lidi[i].jmeno, lidi[i].vyplata);
    }



    return 0;
}

Funguje to.

Řešení David Zeman