RuLibrary.com

ГЛАВНАЯ | ПОИСК | ТОП | КАРТА САЙТА      

 
 


 

Керниган Ричи >> Язык C (страница 26)


\(

CHAR *SBRK();

REGISTER CHAR *CP;

REGISTER HEADER *UP;

REGISTER INT RNU;

RNU=NALLOC*((NU+NALLOC-1)/NALLOC);

CP=SBRK(RNU*SIZEOF(HEADER));

IF ((INT)CP==-1) /*NO SPACE AT ALL*/

RETURN(NULL);

UP=(HEADER *)CP;

UP->S.SIZE=RNU;

FREE((CHAR *)(UP+1));

RETURN(ALLOCP);

\)

Если больше не осталось свободного пространства, то фун- кция SBRK возвращает "-1", хотя NULL был бы лучшим выбором. Для надежности сравнения "-1" должна быть преобразована к типу INT. Снова приходится многократно использовать явные преобразования (перевод) типов, чтобы обеспечить определен- ную независимость функций от деталей представления указате- лей на различных машинах.

И последнее - сама функция FREE. Начиная с ALLOCP, она просто просматривает свободный список в поиске места для введения свободного блока. Это место находится либо между двумя существующими блоками, либо в одном из концов списка. В любом случае, если освободившийся блок примыкает к одному из соседних, смежные блоки объединяются. Следить нужно толь- ко затем, чтобы указатели указывали на то, что нужно, и что- бы размеры были установлены правильно.

FREE(AP) /*PUT BLOCKE AP IN FREE LIST*/ CHAR *AP; \(

REGISTER HEADER *P, *G;

P=(HEADER*)AP-1; /*POINT TO HEADER*/

FOR (G=ALLOCP; !(P>G && P>G->S.PTR);G=G->S.PTR) IF (G>=G->S.PTR && (P>G \!\! P<G->S.PTR))

BREAK; /*AT ONE END OR OTHER*/ IF (P+P->S.SIZE==G->S.PTR)\(/*JOIN TO UPPER NBR*/

P->S.SIZE += G->S.PTR->S.SIZE;

P->S.PTR = G->S.PTR->S.PTR; \) ELSE

P->S.PTR = G->S.PTR; IF (G+G->S.SIZE==P) \( /*JOIN TO LOWER NBR*/

G->S.SIZE+=P->S.SIZE;

G->S.PTR=P->S.PTR; \) ELSE

G->S.PTR=P; ALLOCP = G;

\)

Хотя распределение памяти по своей сути зависит от ис- пользуемой машины, приведенная выше программа показывает, как эту зависимость можно регулировать и ограничить весьма небольшой частью программы. Использование TYPEDEF и UNION позволяет справиться с выравниванием (при условии, что функ- ция SBRK обеспечивает подходящий указатель). Переводы типов организуют выполнение явного преобразования типов и даже справляются с неудачно разработанным системным интерфейсом. И хотя рассмотренные здесь подробности связаны с распределе- нием памяти, общий подход равным образом применим и к другим ситуациям.

Упражнение 8-6

Функция из стандартной библиотеки CALLOC(N,SIZE) возвра- щает указатель на "N" объектов размера SIZE, причем соответ- ствующая память инициализируется на нуль. напишите программу для CALLOC, используя функцию ALLOC либо в качестве образца, либо как функцию, к которой происходит обращение.

Упражнение 8-7

Функция ALLOC принимает затребованный размер, не прове- ряя его правдоподобности; функция FREE полагает, что тот блок, который она должна освободить, содержит правильное значение в поле размера. Усовершенствуйте эти процедуры, затратив больше усилий на проверку ошибок.

Упражнение 8-8

Напишите функцию BFREE(P,N), которая включает произволь- ный блок "P" из "N" символов в список свободных блоков, уп- равляемый функциями ALLOC и FREE. С помощью функции BFREE пользователь может в любое время добавлять в свободный спи- сок статический или внешний массив.

* 9. Приложение А: справочное руководство по языку 'C' *
9.1. Введение

Это руководство описывает язык 'с' для компьютеров DEC PDP-11, HONEYWELL 6000, IBM система/370 и INTERDATA 8/32. там, где есть расхождения, мы сосредотачиваемся на версии для PDP-11, стремясь в то же время указать детали, которые зависят от реализации. За малым исключением, эти расхождения непосредственно обусловлены основными свойствами используе- мого аппаратного оборудования; различные компиляторы обычно вполне совместимы.

10. Лексические соглашения

Имеется шесть классов лексем: идентификаторы, ключевые слова, константы, строки, операции и другие разделители. Пробелы, табуляции , новые строки и комментарии (совместно, "пустые промежутки"), как описано ниже, игнорируются, за ис- ключением тех случаев, когда они служат разделителями лек- сем. Необходим какой-то пустой промежуток для разделения идентификаторов, ключевых слов и констант, которые в против- ном случае сольются.

Если сделан разбор входного потока на лексемы вплоть до данного символа, то в качестве следующей лексемы берется са- мая длинная строка символов, которая еще может представлять собой лексему.

