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

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

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

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

Каждый элемент этого массиваявляется указателем на начало связанного списка блоков, описывающих имена с данным хэш-кодом. Еслиэлемент массива равен NULL, это значит, что имен с соответствующим хэш-кодом нет.Блок в списке — это структура, содержащая указатели на имя, на замещающий текст и на следующий блок всписке; значение NULL в указателе на следующий блок означает конец списка.struct nlist { /* элемент таблицы */struct nlist *next; /* указатель на следующий элемент */char *name; /* определенное имя */char *defn; /* замещающий текст */};А вот как записывается определение массива указателей:#define HASHSIZE 101static struct nlist *hashtab[HASHSIZE]; /* таблица указателей */Функция хэширования, используемая в lookup и install, суммирует коды символов в строке и в качестверезультата выдает остаток от деления полученной суммы на размер массива указателей. Это не самая лучшаяфункция хэширования, но достаточно лаконичная и эффективная./* hash: получает хэш-код для строки s */unsigned hash(char *s){unsigned hashval;for (hashval = 0; *s != '\0'; s++)hashval = *s + 31 * hashval;return hashval % HASHSIZE;}Беззнаковая арифметика гарантирует, что хэш-код будет неотрицательным.Хэширование порождает стартовый индекс для массива hashtab; если соответствующая строка в таблицеесть, она может быть обнаружена только в списке блоков, на начало которого указывает элемент массиваhashtab с этим индексом.

Поиск осуществляется с помощью lookup. Если lookup находит элемент сзаданной строкой, то возвращает указатель на нее, если не находит, то возвращает NULL./* lookup: ищет s */struct nlist *lookup(char *s){struct nlist *np;for (np = hashtab[hash(s)]; np != NULL; np = np->next)if (strcmp(s, np->name) == 0)return np; /* нашли */return NULL; /* не нашли */}В for-цикле функции lookup для просмотра списка используется стандартная конструкцияfor (ptr = head; ptr != NULL; ptr = ptr->next)Функция install обращается к lookup, чтобы определить, имеется ли уже вставляемое имя. Если это так,то старое определение будет заменено новым. В противном случае будет образован новый элемент. Еслизапрос памяти для нового элемента не может быть удовлетворен, функция install выдает NULL.struct nlist *lookup(char *);char *strdup(char *);/* install: заносит имя и текст (name, defn) в таблицу */struct nlist *install(char *name, char *defn){struct nlist *np;unsigned hashval;if ((np = lookup(name)) == NULL) { /* не найден */np = (struct nlist *) malloc(sizeof(*np));if (np == NULL || (np->name = strdup(name)) == NULL)return NULL;hashval = hash(name);np->next = hashtab[hashval];hashtab[hashval] = np;} else /* уже имеется */free((void *) np->defn); /* освобождаем прежний defn */if ((np->defn = strdup(defn)) == NULL)return NULL;return np;}Упражнение 6.5.

Напишите функцию undef, удаляющую имя и определение из таблицы, организациякоторой поддерживается функциями lookup и install.Упражнение 6.6. Реализуйте простую версию #define-процессора (без аргументов), которая использовалабы программы этого параграфа и годилась бы для Си-программ. Вам могут помочь программы getch иungetch.6.7. Средство typedefЯзык Си предоставляет средство, называемое typedef, которое позволяет давать типам данных новыеимена. Например, объявлениеtypedef int Length;делает имя Length синонимом int. С этого момента тип Length можно применять в объявлениях, воператоре приведения и т. д.

точно так же, как тип int:Length len, maxlen;Length *lengths[];Аналогично объявлениеtypedef char *String;делает String синонимом char*, т. е. указателем на char, и правомерным будет, например, следующееего использование:String р, lineptr[MAXLINES], alloc(int);int strcmp(String, String);p = (String) malloc(100);Заметим, что объявляемый в typedef тип стоит на месте имени переменной в обычном объявлении, а несразу за словом typedef. С точки зрения синтаксиса слово typedef напоминает класс памяти — extern,static и т.

д. Имена типов записаны с заглавных букв для того, чтобы они выделялись.Для демонстрации более сложных примеров применения typedef воспользуемся этим средством призадании узлов деревьев, с которыми мы уже встречались в данной главе.typedef struct tnode *Treeptr;typedef struct tnode { /* узел дерева: */char *word; /* указатель на текст */int count; /* число вхождений */Treeptr left; /* левый сын */Treeptr right; /* правый сын */} Treenode;В результате создаются два новых названия типов: Treenode (структура) и Treeptr (указатель наструктуру).

