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