Главная » Просмотр файлов » Керниган и Ритчи - Язык программирования Си

Керниган и Ритчи - Язык программирования Си (793773), страница 30

Файл №793773 Керниган и Ритчи - Язык программирования Си (Керниган и Ритчи - Язык программирования Си) 30 страницаКерниган и Ритчи - Язык программирования Си (793773) страница 302019-04-24СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 30)

Так, если -x служит признаком слова "кроме", которое изменяетзадание на противоположное, а -n указывает на потребность в нумерации строк, то командаfind -x -n образецнапечатает все строки, в которых не найден указанный образец, и, кроме того, перед каждой строкой укажетее номер.Необязательные аргументы разрешается располагать в любом порядке, при этом лучше, чтобы остальнаячасть программы не зависела от числа представленных аргументов.

Кроме того, пользователю было быудобно, если бы он мог комбинировать необязательные аргументы, например, так:find -nx образецА теперь запишем нашу программу.#include <stdio.h>#include <string.h>#define MAXLINE 1000int getline(char *line, int max);/* find: печать строк образцами из 1-го аргумента */main(int angc, 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: неверный параметр %с\п", с);argc = 0;found = -1;break;}if (argc != 1)printf ("Используйте: find -x -n образец\п");elsewhile (getline(line, MAXLINE) > 0) {lineno++;if ((strstr(line, *argv) != NULL) != except) {if (number)printf("%ld:", lineno);printf("%s", line);found++;}}return found;}Перед получением очередного аргумента argc уменьшается на 1, a argv "перемещается" на следующийаргумент.

После завершения цикла при отсутствии ошибок argc содержит количество еще не обработанныхаргументов, a argv указывает на первый из них. Таким образом, argc должен быть равен 1, а *аrgvуказывать на образец. Заметим, что *++аrgv является указателем на аргумент-строку, 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 = readlinesdineptr, MAXLINES)) >= 0) {qsort((void **) lineptr, 0, nlines-1,(int (*)(void*, void*))(numeric ? numcmp : strcmp));writelines(lineptr, nlines);return 0;} else {printf("Введено слишком много строк\п");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 — это функция, а(*comp)(v[i], v[left])— обращение к ней. Скобки здесь нужны, чтобы обеспечить правильную трактовку объявления; без нихобъявлениеint *comp(void *, void *) /* НЕВЕРНО */'говорило бы, что comp — это функция, возвращающая указатель на int, а это совсем не то, что требуется.Мы уже рассматривали функцию strcmp, сравнивающую две строки. Ниже приведена функция numcmp,которая сравнивает две строки, рассматривая их как числа; предварительно они переводятся в числовыезначения функцией atof .#include <stdlib.h>/* numcmp: сравнивает s1 и s2 как числа */int numcmp(char *s1, char *s2){double v1, v2;v1 = atof(s1);v2 = atof(s2);if (v1 < v2)return -1;else if (v1 > v2)return 1;elsereturn 0;}Функция swap, меняющая местами два указателя, идентична той, что мы привели ранее в этой главе заисключением того, что объявления указателей заменены на void*.void swap(void *v[], int i, int j){voidtempv[i]v[j]*temp;= v[i];= v[j];= temp;}Программу сортировки можно дополнить и множеством других возможностей; реализовать некоторые из нихпредлагается в качестве упражнений.Упражнение 5.14.

Модифицируйте программу сортировки, чтобы она реагировала на параметр -r,указывающий, что объекты нужно сортировать в обратном порядке, т. е. в порядке убывания. Обеспечьте,чтобы -r работал и вместе с -n.Упражнение 5.15. Введите в программу необязательный параметр -f, задание которого делало бынеразличимыми символы нижнего и верхнего регистров (например, а и А должны оказаться при сравненииравными).Упражнение 5.16. Предусмотрите в программе необязательный параметр -d, который заставит программупри сравнении учитывать только буквы, цифры и пробелы.

Организуйте программу таким образом, чтобы этотпараметр мог работать вместе с параметром -f.Упражнение 5.17. Реализуйте в программе возможность работы с полями: возможность сортировки по полямвнутри строк. Для каждого поля предусмотрите свой набор параметров. Предметный указатель этой книги 8упорядочивался с параметрами: -df для терминов и -n для номеров страниц.5.12. Сложные объявленияИногда Си ругают за синтаксис объявлений, особенно тех, которые содержат в себе указатели на функции.Таким синтаксис получился в результате нашей попытки сделать похожими объявления объектов и ихиспользование.

Характеристики

Тип файла
PDF-файл
Размер
2,25 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7046
Авторов
на СтудИзбе
259
Средний доход
с одного платного файла
Обучение Подробнее