Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π―Π·Ρ‹ΠΊ программирования Π‘ΠΈ. ИзданиС 3-Π΅, исправлСнноС». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 33

Автор Π‘Ρ€Π°ΠΉΠ°Π½ ΠšΠ΅Ρ€Π½ΠΈΠ³Π°Π½

find -x -n ΠΎΠ±Ρ€Π°Π·Π΅Ρ†

Π½Π°ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ всС строки, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π·Π΅Ρ†, ΠΈ, ΠΊΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΏΠ΅Ρ€Π΅Π΄ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ строкой ΡƒΠΊΠ°ΠΆΠ΅Ρ‚ Π΅Π΅ Π½ΠΎΠΌΠ΅Ρ€.

ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒ Π² любом порядкС, ΠΏΡ€ΠΈ этом Π»ΡƒΡ‡ΡˆΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΡ‚Π°Π»ΡŒΠ½Π°Ρ Ρ‡Π°ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π΅ зависСла ΠΎΡ‚ числа прСдставлСнных Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΡƒΠ΄ΠΎΠ±Π½ΠΎ, Ссли Π±Ρ‹ ΠΎΠ½ ΠΌΠΎΠ³ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚Π°ΠΊ:

find -nx ΠΎΠ±Ρ€Π°Π·Π΅Ρ†

А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ запишСм Π½Π°ΡˆΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ.

#include β€Ήstdio.hβ€Ί

#include β€Ήstring.hβ€Ί

#define MAXLINE 1000


int getline(char *line, int max);


/* find: ΠΏΠ΅Ρ‡Π°Ρ‚ΡŒ строк ΠΎΠ±Ρ€Π°Π·Ρ†Π°ΠΌΠΈ ΠΈΠ· 1-Π³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° */

main(int argc, char *argv[])

{

 char line[MAXLINE];

 long lineno = 0;

 int c, except = 0, number = 0, found = 0;


 while (--argc β€Ί 0 && (*++argv)[0] == '-')

  while (c = *++argv[0])

   switch (c) {

   case 'x':

    except = 1;

    break;

   case 'n':

    number = 1;

    break;

   default:

    printf("find: Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ %c\n", c);

    argc = 0;

    found = -1;

    break;

   }

 if (argc != 1)

  printf("Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅: find -x -n ΠΎΠ±Ρ€Π°Π·Π΅Ρ†\n");

 else

  while (getline(line, MAXLINE) β€Ί 0) {

   lineno++;

   if ((strstr(line, *argv) != NULL) != except) {

    if (number)

     printf("%ld:", lineno);

    printf("%s", line);

    found++;

   }

  }

 return found;

}

ΠŸΠ΅Ρ€Π΅Π΄ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° argc ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ΡΡ Π½Π° 1, Π° argv "пСрСмСщаСтся" Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚. ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ†ΠΈΠΊΠ»Π° ΠΏΡ€ΠΈ отсутствии ошибок argc содСрТит количСство Π΅Ρ‰Π΅ Π½Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Ρ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², a argv ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΈΠ· Π½ΠΈΡ…. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, argc Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π²Π΅Π½ 1, a *argv ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° ΠΎΠ±Ρ€Π°Π·Π΅Ρ†. Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ *++argv являСтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ Π½Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚- строку, a (*++argv)[0] - Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π²Ρ‹ΠΌ символом, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΡΠ»Π°Ρ‚ΡŒΡΡ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌ способом:

**++argv;

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ индСксирования [] ΠΈΠΌΠ΅Π΅Ρ‚ Π±ΠΎΠ»Π΅Π΅ высокий ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚, Ρ‡Π΅ΠΌ * ΠΈ ++, ΠΊΡ€ΡƒΠ³Π»Ρ‹Π΅ скобки здСсь ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹, Π±Π΅Π· Π½ΠΈΡ… Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ‚Ρ€Π°ΠΊΡ‚ΠΎΠ²Π°Π»ΠΎΡΡŒ Π±Ρ‹ Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ *++(argv[0]). ИмСнно Ρ‚Π°ΠΊΠΎΠ΅ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΌΡ‹ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ Π²ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌ Ρ†ΠΈΠΊΠ»Π΅, Π³Π΄Π΅ ΠΏΡ€ΠΎΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ символы ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. Π’ΠΎ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅ΠΌ Ρ†ΠΈΠΊΠ»Π΅ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ *++argv[0] ΠΏΡ€ΠΈΡ€Π°Ρ‰ΠΈΠ²Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ argv[0].

