6.2.1. Π‘ΠΎΡΡΠΈΡΠΎΠ²ΠΊΠ°: qsort()
Π‘ΠΎΡΡΠΈΡΠΎΠ²ΠΊΠ° Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ qsort():
#include <stdlib.h> /* ISO Π‘ */
void qsort(void *base, size_t nmemb, size_t size,
int (*compare)(const void*, const void*));
ΠΠ°Π·Π²Π°Π½ΠΈΠ΅ qsort() ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΠΎΡ Π°Π»Π³ΠΎΡΠΈΡΠΌΠ° ΠΌΠ°ΡΠΈΠ½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠΈΡΠΊΠ° Π₯ΠΎΠ°ΡΠ° Quicksort (C.A.R. Hoare's Quicksort algorithm), ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΡΡ Π² ΠΏΠ΅ΡΠ²ΠΎΠ½Π°ΡΠ°Π»ΡΠ½ΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Unix. (ΠΠΈΡΡΠΎ Π² ΡΡΠ°Π½Π΄Π°ΡΡΠ΅ POSIX Π½Π΅ ΡΡΠ΅Π±ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΡΠΎΠ³ΠΎ Π°Π»Π³ΠΎΡΠΈΡΠΌΠ° Π΄Π»Ρ qsort(). Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ GLIBC ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π²ΡΡΠΎΠΊΠΎ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΡ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°ΡΠΈΡ Quicksort ΠΈ Insertion Sort.)
qsort() ΡΠΎΡΡΠΈΡΡΠ΅Ρ ΠΌΠ°ΡΡΠΈΠ²Ρ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ². ΠΠ½Π° ΡΠ°Π±ΠΎΡΠ°Π΅Ρ, ΠΏΠ΅ΡΠ΅ΡΠ°ΡΠΎΠ²ΡΠ²Π°Ρ Π½Π΅ΠΏΡΠΎΠ·ΡΠ°ΡΠ½ΡΠ΅ ΡΡΠ°ΡΡΠΊΠΈ ΠΏΠ°ΠΌΡΡΠΈ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΌΠ΅ΡΡΠ° ΠΌΠ°ΡΡΠΈΠ²Π° Π² Π΄ΡΡΠ³ΠΎΠΉ ΠΈ ΠΏΠΎΠ»Π°Π³Π°ΡΡΡ Π½Π° ΡΠΎ, ΡΡΠΎ Π²Ρ, ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΡ, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΠΈΡΠ΅ ΡΡΠ½ΠΊΡΠΈΡ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅ ΡΠ°ΡΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΠΌΠ°ΡΡΠΈΠ²Π° ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π΄ΡΡΠ³ΠΎΠ³ΠΎ. ΠΡΠ³ΡΠΌΠ΅Π½ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅:
void *base
ΠΠ΄ΡΠ΅Ρ Π½Π°ΡΠ°Π»Π° ΠΌΠ°ΡΡΠΈΠ²Π°.
size_t nmemb
ΠΠ±ΡΠ΅Π΅ ΡΠΈΡΠ»ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² Π² ΠΌΠ°ΡΡΠΈΠ²Π΅.
size_t size
Π Π°Π·ΠΌΠ΅Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΠΌΠ°ΡΡΠΈΠ²Π°. ΠΡΡΡΠΈΠΉ ΡΠΏΠΎΡΠΎΠ± ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΡΠΎΠ³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ β ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ Π‘ sizeof.
int (*compare)(const void*, const void*)
ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡΡΡΡΠ°ΡΠ°ΡΡΠ΅Π΅ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΡΡΠ½ΠΊΡΠΈΠΈ. ΠΠ½ΠΎ Π³ΠΎΠ²ΠΎΡΠΈΡ, ΡΡΠΎ Β«compare ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π½Π° ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π΄Π²Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° 'const void*' ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ intΒ».
ΠΠΎΠ»ΡΡΠ°Ρ ΡΠ°ΡΡΡ ΡΠ°Π±ΠΎΡΡ Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΠΈ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ. ΠΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΈΠΌΠΈΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ strcmp(): ΠΌΠ΅Π½ΡΡΠ΅ Π½ΡΠ»Ρ, Π΅ΡΠ»ΠΈ ΠΏΠ΅ΡΠ²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Β«ΠΌΠ΅Π½ΡΡΠ΅Β» Π²ΡΠΎΡΠΎΠ³ΠΎ, Π½ΠΎΠ»Ρ, Π΅ΡΠ»ΠΈ ΠΎΠ½ΠΈ ΡΠ°Π²Π½Ρ, ΠΈ Π±ΠΎΠ»ΡΡΠ΅ Π½ΡΠ»Ρ, Π΅ΡΠ»ΠΈ ΠΏΠ΅ΡΠ²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Β«Π±ΠΎΠ»ΡΡΠ΅Β» Π²ΡΠΎΡΠΎΠ³ΠΎ. ΠΠΌΠ΅Π½Π½ΠΎ ΡΡΠ½ΠΊΡΠΈΡ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Β«Π±ΠΎΠ»ΡΡΠ΅Β» ΠΈ Β«ΠΌΠ΅Π½ΡΡΠ΅Β» Π΄Π»Ρ Π²ΡΠ΅Π³ΠΎ, ΡΡΠΎ Π²Ρ ΡΡΠ°Π²Π½ΠΈΠ²Π°Π΅ΡΠ΅. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π»Ρ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ Π΄Π²ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ double ΠΌΡ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ:
int dcomp(const void *d1p, const void *d2p) {
const double *d1, *d2;
d1 = (const double*)d1p; /* ΠΡΠΈΠ²Π΅ΡΡΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ ΠΊ Π½ΡΠΆΠ½ΠΎΠΌΡ ΡΠΈΠΏΡ */
d2 = (const double*)d2p;
if (*d1 < *d2) /* Π‘ΡΠ°Π²Π½ΠΈΡΡ ΠΈ Π²Π΅ΡΠ½ΡΡΡ Π½ΡΠΆΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ */
return -1;
else if (*d1 > *d2)
return 1;
else if (*d1 == *d2)
return 0;
else
return -1; /* NaN ΡΠΎΡΡΠΈΡΡΠ΅ΡΡΡ Π΄ΠΎ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΡΡ ΡΠΈΡΠ΅Π» */
}
ΠΡΠΎ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΠΎΠ±ΡΠΈΠΉ ΡΡΠ΅ΡΠ΅ΠΎΡΠΈΠΏ Π΄Π»Ρ ΡΡΠ½ΠΊΡΠΈΠΉ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ: ΠΏΡΠΈΠ²Π΅ΡΡΠΈ ΡΠΈΠΏ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² ΠΎΡ void* ΠΊ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΡΠΌ Π½Π° ΡΡΠ°Π²Π½ΠΈΠ²Π°Π΅ΠΌΡΠΉ ΡΠΈΠΏ, Π° Π·Π°ΡΠ΅ΠΌ Π²Π΅ΡΠ½ΡΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ.
ΠΠ»Ρ ΡΠΈΡΠ΅Π» Ρ ΠΏΠ»Π°Π²Π°ΡΡΠ΅ΠΉ ΡΠΎΡΠΊΠΎΠΉ ΠΏΡΠΎΡΡΠΎΠ΅ Π²ΡΡΠΈΡΠ°Π½ΠΈΠ΅, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ΅ 'return *d1 - *d2', Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ, ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ Π΅ΡΠ»ΠΈ ΠΎΠ΄Π½ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΎΡΠ΅Π½Ρ ΠΌΠ°Π»Π΅Π½ΡΠΊΠΎΠ΅ ΠΈΠ»ΠΈ ΠΎΠ΄Π½ΠΎ ΠΈΠ»ΠΈ ΠΎΠ±Π° Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΠ²Π»ΡΡΡΡΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠΌΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌΠΈ Β«Π½Π΅ ΡΠΈΡΠ»ΠΎΒ» ΠΈΠ»ΠΈ Β«Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΡΡΡΒ». ΠΠΎΡΡΠΎΠΌΡ Π½Π°ΠΌ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡΡΡ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Π²ΡΡΡΠ½ΡΡ, ΠΏΡΠΈΠ½ΠΈΠΌΠ°Ρ Π²ΠΎ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π΅ΡΠΈΡΠ»ΠΎΠ²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ (ΠΊΠΎΡΠΎΡΠΎΠ΅ Π΄Π°ΠΆΠ΅ Π½Π΅ ΡΠ°Π²Π½ΠΎ ΡΠ°ΠΌΠΎΠΌΡ ΡΠ΅Π±Π΅!)
6.2.1.1. ΠΡΠΈΠΌΠ΅Ρ: ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠ° ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊΠΎΠ²
ΠΠ»Ρ Π±ΠΎΠ»Π΅Π΅ ΡΠ»ΠΎΠΆΠ½ΡΡ ΡΡΡΡΠΊΡΡΡ ΡΡΠ΅Π±ΡΡΡΡΡ Π±ΠΎΠ»Π΅Π΅ ΡΠ»ΠΎΠΆΠ½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ°ΡΡΠΌΠΎΡΡΠΈΡΠ΅ ΡΠ»Π΅Π΄ΡΡΡΡΡ (Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΡΡΠΈΠ²ΠΈΠ°Π»ΡΠ½ΡΡ) struct employee:
struct employee {
char lastname[30];
char firstname[30];
long emp_id;
time_t start_date;
};
ΠΡ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ Π΄Π»Ρ ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊΠΎΠ² ΠΏΠΎ ΡΠ°ΠΌΠΈΠ»ΠΈΠΈ, ΠΈΠΌΠ΅Π½ΠΈ ΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΌΡ Π½ΠΎΠΌΠ΅ΡΡ:
int emp_name_id_compare(const void *e1p, const void *e2p) {
const struct employee *e1, *e2;
int last, first;
e1 = (const struct employee*)e1p; /* ΠΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ */
e2 = (const struct employee*)e2p;
if ((last = strcmp(e1->lastname, e2->lastname)) != 0)
/* Π‘ΡΠ°Π²Π½ΠΈΡΡ ΡΠ°ΠΌΠΈΠ»ΠΈΠΈ */
return last; /* Π€Π°ΠΌΠΈΠ»ΠΈΠΈ ΡΠ°Π·Π»ΠΈΡΠ°ΡΡΡΡ */
/* ΡΠ°ΠΌΠΈΠ»ΠΈΠΈ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡ, ΡΡΠ°Π²Π½ΠΈΡΡ ΠΈΠΌΠ΅Π½Π° */
if ((first = strcmp(e1->firstname, e2->firstname)) != 0)
/* Π‘ΡΠ°Π²Π½ΠΈΡΡ ΠΈΠΌΠ΅Π½Π° */
return first; /* ΠΠΌΠ΅Π½Π° ΡΠ°Π·Π»ΠΈΡΠ°ΡΡΡΡ */
/* ΠΈΠΌΠ΅Π½Π° ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡ, ΡΡΠ°Π²Π½ΠΈΡΡ Π½ΠΎΠΌΠ΅ΡΠ° ID */
if (e1->emp_id < e2->emp_id) /* Π‘ΡΠ°Π²Π½ΠΈΡΡ ID ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊΠ° */
return -1;
else if (e1->emp_id == e2->emp_id)
return 0;
else
return 1;
}
ΠΠΎΠ³ΠΈΠΊΠ° Π·Π΄Π΅ΡΡ ΠΏΡΠΎΡΡΠ°: ΡΠ½Π°ΡΠ°Π»Π° ΡΡΠ°Π²Π½ΠΈΠ²Π°ΡΡΡΡ ΡΠ°ΠΌΠΈΠ»ΠΈΠΈ, Π·Π°ΡΠ΅ΠΌ ΠΈΠΌΠ΅Π½Π°, Π° Π·Π°ΡΠ΅ΠΌ Π½ΠΎΠΌΠ΅ΡΠ° ID, Π΅ΡΠ»ΠΈ Π΄Π²Π° ΠΈΠΌΠ΅Π½ΠΈ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΡ Π΄Π»Ρ ΡΡΡΠΎΠΊ strcmp(), ΠΌΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ΅ ΠΎΡΡΠΈΡΠ°ΡΠ΅Π»ΡΠ½ΠΎΠ΅/Π½ΡΠ»Π΅Π²ΠΎΠ΅/ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅Π½ΠΈΡ.
ΠΡΠΈ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠΈ ID ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊΠΎΠ² Π½Π΅Π»ΡΠ·Ρ ΠΏΡΠΎΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π²ΡΡΠΈΡΠ°Π½ΠΈΠ΅: ΠΏΡΠ΅Π΄ΡΡΠ°Π²ΡΡΠ΅, ΡΡΠΎ long 64-ΡΠ°Π·ΡΡΠ΄Π½ΡΠΉ, Π° int 32-ΡΠ°Π·ΡΡΠ΄Π½ΡΠΉ, Π° Π΄Π²Π° Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ Π»ΠΈΡΡ Π² ΡΡΠ°ΡΡΠΈΡ 32 Π±ΠΈΡΠ°Ρ (ΡΠΊΠ°ΠΆΠ΅ΠΌ, ΠΌΠ»Π°Π΄ΡΠΈΠ΅ 32 Π±ΠΈΡΠ° ΡΠ°Π²Π½Ρ Π½ΡΠ»Ρ). Π ΡΠ°ΠΊΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π²ΡΡΠΈΡΠ°Π½ΠΈΠ΅ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΡΠΈΠ²Π΅Π»ΠΎ Π±Ρ ΠΊ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΡ ΡΠΈΠΏΠ° ΠΊ int Ρ ΠΎΡΠ±ΡΠ°ΡΡΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΡΠ°ΡΡΠΈΡ 32 Π±ΠΈΡΠΎΠ² ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅Π½ΠΈΠ΅ΠΌ Π½Π΅Π²Π΅ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°.
ΠΠΠΠΠ§ΠΠΠΠ. ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΌΡ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΠ»ΠΈΡΡ ΠΏΡΠΈ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠΈ ΠΈΠΌΠ΅Π½, Π² ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π²ΡΠ΅ ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊΠΈ Ρ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡΠΈΠΌΠΈ ΡΠ°ΠΌΠΈΠ»ΠΈΡΠΌΠΈ ΠΈ ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ ΠΎΠΊΠ°Π·Π°Π»ΠΈΡΡ Π±Ρ ΡΠ³ΡΡΠΏΠΏΠΈΡΠΎΠ²Π°Π½Ρ, Π½ΠΎ Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ ΠΎΡΡΠΎΡΡΠΈΡΠΎΠ²Π°Π½Ρ
ΠΡΠΎ Π²Π°ΠΆΠ½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ qsort() Π½Π΅ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ ΡΡΠ°Π±ΠΈΠ»ΡΠ½ΠΎΠΉ ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ. Π‘ΡΠ°Π±ΠΈΠ»ΡΠ½Π° ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠ°, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ, Π΅ΡΠ»ΠΈ Π΄Π²Π° ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΡΠ°Π²Π½Ρ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ ΠΊΠ»ΡΡΠ°(-Π΅ΠΉ), ΠΎΠ½ΠΈ ΡΠΎΡ ΡΠ°Π½ΡΡΡ ΡΠ²ΠΎΠΉ ΠΏΠ΅ΡΠ²ΠΎΠ½Π°ΡΠ°Π»ΡΠ½ΡΠΉ ΠΏΠΎΡΡΠ΄ΠΎΠΊ Π΄ΡΡΠ³ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π΄ΡΡΠ³Π° Π² ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌ ΠΎΡΡΠΎΡΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΌ ΠΌΠ°ΡΡΠΈΠ²Π΅. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ°ΡΡΠΌΠΎΡΡΠΈΡΠ΅ ΡΡΠ΅Ρ ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊΠΎΠ² Ρ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΡΠΌΠΈ ΡΠ°ΠΌΠΈΠ»ΠΈΡΠΌΠΈ ΠΈ ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ ΠΈ Ρ Π½ΠΎΠΌΠ΅ΡΠ°ΠΌΠΈ 17, 42 ΠΈ 81. ΠΡ ΠΏΠΎΡΡΠ΄ΠΎΠΊ Π² ΠΏΠ΅ΡΠ²ΠΎΠ½Π°ΡΠ°Π»ΡΠ½ΠΎΠΌ ΠΌΠ°ΡΡΠΈΠ²Π΅. Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π±ΡΠ» 42, 81 ΠΈ 17 (Π§ΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊ 42 Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ ΠΏΠΎ ΠΈΠ½Π΄Π΅ΠΊΡΡ Ρ ΠΌΠ΅Π½ΡΡΠΈΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ, ΡΠ΅ΠΌ ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊ 81, ΠΊΠΎΡΠΎΡΡΠΉ, Π² ΡΠ²ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ, Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ ΠΏΠΎ ΠΈΠ½Π΄Π΅ΠΊΡΡ Ρ ΠΌΠ΅Π½ΡΡΠΈΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ, ΡΠ΅ΠΌ ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊ 17). ΠΠΎΡΠ»Π΅ ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ ΠΏΠΎΡΡΠ΄ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ ΠΎΠΊΠ°Π·Π°ΡΡΡΡ 81, 42 ΠΈ 17. ΠΡΠ»ΠΈ ΠΎΡΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, ΠΏΡΠΎΡΠ΅Π΄ΡΡΠ° ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡ Π²ΡΠ΅ Π²Π°ΠΆΠ½ΡΠ΅ ΠΊΠ»ΡΡΠ΅Π²ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ (ΠΠ°ΡΠ° ΡΠ°ΠΊ ΠΈ Π΄Π΅Π»Π°Π΅Ρ.)
ΠΡΠΎΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π΄ΡΡΠ³ΡΡ ΡΡΠ½ΠΊΡΠΈΡ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡΡΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊΠΎΠ² ΠΏΠΎ ΡΡΠ°ΡΡΠΈΠ½ΡΡΠ²Ρ:
int emp_seniority_compare(const void *e1p,
const void *e2p) {
const struct employee *e1, *e2;
double diff;
/* ΠΡΠΈΠ²Π΅ΡΡΠΈ ΡΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ ΠΊ Π½ΡΠΆΠ½ΠΎΠΌΡ ΡΠΈΠΏΡ */
e1 = (const struct employee*)e1p;
e2 = (const struct employee*)e2p;
/* Π‘ΡΠ°Π²Π½ΠΈΡΡ Π²ΡΠ΅ΠΌΠ΅Π½Π° */
diff = difftime(e1->start_date, e2->start_date);
if (diff < 0)
return -1;
else if (diff > 0)
return 1;
else
return 0;
}
ΠΠ»Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎΠΉ ΠΏΠ΅ΡΠ΅Π½ΠΎΡΠΈΠΌΠΎΡΡΠΈ ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈ difftime(), ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠ°Π·Π½ΠΈΡΡ Π² ΡΠ΅ΠΊΡΠ½Π΄Π°Ρ ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²ΡΠΌΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡΠΌΠΈ time_t. ΠΠ»Ρ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ³ΠΎ ΡΠ»ΡΡΠ°Ρ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅, ΡΠ°ΠΊΠΎΠ΅, ΠΊΠ°ΠΊ
return (int)difftime(e1->start_date, e2->start_date);
Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΡΠ°Π±ΠΎΡΠ°ΡΡ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ time_t Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ Π² ΠΏΡΠΈΠ΅ΠΌΠ»Π΅ΠΌΠΎΠΌ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΠΌΡ Π²ΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈ ΠΏΠΎΠ»Π½ΡΠΉ ΡΡΠ΅Ρ ΡΡΠΎΡΠΎΠ½Π½ΠΈΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ if, ΠΏΡΠΎΡΡΠΎ ΠΈΠ· ΠΏΡΠ΅Π΄ΠΎΡΡΠΎΡΠΎΠΆΠ½ΠΎΡΡΠΈ.
ΠΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ°ΠΉΠ»Π° Π΄Π°Π½Π½ΡΡ ΡΠΎ ΡΠΏΠΈΡΠΊΠΎΠΌ ΠΏΡΡΠΈ ΠΏΡΠ΅Π·ΠΈΠ΄Π΅Π½ΡΠΎΠ² Π‘Π¨Π:
$ cat presdata.txt
/* Π€Π°ΠΌΠΈΠ»ΠΈΡ, ΠΈΠΌΡ, Π½ΠΎΠΌΠ΅Ρ ΠΏΡΠ΅Π·ΠΈΠ΄Π΅Π½ΡΠ°, ΠΈΠ½Π°ΡΠ³ΡΡΠ°ΡΠΈΡ */
Bush George 43 980013600
Clinton William 42 727552800
Bush George 41 601322400
Reagan Ronald 40 348861600
Carter James 39 222631200
Π ch06-sortemp.c ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π° ΠΏΡΠΎΡΡΠ°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΡΠΈΡΡΠ²Π°Π΅Ρ ΡΡΠΎΡ ΡΠ°ΠΉΠ» Π² ΠΌΠ°ΡΡΠΈΠ² struct employee, Π° Π·Π°ΡΠ΅ΠΌ ΡΠΎΡΡΠΈΡΡΠ΅Ρ Π΅Π³ΠΎ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π΄Π²Π΅ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ.
1 /* ch06-sortemp.c --- ΠΠ΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΠ΅Ρ qsort() Ρ Π΄Π²ΡΠΌΡ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ. */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <time.h>
6
7 struct employee {
8 char lastname[30];
9 char firstname[30];
10 long emp_id;
11 time_t start_date;
12 };
13
14 /* emp_name_id_compare --- ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ, Π·Π°ΡΠ΅ΠΌ no ID */
15
16 int emp_name_id_compare(const void *e1p, const void *e2p)
17 {
/* ...ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ ΡΠ°Π½Π΅Π΅, ΠΎΠΏΡΡΠ΅Π½ΠΎ Π΄Π»Ρ ΡΠΊΠΎΠ½ΠΎΠΌΠΈΠΈ ΠΌΠ΅ΡΡΠ°... */
39 }
40
41 /* emp_seniority_compare --- ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΡΠ°ΡΡΠΈΠ½ΡΡΠ²Ρ */
42
43 int emp_seniority_compare(const void *e1p, const void *e2p)
44 {
/* ...ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ ΡΠ°Π½Π΅Π΅, ΠΎΠΏΡΡΠ΅Π½ΠΎ Π΄Π»Ρ ΡΠΊΠΎΠ½ΠΎΠΌΠΈΠΈ ΠΌΠ΅ΡΡΠ°... */
58 }
59
60 /* main --- Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠ°ΡΠΈΡ ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ */
61
62 int main(void)
63 {
64 #define NPRES 10
65 struct employee presidents[NPRES];
66 int i, npres;
67 char buf[BUFSIZ];
68
69 /* ΠΡΠ΅Π½Ρ ΠΏΡΠΎΡΡΠΎΠΉ ΠΊΠΎΠ΄ Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡ Π΄Π°Π½Π½ΡΡ : */
70 for (npres = 0; npres < NPRES && fgets(buf, BUFSIZ, stdin) != NULL;
71 npres++) {
72 sscanf(buf, "%s %s %ld %ld\n",
73 presidents[npres].lastname,
74 presidents[npres].firstname,
75 &presidents[npres].emp_id,
76 &presidents[npres].start_date);
77 }