Теперь программу talloc можно записать в следующем виде:Treeptr talloc(void){return (Treeptr) malloc(sizeof (Treenode));}Следует подчеркнуть, что объявление typedef не создает объявления нового типа, оно лишь сообщаетновое имя уже существующему типу. Никакого нового смысла эти новые имена не несут, они объявляютпеременные в точности с теми же свойствами, как если бы те были объявлены напрямую безпереименования типа. Фактически typedef аналогичен #define с тем лишь отличием, что приинтерпретации компилятором он может справиться с такой текстовой подстановкой, которая не может бытьобработана препроцессором. Напримерtypedef int (*PFI)(char *, char *);создает тип PFI — "указатель на функцию (двух аргументов типа char *), возвращающую int", который,например, в программе сортировки, описанной в главе 5, можно использовать в таком контексте:PFI strcmp, numcmp;Помимо просто эстетических соображений, для применения typedef существуют две важные причины.Первая — параметризация программы, связанная с проблемой переносимости.

Если с помощью typedefобъявить типы данных, которые, возможно, являются машинно-зависимыми, то при переносе программы надругую машину потребуется внести изменения только в определения typedef. Одна из распространенныхситуаций —использование typedef-имен для варьирования целыми величинами. Для каждой конкретноймашины это предполагает соответствующие установки short, int или long, которые делаются аналогичноустановкам стандартных типов, например size_t и ptrdiff_t.Вторая причина, побуждающая к применению typedef, — желание сделать более ясным текст программы.Тип, названный Treeptr (от английских слов tree — дерево и pointer — указатель), более понятен, чем тотже тип, записанный как указатель на некоторую сложную структуру.6.8.

ОбъединенияОбъединение — это переменная, которая может содержать (в разные моменты времени) объекты различныхтипов и размеров. Все требования относительно размеров и выравнивания выполняет компилятор.Объединения позволяют хранить разнородные данные в одной и той же области памяти без включения впрограмму машинно-зависимой информации. Эти средства аналогичны вариантным записям в Паскале.Примером использования объединений мог бы послужить сам компилятор, заведующий таблицей символов,если предположить, что константа может иметь тип int, float или являться указателем на символ и иметьтип char *.

Значение каждой конкретной константы должно храниться в переменной соответствующегоэтой константе типа. Работать с таблицей символов всегда удобнее, если значения занимают одинаковую пообъему память и запоминаются в одном и том же месте независимо от своего типа. Цель введения впрограмму объединения — иметь переменную, которая бы на законных основаниях хранила в себе значениянескольких типов.

Синтаксис объединений аналогичен синтаксису структур. Приведем пример объединения.union u_tag {int ival;float fval;char *sval;} u;Переменная u будет достаточно большой, чтобы в ней поместилась любая переменная из указанных трехтипов; точный ее размер зависит от реализации. Значение одного из этих трех типов может быть присвоенопеременной и и далее использовано в выражениях, если это правомерно, т. е. если тип взятого ею значениясовпадает с типом последнего присвоенного ей значения. Выполнение этого требования в каждый текущиймомент — целиком на совести программиста. В том случае, если нечто запомнено как значение одного типа,а извлекается как значение другого типа, результат зависит от реализации.Синтаксис доступа к элементам объединения следующий:имя-объединения.элементилиуказатель-на-объединение->элементт. е.

в точности такой, как в структурах. Если для хранения типа текущего значения и использовать, скажем,переменную utype, то можно написать такой фрагмент программы:if (utype == INT)printf("%d\n", u.ival);else if (utype == FLOAT)printf("%f\n", u.fval);else if (utype == STRING)printf("%s\n", u.sval);elseprintf ("неверный тип %d в utype\n", utype);Объединения могут входить в структуры и массивы, и наоборот. Запись доступа к элементу объединения,находящегося в структуре (как и структуры, находящейся в объединении), такая же, как и для вложенныхструктур.

Например, в массиве структурstruct {char *name;int flags;int utype;union {int ival;float fval;char *sval;} u;} symtab[NSYM];к ival обращаются следующим образом:symtab[i].u.ivalа к первому символу строки sval можно обратиться любым из следующих двух способов:*symtab[i].u.svalsymtab[i].u.sval[0]Фактически объединение — это структура, все элементы которой имеют нулевое смещение относительно еебазового адреса и размер которой позволяет поместиться в ней самому большому ее элементу, авыравнивание этой структуры удовлетворяет всем типам объединения.

Операции, применимые к структурам,годятся и для объединений, т. е. законны присваивание объединения и копирование его как единого целого,взятие адреса от объединения и доступ к отдельным его элементам.Инициализировать объединение можно только значением, имеющим тип его первого элемента; такимобразом, упомянутую выше переменную u можно инициализировать лишь значением типа int.В главе 8 (на примере программы, заведующей выделением памяти) мы покажем, как, применяяобъединение, можно добиться, чтобы расположение переменной было выровнено по соответствующейгранице в памяти.6.9. Битовые поляПри дефиците памяти может возникнуть необходимость запаковать несколько объектов в одно словомашины.

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

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

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

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