ΠŸΠΎΡ‚Ρ€Π΅Π±Π½ΠΎΡΡ‚ΡŒ Π² Π±ΠΎΠ»Π΅Π΅ слоТных выраТСниях для ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ Π½Π΅ Ρ‚Π°ΠΊ ΡƒΠΆ часто. Но Ссли Ρ‚Π°ΠΊΠΎΠ΅ случится, Ρ‚ΠΎ разбивая процСсс вычислСния указатСля Π½Π° Π΄Π²Π° ΠΈΠ»ΠΈ Ρ‚Ρ€ΠΈ шага, Π²Ρ‹ ΠΎΠ±Π»Π΅Π³Ρ‡ΠΈΡ‚Π΅ восприятиС этого выраТСния.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 5.10. ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ expr, ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚ΠΈΡ€ΡƒΡŽΡ‰ΡƒΡŽ ΠΎΠ±Ρ€Π°Ρ‚Π½ΡƒΡŽ ΠΏΠΎΠ»ΡŒΡΠΊΡƒΡŽ запись выраТСния, Π·Π°Π΄Π°Π²Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строкой, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΈ ΠΎΠΏΠ΅Ρ€Π°Π½Π΄ прСдставлСны ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ. НапримСр,

expr 2 3 4 + *

вычисляСтся Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ 2*(3+4).

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 5.11. Π£ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΡƒΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ entab ΠΈ detab (см. упраТнСния 1.20 ΠΈ 1.21) Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‡Π΅Ρ€Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π·Π°Π΄Π°Π²Π°Ρ‚ΡŒ список "стопов" табуляции.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 5.12. Π Π°ΡΡˆΠΈΡ€ΡŒΡ‚Π΅ возмоТности entab ΠΈ detab Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ Π²ΠΈΠ΄Π°

entab -m +n

"стопы" табуляции Π½Π°Ρ‡ΠΈΠ½Π°Π»ΠΈΡΡŒ с m-ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΠ»ΠΈΡΡŒ Ρ‡Π΅Ρ€Π΅Π· ΠΊΠ°ΠΆΠ΄Ρ‹Π΅ n ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°ΠΉΡ‚Π΅ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΉ для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ повСдСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (ΠΊΠΎΠ³Π΄Π° Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²).

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 5.13. ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ tail, ΠΏΠ΅Ρ‡Π°Ρ‚Π°ΡŽΡ‰ΡƒΡŽ n послСдних Π²Π²Π΅Π΄Π΅Π½Π½Ρ‹Ρ… строк. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ n Ρ€Π°Π²Π½ΠΎ 10, Π½ΠΎ ΠΏΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ n ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°. ΠžΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ Π²ΠΈΠ΄Π°

tail -n

ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ n послСдних строк. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° вСсти сСбя осмыслСнно ΠΏΡ€ΠΈ Π»ΡŽΠ±Ρ‹Ρ… Π²Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ любом Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ n. ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°ΠΈΠ»ΡƒΡ‡ΡˆΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ°ΠΌΡΡ‚ΡŒ; Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π½ΠΈΠ΅ строк ΠΎΡ€Π³Π°Π½ΠΈΠ·ΡƒΠΉΡ‚Π΅, ΠΊΠ°ΠΊ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ сортировки, описанной Π² ΠΏΠ°Ρ€Π°Π³Ρ€Π°Ρ„Π΅ 5.6, Π° Π½Π΅ Π½Π° основС Π΄Π²ΡƒΠΌΠ΅Ρ€Π½ΠΎΠ³ΠΎ массива с фиксированным Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ строки.

5.11 Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