10.1. Комментарии

Комментарий открывается символами /* и заканчивается символами /*. Комментарии не вкладываются друг в друга.

10.2. Идентификаторы (имена)

Идентификатор - это последовательность букв и цифр; пер- вый символ должен быть буквой. Подчеркивание _ считается буквой. Буквы нижнего и верхнего регистров различаются. зна- чащими являются не более, чем первые восемь символов, хотя можно использовать и больше. На внешние идентификаторы, ко- торые используются различными ассемблерами и загрузчиками, накладыватся более жесткие ограничения:

DEC PDP-11 7 символов, 2 регистра

HONEYWELL 6000 6 символов, 1 регистр

IBM 360/370 7 символов, 1 регистр

INTERDATA 8/32 8 символов, 2 регистра

10.3. Ключевые слова

Следующие идентификаторы зарезервированы для использова- ния в качестве ключевых слов и не могут использоваться иным образом:

INT EXTERN ELSE

CHAR REGISTER FOR

FLOAT TYPEDEF DO

DOUBLE STATIC WHILE

STRUCT GOTO SWITCH

UNION RETURN CASE

LONG SIZEOF DEFAULT

SHORT BREAK ENTRY

UNSIGNED CONTINUE

*AUTO IF

Ключевое слово ENTRY в настоящее время не используется ка- ким-либо компилятором; оно зарезервировано для использования в будущем. В некоторых реализациях резервируется также слова FORTRAN и ASM

10.4. Константы

Имеется несколько видов констант, которые перечислены ниже. В пункте 10.6 резюмируются характеристики аппаратных сред- ств, которые влияют на размеры.

10.4.1. Целые константы

Целая константа, состоящая из последовательности цифр, считается восьмеричной, если она начинается с 0 (цифра нуль), и десятичной в противном случае. Цифры 8 и 9 имеют восьмеричные значения 10 и 11 соответственно. Последователь- ность цифр, которой предшествуют символы 0х (нуль, х-малень- кое) или 0х (нуль х-большое), рассматривается как шестнадца- тиричное целое. Шестнадцатиричные цифры включают буквы от а (маленькое) или а (большое) до F (маленькое) или F (большое) со значениями от 10 до 15. Десятичная константа, величина которой превышает наибольшее машинное целое со знаком, счи- тается длинной; восмеричная или шестнадцатиричная константа, которое превышает наибольшее машинное целое без знака, также считается длинной.

10.4.2. Явные длинные константы

Десятичная, восмеричная или шестнадцатиричная константа, за которой непосредственно следует L (эль-маленькое) или L (эль-большое), является длинной константой. Как обсуждается ниже, на некоторых машинах целые и длинные значения могут рассматриваться как идентичные.

10.4.3. Символьные константы

Символьная константа - это символ, заключенный в одиноч- ные кавычки, как, например, 'X'. Значением символьной конс- танты является численное значение этого символа в машинном представлении набора символов.

Некоторые неграфические символы, одиночная кавычка ' и обратная косая черта \ могут быть представлены в соответст- вии со следующей таблицей условных последовательностей:

новая строка NL/LF/ \N

горизонтальная табуляция HT \T

символ возврата на одну позицию BS \B

возврат каретки CR \R

переход на новую страницу FF \F

обратная косая черта \ \\

одиночная кавычка ' \'

комбинация битов DDD \DDD

Условная последовательность \DDD состоит из обратной ко- сой черты, за которой следуют 1,2 или 3 восмеричных цифры, которые рассмативаются как задающие значение желаемого сим- вола. Специальным случаем этой конструкции является последо- вательность \0 (за нулем не следует цифра), которая опреде- ляет символ NUL. если следующий за обратной косой чертой символ не совпадает с одним из указанных, то обратная косая черта игнорируется.

10.4.4. Плавающие константы

Плавающая константа состоит из целой части, десятичной точки, дробной части, буквы E (маленькая) или E (большая) и целой экспоненты с необязательным знаком. Как целая, так и дробная часть являются последовательностью цифр. Либо целая, либо дробная часть (но не обе) может отсутствовать; либо де- сятичная точка, либо е (маленькая) и экспонента (но не то и другое одновременно) может отсутствовать. Каждая плавающая константа считается имеющей двойную точность.

10.5. Строки

Строка - это последовательность символов, заключенная в двойные кавычки, как, наприимер,"...". Строка имеет тип "массив массивов" и класс памяти STATIC (см. Пункт 4 ниже). Строка инициализирована указанными в ней символами. Все строки, даже идентично записанные, считаются различными. Компилятор помещает в конец каждой строки нулевой байт \0, с тем чтобы просматривающая строку программа могла определить ее конец. Перед стоящим внутри строки символом двойной ка- вычки " должен быть поставлен символ обратной косой черты \; кроме того, могут использоваться те же условия последова- тельности, что и в символьных константах. И последнее, об- ратная косая черта \, за которой непосредственно следует символ новой строки, игнорируется.

10.6. Характеристики аппаратных средств

Следующая ниже таблица суммирует некоторые свойства ап- паратного оборудования, которые меняются от машины к машине. Хотя они и влияют на переносимость программ, на практике они представляют маленькую проблему, чем это может казаться за- ранее.

Таблица 1

DEC PDP-11 HONEYWELL IBM 370 INTERDATA 8/32

ASCII ASCII EBCDIC ASCII

CHAR 8 BITS 9 BITS 8 BITS 8 BITS

INT 16 36 32 32

SHORT 16 36 16 16

LONG 32 36 32 32

FLOAT 32 36 32 32

DOUBLE 64 72 64 64

RANGE -38/+38 -38/+38 -76/+76 -76/+76

11. Синтаксическая нотация

В используемой в этом руководстве синтаксической нотации синтаксические категории выделяются курсивом (прим. перев.: в настоящее время синтексические категории вместо курсивом выделяются подчеркиванием), а литерные слова и символы - жирным шрифтом. Альтернативные категории перечисляются на отдельных строчках. Необязательный символ, терминальный или нетерминальный, указывается индексом "необ", так что

\( выражение

--------- необ \)

указывает на необязательное выражение, заключенное в фигур- ных скобках. Синтаксис суммируется в пункте 18.

12. Что в имени тебе моем?

Язык "C" основывает интерпретацию идентификатора на двух признаках идентификатора: его классе памяти и его типе. Класс памяти определяет место и время хранения памяти, свя- занной с идентификатором; тип определяет смысл величин, на- ходящихся в памяти, определенной под идентификатором.

Имеются четыре класса памяти: автоматическая, статичес- кая, внешняя и регистровая. Автоматические переменные явля- ются локальными для каждого вызова блока и исчезают при вы- ходе из этого блока. Статические переменные являются локаль- ными, но сохраняют свои значения для следующего входа в блок даже после того, как управление передается за пределы блока. Внешние переменные существуют и сохраняют свои значения в течение выполнения всей программы и могут использоваться для связи между функциями, в том числе и между независимо ском- пилированными функциями. Регистровые переменные хранятся (ели это возможно) в быстрых регистрах машины; подобно авто- матическим переменным они являются локальными для каждого блока и исчезают при выходе из этого блока.

В языке "C" предусмотрено несколько основных типов объектов:

объекты, написанные как символы (CHAR), достаточно вели- ки, чтобы хранить любой член из соответствующего данной реа- лизации внутреннего набора символов, и если действительный символ из этого набора символов хранится в символьной пере- менной, то ее значение эквивалентно целому коду этого симво- ла. В символьных переменных можно хранить и другие величины, но реализация будет машинно-зависимой.

Можно использовать до трех размеров целых, описываемых как SHORT INT, INT и LONG INT. Длинные целые занимают не меньше памяти, чем короткие, но в конкретной реализации мо- жет оказаться, что либо короткие целые, либо длинные целые, либо те и другие будут эквивалентны простым целым. "Простые" целые имеют естественный размер, предусматриваемый архиитек- турой используемой машины; другие размеры вводятся для удво- летворения специальных потребностей.

Целые без знака, описываемые как UNSIGNED, подчиняются законам арифметики по модулю 2**N, где N - число битов в их представлении. (На PDP-11 длинные величины без знака не пре- дусмотрены).

Плавающие одинарной точности (FLOAT) и плавающие двойной точности (DOUBLE) в некоторых реализациях могут быть синони- мами.

Поскольку объекты упомянутых выше типов могут быть ра- зумно интерпретированы как числа, эти типы будут называться арифметическими. типы CHAR и INT всех размеров совместно бу- дут называться целочисленными. Типы FLOAT и DOUBLE совместно будут называться плавающими типами.

Кроме основных арифметических типов существует концепту- ально бесконечный класс производных типов, которые образуют- ся из основных типов следующим образом:

массивы объектов большинства типов;

функции, которые возвращают объекты заданного типа;

указатели на объекты данного типа;

структуры, содержащие последовательность объектов

различных типов;

объединения, способные содержать один из нескольких

объектов различных типов.

Вообще говоря, эти методы построения объектов могут при- меняться рекурсивно.

13. Объекты и L-значения

Объект является доступным обработке участком памяти; L-значение - это выражение, ссылающееся на объект. Очевидным примером выражения L-значения является идентификатор. Сущес- твуют операции, результатом которых являются L-значения; ес- ли, например, E - выражение указанного типа, то *E является выражением L-значения, ссылающимся на объект E. Название "L-значение" происходит от выражения присваивания E1=E2, в котором левая часть должна быть выражением L-значения. При последующем обсуждении каждой операции будет указываться, ожидает ли она операндов L-значения и выдает ли она L-значе- ние.

14. Преобразования

Название книги: Язык C
Автор: Керниган Ричи
Просмотрено 45099 раз

123456789101112131415161718192021222324252627282930313233


 
Page generation 0.003 seconds
Новость: Весёлые и смешные коты - blogosmeh.ru