Π’ Π‘ΠΈ сама функция Π½Π΅ являСтся ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, Π½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π½ΠΈΠΌ, ΠΊΠ°ΠΊ с ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ: ΠΏΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°Ρ‚ΡŒ, Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ Π² массивС, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΈΠ· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ Ρ‚. Π΄. Для ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ этих возмоТностСй Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ сортировки, которая ΡƒΠΆΠ΅ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°Π»Π°ΡΡŒ Π² настоящСй Π³Π»Π°Π²Π΅. ИзмСним Π΅Π΅ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈ Π·Π°Π΄Π°Π½ΠΈΠΈ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° -n Π²Π²ΠΎΠ΄ΠΈΠΌΡ‹Π΅ строки ΡƒΠΏΠΎΡ€ΡΠ΄ΠΎΡ‡ΠΈΠ²Π°Π»ΠΈΡΡŒ ΠΏΠΎ ΠΈΡ… числовому Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ, Π° Π½Π΅ Π² лСксикографичСском порядкС.

Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ°, ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, распадаСтся Π½Π° Ρ‚Ρ€ΠΈ части: Π½Π° сравнСниС, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰Π΅Π΅ ΡƒΠΏΠΎΡ€ΡΠ΄ΠΎΡ‡Π΅Π½Π½ΠΎΡΡ‚ΡŒ ΠΏΠ°Ρ€Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²; пСрСстановку, ΠΌΠ΅Π½ΡΡŽΡ‰ΡƒΡŽ мСстами ΠΏΠ°Ρ€Ρƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ², ΠΈ ΡΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ осущСствляСт сравнСния ΠΈ пСрСстановки Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° всС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ упорядочСны. Алгоритм сортировки Π½Π΅ зависит ΠΎΡ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ сравнСния ΠΈ пСрСстановки, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ пСрСдавая Π΅ΠΌΡƒ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ сравнСния ΠΈ пСрСстановки, Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΠΈ сортировки.

ЛСксикографичСскоС сравнСниС Π΄Π²ΡƒΡ… строк выполняСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ strcmp (ΠΌΡ‹ ΡƒΠΆΠ΅ использовали эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π² Ρ€Π°Π½Π΅Π΅ рассмотрСнной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ сортировки); Π½Π°ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ потрСбуСтся ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° numcmp, ΡΡ€Π°Π²Π½ΠΈΠ²Π°ΡŽΡ‰Π°Ρ Π΄Π²Π΅ строки ΠΊΠ°ΠΊ числовыС значСния ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰Π°Ρ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ сравнСния Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ Π²ΠΈΠ΄Π΅, Π² ΠΊΠ°ΠΊΠΎΠΌ Π΅Π³ΠΎ Π²Ρ‹Π΄Π°Π΅Ρ‚ strcmp. Π­Ρ‚ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±ΡŠΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΏΠ΅Ρ€Π΅Π΄ main, Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΎΠ΄Π½Ρƒ ΠΈΠ· Π½ΠΈΡ… пСрСдаСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ qsort. Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΡΡ€Π΅Π΄ΠΎΡ‚ΠΎΡ‡ΠΈΡ‚ΡŒΡΡ Π½Π° Π³Π»Π°Π²Π½ΠΎΠΌ, ΠΌΡ‹ упростили сСбС Π·Π°Π΄Π°Ρ‡Ρƒ, ΠΎΡ‚ΠΊΠ°Π·Π°Π²ΡˆΠΈΡΡŒ ΠΎΡ‚ Π°Π½Π°Π»ΠΈΠ·Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… ошибок ΠΏΡ€ΠΈ Π·Π°Π΄Π°Π½ΠΈΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ².

#include β€Ήstdio.hβ€Ί

#include β€Ήstring.hβ€Ί


#define MAXLINES 5000 /* максимальноС число строк */

char *lineptr[MAXLINES]; /* ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° строки тСкста */


int readlines(char *lineptr[], int nlines);

void writelines(char *lineptr[], int nlines);

void qsort(void *lineptr[], int left, int right,

int (*comp)(void *, void *));

int numcmp(char *, char *);


/* сортировка строк */

main(int argc, char *argv[])

{

 int nlines; /* количСство ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Π½Ρ‹Ρ… строк */

 int numeric = 0; /* 1, Ссли сорт. ΠΏΠΎ числ. Π·Π½Π°Ρ‡. */

 if (argc β€Ί 1 && strcmp(argv[1], "-n") == 0)

  numeric = 1;

 if ((nlines = readlines(lineptr, MAXLINES)) β€Ί= 0) {

  qsort((void **) lineptr, 0, nlines-1,

   (int (*)(void*,void*))(numeric ? numcmp : strcmp));

  writelines(lineptr, nlines);

  return 0;

 } else {

  printf("BΠ²Π΅Π΄Π΅Π½ΠΎ слишком ΠΌΠ½ΠΎΠ³ΠΎ строк\n");

  return 1;

 }

}

Π’ обращСниях ΠΊ функциям qsort, strcmp ΠΈ numcmp ΠΈΡ… ΠΈΠΌΠ΅Π½Π° Ρ‚Ρ€Π°ΠΊΡ‚ΡƒΡŽΡ‚ΡΡ ΠΊΠ°ΠΊ адрСса этих Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, поэтому ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€& ΠΏΠ΅Ρ€Π΅Π΄ Π½ΠΈΠΌΠΈ Π½Π΅ Π½ΡƒΠΆΠ΅Π½, ΠΊΠ°ΠΊ ΠΎΠ½ Π½Π΅ Π±Ρ‹Π» Π½ΡƒΠΆΠ΅Π½ ΠΈ ΠΏΠ΅Ρ€Π΅Π΄ ΠΈΠΌΠ΅Π½Π΅ΠΌ массива.

ΠœΡ‹ написали qsort Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° ΠΌΠΎΠ³Π»Π° ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ любого Ρ‚ΠΈΠΏΠ°, Π° Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ строки символов. Как Π²ΠΈΠ΄Π½ΠΎ ΠΈΠ· ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΠ°, функция qsort Π² качСствС своих Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ массив ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ, Π΄Π²Π° Ρ†Π΅Π»Ρ‹Ρ… значСния ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ с двумя Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ-указатСлями. Π’ качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²-ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π·Π°Π΄Π°Π½Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΎΠ±ΠΎΠ±Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° void *. Π›ΡŽΠ±ΠΎΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ½ΠΎ привСсти ΠΊ Ρ‚ΠΈΠΏΡƒ void * ΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π±Π΅Π· ΠΏΠΎΡ‚Π΅Ρ€ΠΈ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, поэтому ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ ΠΊ qsort, ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π² Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π² void *. Π’Π½ΡƒΡ‚Ρ€ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ сравнСния Π΅Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ Π΅ΠΉ Ρ‚ΠΈΠΏΡƒ. На самом Π΄Π΅Π»Π΅ эти прСобразования Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ влияния Π½Π° прСдставлСния Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Π½Π΅ ΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚, ΠΎΠ½ΠΈ лишь ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ Ρ‚ΠΈΠΏΠΎΠ² для компилятора.

/* qsort: сортируСт v[left]…v[right] ΠΏΠΎ Π²ΠΎΠ·Ρ€Π°ΡΡ‚Π°Π½ΠΈΡŽ */

void qsort(void *v[], int left, int right, int (*comp)(void *, void *))

{

 int i, last;

 void swap(void *v[], int, int);


 if (left β€Ί= right) /* Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ дСлаСтся, Ссли */

  return; /* Π² массивС ΠΌΠ΅Π½Π΅Π΅ Π΄Π²ΡƒΡ… элСмСнтов */

 swap(v, left, (left + right)/2);

 last = left;

 for (i = left+1; i β€Ή= right; i++)

  if ((*comp)(v[i], v[left]) β€Ή 0)

   swap(v, ++last, i);

 swap(v, left, last);

 qsort(v, left, last-1, comp);

 qsort(v, last+1, right, comp);

}

ΠŸΠΎΠ²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½Π΅ΠΉ приглядимся ΠΊ объявлСниям. Π§Π΅Ρ‚Π²Π΅Ρ€Ρ‚Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ qsort:

int (*comp)(void *, void *)

сообщаСт, Ρ‡Ρ‚ΠΎ comp - это ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая ΠΈΠΌΠ΅Π΅Ρ‚ Π΄Π²Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°- указатСля ΠΈ Π²Ρ‹Π΄Π°Π΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚ΠΈΠΏΠ° int. ИспользованиС comp Π² строкС

if ((*comp)(v[i], v[left]) β€Ή 0)

согласуСтся с объявлСниСм "comp - это ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ", ΠΈ, ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, *comp - это функция, Π°