Что означает (СИ) ?
Последнее время стал часто натыкаться в названиях книг на следующую абревиатуру (СИ)
Пример: В облаках (СИ)
Чойта ?
Комментарии 10
Самиздат, если не ошибаюсь.
Спасибо. А по-подробнее ?
lunarian, Ну т.е. произведения, не опубликованные или опубликованные самостоятельно. Типа того
Типа, я написала книгу и издала её за свои деньги.
Спасибо за понятный идоступный ответ !
Это какое-то негласное правило для авторов ?
lunarian, А вот этого не знаю, ничего не скажу.
lunarian, — А неуловимый Джо, действительно такой неуловимый?
— Нет, просто он нахрен никому не нужен.
Я надеюсь, что вопросов о том почему издательства их не издают, не последует.
Bjoern, вц Е. В. Каширская — Тимка и Тинка в 1812 году (+ наклейки) ц2 уйц
уввцв вцвыв
lunarian, Кто смог издать, тот уже не СИ =)
Много современных молодых писателей начинают (пытаются) писать и выкладывают в открытый доступ, для того что бы все могли прочитать это и оставить свои замечания для дальнейшего улучшения стиля, сюжета и исправления ошибок. К примеру так появилась трилогия «50 оттенков серого», но мы не цепляем ярлыки, что это СИ, фанфик, плагиат и т.д.
Не так давно, ради эксперимента кто-то (Лукьяненко или Акунин, или кто-то из этих) из российских писателей проводил эксперимент и выкладывал так книгу. Но мы тоже не вешаем на это произведение, что оно СИ.
СИ принято сейчас называть только произведения, которые есть в открытом электронном доступе и у них нет бумажных аналогов, нет уникального книжного идентификатора. Так к примеру переводы иностранных поп-книг тоже могут назвать СИ. И если вы читатель данного произведения и решили как-то его отметить на этом сайтике, то из-за ярой недружбы с авторами с сайта СамИздат. (ссылку приводит выше Argon_dog), то это произведение смело может быть окрещено как СИ. Но есть высока вероятность, что даже книги, которые были опубликованы в общем доступе на СИ и с последующим изданием в АТС, Эксмо и прочих крупных издательствах, не таких как Маргинал АД; тоже на этом сайте могут ознаменовать красивым ярлыком СИ =)
Что бы было понятно:
Книга: В облаках (СИ), Читатель, который добавил эту книга на этот сайт, читал её на просторах интернета, возможно на том же сайти СамИздата. Книга эта получается, что ещё не издавалась. Поэтому и Читатель или Редактор профиля писателя добавил в скобках слово СИ.
зы: Те кто смог сам издать (а это последнее время на этом сайте много интервью с молодыми авторами) как СИ не считается и как трэш тоже =)
зыы: у меня тоже было добавлено кучу книг прочитанных с простор интернета, но такой хернёй я не маюсь и не ставлю аббревиатур СИ. На мой взгляд это просто элементарное не уважение к автору и произведению.
Многие добавлялись просто еще до того, как произведения пошли в народ, ну и надо было как-то оформлять, не издания же. А потом произведения появились, а привычка осталась.
Что значит си в названии книги
![]()
Жанр: Любовно-фантастические романы, Любовные романы
Вы знали, что девушки с Земли – лучшие невесты во всех объединенных мирах? Никто не знал, и оттого еще сложнее будет это доказать. Меня зовут Виктория, и я привыкла побеждать. Меня единственную выбрали представлять Землю в отборе невест для пяти правителей.
-
[0] |
Просмотров: 1808
- 29 декабря 2021, 15:03
![]()
Жанр: Любовное фэнтези, Фэнтези
Стать личной музой гения маг-техники мечтают десятки девушек, занять место его любовницы – сотни, получить статус жены – тысячи. И лишь единицам известно, сколь незавидна женская доля подле умнейшего представителя клана кровопийц.
-
[0] |
Просмотров: 358
- 22 июля 2019, 09:00
![]()
Жанр: Историческая фантастика, Фантастика
Сознание офицера спецназа с позывным «Ермак», прошедшего Афган, две чеченских кампании, несколько других конфликтов и загранкомандировок, после смерти переносится в 1888 год. Новое тело принадлежит четырнадцатилетнему сироте – будущему казаку Амурского.
-
[1] |
Просмотров: 3113
- 1 февраля 2019, 11:40
![]()
Жанр: Любовное фэнтези, Фэнтези
Мой начальник красив, умен, обворожителен. А еще Ник Н’Ери хищник, привыкший получать то, что хочет. И сейчас ему нужна подставная невеста для родственников, в роли которой он видит лишь меня. И я бы отказалась, если бы самой не понадобилась помощь. Откуда.
-
[0] |
Просмотров: 2413
- 23 мая 2018, 17:40
![]()
Жанр: Попаданцы, Фантастика
Русско-японская война – боль и национальная трагедия России! Множество умов тревожили мысли о причинах поражения. Множество людей жаждало ее «переиграть». Но удача улыбнулась не тому, кто об этом мечтал – наш современник Алексей Орлов, мало что помнящий.
-
[0] |
Просмотров: 2269
- 13 апреля 2018, 16:07
![]()
Жанр: Юмористическое фэнтези, Фэнтези
Незабываемый отпуск блондинки – системного администратора (очень ква-ква-квалифицированного специалиста) в другом мире.
Неправильно сформулированное желание – и вуаля! Теперь я вешу 156 кг. А всего лишь хотела найти того, кто полюбит меня за богатый внутренний.
-
[0] |
Просмотров: 3127
- 2 апреля 2018, 11:20
![]()
Жанр: Боевое фэнтези, Фэнтези
Ежегодный турнир среди магических академий объявляется открытым!
Мрачный лабиринт, полный ловушек, коварные соперники, любовь и предательство – лишь малая часть того, с чем предстоит столкнуться участникам турнира в борьбе за звание лучшего. Есть ли шанс.
-
[0] |
Просмотров: 4067
- 18 ноября 2017, 14:40
![]()
Жанр: Героическая фантастика, Фантастика
Приятно, когда твои заслуги ценят на новой родине, но почивать на лаврах не удастся. Главное правило руководителя – если кто-то хорошо справляется со своей работой, ему нужно дать еще больше работы. А уж если твой непосредственный руководитель – сам император.
-
[0] |
Просмотров: 2237
- 6 сентября 2017, 02:46
![]()
Жанр: Любовное фэнтези, Фэнтези
Тяжело в бою было, но и в ученье нелегко приходится Зославе. Не так проста наука магическая, как то ей прежде мнилось. Да и дела сердечные запутались, что пряжа у дурной рукодельницы. Поди-ка разберись, сердцем выбирать, головою или политическими соображениями. А еще неведомый лиходей в Академии объявился, студентов извести пытается, то зелья отравит, то ловушку на тропе поставит. И поди-ка пойми, царевичи ему надобны или внучка берендеева, не в свои дела нос любопытный.
-
[1] |
Просмотров: 5513
- 13 июня 2017, 00:27
![]()
Жанр: Любовное фэнтези, Фэнтези
За гнилыми болотами, в самой чаще леса, там, где не поет птица, где не ходит дикий зверь, живет ведьма. Лицо ее – ямы и рытвины, бородавки да мерзкая слизь от дел ее греховных. Голос – воронье карканье, что ни слово скажет, то жаба соскочит. Тело– хвостатое.
Что значит си после названия книги
Дорогие друзья, только что наткнулась на слово РАНДОМ, пугающее и навевающее ассоциации с. ладно, пропустим. И тут же ДЖЕДАЙ, и КА с ЦА, мама дорогая! Конечно, я погуглила и всё выяснила, но может, создать такой словарь, который поможет новичкам сориентироваться в лит-эровском мире. Я тоже новичок, и первое расшифрованное сокращение- ЛЫР вызвало вопрос, есть ли здесь оттенок презрения к жанру?
ПРИСЫЛАЙТЕ расшифровки терминов и сокращений, активным помощникам- мои лайки, отзывы, награды
9. Прода, продочка- продолжение,новая часть незаконченного произведения
22. Фанфи́к — разновидность творчества поклонников коммерческих произведений искусства, использующая идеи сюжета и персонажей из оригинального произведения. Это и «продолжения», и пародии, и «альтернативные вселенные», и многие другие подобные тексты
26. Попаданка — это молодая девушка, попадающая в прошлое или в другой мир, где зачастую ей приходится столкнуться с различными проблемами
27.Попаданец — это персонаж, который в результате некоторого фантастического допущения (портал, зеркало, подозрительная комната и пр.) попадает куда-то в другое место и/или время
39. ОБВМ – «офигенно богатый внутренний мир». В саркастическом смысле, обычно по отношению ко всяким страдающим трепетным девам и дивным эльфам (утащено из блога Ольги Бойковой)
44. Простыня — тяжелый однообразный текст, не разделенный подзаголовками и списками
45. ЗБП — количество знаков без пробелов
46. Килознак, КЗ — тысяча письменных знаков
51. Си́ты (англ. Sith) (неправильный перевод — Ситхи) — вымышленные персонажи из вселенной «Звёздных войн», адепты тёмной стороны Силы. Ситы — непримиримые противники джедаев, большинство ситов сами когда-то были джедаями
Введение в Си. Послание из прошлого столетия
Предисловие
Я несколько раз в своих комментариях ссылался на книгу Эндрю Таненбаума «Operating Systems Design and Implementation» на ее первое издание и на то, как в ней представлен язык Си. И эти комментарии всегда вызывали интерес. Я решил, что пришло время опубликовать перевод этого введения в язык Си. Оно по-прежнему актуально. Хотя наверняка найдутся и те, кто не слышал о языке программировании PL/1, а может даже и об операционной системе Minix.
Это описание интересно также и с исторической точки зрения и для понимания того, как далеко ушел язык Си с момента своего рождения и IT-отрасль в целом.
Хочу сразу оговориться, что мой второй язык французский:
Но это компенсируется 46-летним программистским стажем.
Итак, приступим, наступила очередь Эндрю Таненбаума.
Введение в язык Си (стр. 350 — 362)
Язык программирования Cи был создан Деннисом Ритчи из AT&T Bell Laboratories как язык программирования высокого уровня для разработки операционной системы UNIX. В настоящее время язык широко используется в различных областях. C особенно популярен у системных программистов, потому что позволяет писать программы просто и кратко.
Основной книгой, описывающая язык Cи, является книга Брайана Кернигана и Денниса Ритчи « Язык программирования Cи» (1978). Книги по языку Си писали Bolon (1986), Gehani (1984), Hancock and Krieger (1986), Harbison и Steele (1984) и многие другие.
В этом приложении мы попытаемся дать достаточно полное введение в Cи, так что те кто знаком с языками высокого уровня, такими как Pascal, PL/1 или Modula 2, смогут понять большую часть кода MINIX, приведенного в этой книге. Особенности Cи, которые не используются в MINIX, здесь не обсуждаются. Многочисленные тонкие моменты опущены. Акцент делается на чтении программ на Си, а не на написании кода.
А.1. Основы языка Си
Программа на Cи состоит из набора процедур (часто называемых функциями, даже если они не возвращают значений). Эти процедуры содержат объявления, операторы и другие элементы, которые вместе говорят компьютеру что надо делать. На рисунке A-1 показана небольшая процедура, в которой объявляются три целочисленные переменные и присваиваются им значения. Имя процедуры — main (главная). Процедура не имеет формальных параметров, на что указывает отсутствие каких-либо идентификаторов между скобками за именем процедуры. Тело процедуры заключено в фигурные скобки ( ). Этот пример показывает, что Cи имеет переменные, и что эти переменные должны быть объявлены до использования. Cи также имеет операторы, в этом примере это операторы присваивания. Все операторы должны заканчиваться точкой с запятой (в отличие от Паскаля, который использует двоеточия между операторами, а не после них).
Комментарии начинаются с символов « / *» и заканчивается символами «* /» и могут занимать несколько строк.
Процедура содержит три константы. Константа 10 в первом присваивании
это обычная десятичная константа. Константа 015 является восьмеричной константой
(равно 13 в десятичной системе счисления). Восьмеричные константы всегда начинаются с начального нуля. Константа 0xFF является шестнадцатеричной константой (равной 255 десятичной). Шестнадцатеричный константы всегда начинаются с 0x. Все три типа используются в Cи.
А.2. Основные типы данных
Cи имеет два основных типа данных (переменных): целое и символ, объявляемые как int и char, соответственно. Нет отдельной булевой переменной. В качестве булевой переменной используется переменная int. Если эта переменная содержит 0, то это означает ложь/false, а любое другое значение означает истина/true. Cи также имеет и типы с плавающей точкой, но MINIX не использует их.
Спецификатор register также допускается как для int, так и для char, и является подсказкой для компилятору, что объявленную переменную стоит поместить в регистр, чтобы программа работала быстрее.
Некоторые объявления показаны на рис. А — 2.
Преобразование между типами разрешено. Например, оператор
разрешен, даже если i имеет тип int, а flag_pole — long. Во многих случаях
необходимо или полезно принудительно проводить преобразования между типами данных. Для принудительного преобразования достаточно поставить целевой тип в скобках перед выражением для преобразования. Например:
предписывает преобразовать целое число i в long перед передачей его в качестве параметра в процедуру p, которая ожидает именно параметр long.
При преобразовании между типами следует обратить внимание на знак.
При преобразовании символа в целое число некоторые компиляторы обрабатывают символы как знаковые, то есть от — 128 до +127, тогда как другие рассматривают их как
без знака, то есть от 0 до 255. В MINIX часто встречаются такие выражения, как
которые преобразует с (символ) в целое число, а затем выполняет логическое И
(амперсанд) с восьмеричной константой 0377. В результате получается, что старшие 8 бит
устанавливаются в ноль, фактически заставляя рассматривать c как 8-битное число без знака, в диапазоне от 0 до 255.
А.3. Составные типы и указатели
В этом разделе мы рассмотрим четыре способа построения более сложных типов данных: массивы, структуры, объединения и указатели (arrays, structures, unions, and pointers). Массив — это коллекция/множество элементов одного типа. Все массивы в Cи начинаются с элемента 0.
объявляет массив a с 10 целыми числами, которые будут хранится в элементах массива от [0] до a [9]. Второе, массивы могут быть трех и более измерений, но они не используются в MINIX.
Структура — это набор переменных, обычно разных типов. Структура в Cи похож на record в Паскале. Оператор
объявляет s как структуру, содержащую два члена, целое число i и символ c.
Чтобы присвоить члену i структуры s значение 6, нужно записать следующее выражение:
где оператор точка указывает, что элемент i принадлежит структуре s.
Объединение — это также набор членов, аналогично структуре, за исключением того, что в любой момент в объединение может находится только один из них. Объявление
означает, что вы можете иметь целое число или символ, но никак не оба. Компилятор должен выделить достаточно места для объединения, чтобы в нем мог разместиться самый большой (с точки зрения занимаемой памяти) элемент объединения. Объединения используются только в двух местах в MINIX (для определения сообщения как объединения нескольких различных структур, и для определения дискового блока как объединения блока данных, блока i-узла, блока каталога и т. д.).
Указатели используются для хранения машинных адресов в Cи. Они используются очень и очень часто. Символ звездочка (*) используется для обозначения указателя в объявлениях. Объявление
объявляет целое число i, указатель на целое число pi, массив a из 10 элементов, массив b из 10 указателей на целые числа и указатель на указатель ppi на целое число.
Точные правила синтаксиса для сложных объявлений, объединяющих массивы, указатели и другие типы несколько сложны. К счастью, MINIX использует только простые объявления.
На рисунке A-3 показано объявление массива z структур struct table, каждая из которых имеет
три члена, целое число i, указатель cp на символ и символ с.
Массивы структур распространены в MINIX. Далее, имя table можно объявить как структуру struct table, которую можно использовать в последующих объявлениях. Например,
объявляет p указателем на структуру struct table и предлагает сохранить ее
в register. Во время выполнения программы p может указывать, например, на z [4] или
на любой другой элемент в z, все 20 элементов которой являются структурами типа struct table.
Чтобы сделать p указателем на z [4], достаточно написать
где амперсанд в качестве унарного (монадического) оператора означает «взять адрес того, что за ним следует ». Скопировать в целочисленную переменную n значение члена i
структуры, на которую указывает указатель р, можно следующим образом:
Обратите внимание, что стрелка используется для доступа к члену структуры через указатель. Если мы будем использовать переменную z, то тогда мы должны использовать оператор с точкой:
Разница в том, что z [4] является структурой, и оператор точки выбирает элементы
из составных типов (структуры, массивы) напрямую. С помощью указателей мы не выбираем участника напрямую. Указатель предписывает сначала выбрать структуру и только потом выбрать члена этой структуры.
Иногда удобно дать имя составному типу. Например:
определяет unshort как unsigned short (короткое целое число без знака). Теперь unshort может быть использован в программе как основной тип. Например,
объявляет короткое целое число без знака, указатель на короткое целое число без знака и
массив коротких целых без знака.
А.4. Операторы
Процедуры в Cи содержат объявления и операторы. Мы уже видели объявления, так что теперь мы будем рассматривать операторы. Назначение условного оператора и операторов цикла по существу такие же, как и в других языках. Рисунок А – 4 показывает несколько примеров из них. Единственное, на что стоит обратить внимание, это то, что фигурные скобки используются для группировки операторов, а оператор while имеет две формы, вторая из которых похожа на оператор repeat Паскаля.
Cи также имеет оператор for, но он не похож на оператор for в любом другом языке. Оператор for имеет следующий вид:
Тоже самое можно выразить через опертор while:
В качестве примера рассмотрим следующий оператор:
Этот оператор устанавливает первые n элементов массива a равными нулю. Выполнение оператора начинается с установки i в ноль (это делается вне цикла). Затем оператор повторяется до тех пор, пока i похожи на своих аналогов в других языках. Оператор %
используется по модулю. Стоит отметить, что оператор равенства это ==, а оператор неравенства это! =. Чтобы проверить равны ли a и b, можно написать так:
Си также позволяет объединять оператор присваивания с другими операторами, поэтому
Другие операторы также могут быть объединены таким образом.
Си имеет операторы для манипулирования битами слова. Разрешены как сдвиги, так и побитовые логические операции. Операторы сдвига влево и вправо являются > соответственно. Побитовые логические операторы &, | и ^, которые являются логическим И (AND), включающим ИЛИ (OR) и исключающим ИЛИ (XOP) соответственно. Если i имеет значение 035 (восьмеричное), тогда выражение i & 06 имеет значение 04 (восьмеричное). Еще один пример, если i = 7, то
и получим 074 для j.
Другой важной группой операторов являются унарные операторы, каждый из которых принимает только один операнд. Как унарный оператор, амперсанд & получает адрес переменной.
Если p является указателем на целое число, а i является целым числом, оператор
вычисляет адрес i и сохраняет его в переменной p.
Противоположным взятию адреса является оператор, который принимает указатель в качестве входных данных и вычисляет значение, находящееся по этому адресу. Если мы только что присвоили адрес i указателю p, тогда *p имеет то же значение, что и i.
Другими словами, в качестве унарного оператора за звездочкой следует указатель (или
выражение, дающее указатель), и возвращает значение элемента, на который указывает. Если i имеет значение 6, то оператор
присвоит j число 6.
Оператор! (восклицательный знак – оператор отрицания) возвращает 0, если его операнд отличен от нуля, и 1, если его оператор равен 0.
Он в основном используется в операторах if, например
проверяет значение х. Если x равен нулю (false), то k присваивается значение 0. В действительности, оператор! отменяет условие, следующее за ним, так же, как оператор not в Паскаль.
является побитовым оператором дополнения. Каждый 0 в своем операнде
становится 1, а каждый 1 становится 0.
Оператор sizeof сообщает размер его операнда в байтах. Применительно к
массиву из 20 целых чисел a на компьютере с 2-байтовыми целыми числами, например sizeof a будет иметь значение 40.
Последняя группа операторов — это операторы увеличения и уменьшения.
означает увеличение р. На сколько увеличится p, зависит от его типа.
Целые числа или символы увеличиваются на 1, но указатели увеличиваются на
размер объекта, на который указывает Таким образом, если а является массивом структур, а р указатель на одну из этих структур, и мы пишем
чтобы заставить p указать на одну из структур в массиве, то после увеличения p
будет указывать на a[4] независимо от того, насколько велики структуры. Оператор
аналогичен оператору p++, за исключением того, что он уменьшает, а не увеличивает значение операнда.
где обе переменные являются целыми числами, исходное значение k присваивается n и
только после этого происходит увеличение k. В операторе
сначала увеличивается k, затем его новое значение сохраняется в n.
Последний оператор – это? (знак вопроса), который выбирает одну из двух альтернатив
разделеных двоеточием. Например, оператор,
сравнивает х с у. Если x меньше y, тогда i получает значение 6; в противном случае переменная i получает значение k + 1. Скобки не обязательны.
А.6. Структура программы
Программа на С состоит из одного или нескольких файлов, содержащих процедуры и объявления.
Эти файлы могут быть скомпилированы по отдельности в объектные файлы, которые затем линкуются друг с другом (с помощью компоновщика) для формирования исполняемой программы.
В отличие от Паскаля, объявления процедур не могут быть вложенными, поэтому все они записываются на «верхнем уровне» в файле программы.
Допускается объявлять переменные вне процедур, например, в начале файла перед первым объявлением процедуры. Эти переменные являются глобальными, и могут использоваться в любой процедуре во всей программе, если только ключевое слово static не предшествует объявлению. В этом случае эти переменные нельзя использовать в другом файле. Те же правила применяются к процедурам. Переменные, объявленные внутри процедуры, являются локальными для процедуры.
Процедура может обращаться к целочисленной переменной v, объявленной в другом файле (при условии, что переменная не является статической), объявляя ее у себя внешней:
Каждая глобальная переменная должна быть объявленным ровно один раз без атрибута extern, чтобы выделить память под нее.
Переменные могут быть инициализированы при объявлении:
Массивы и структуры также могут быть инициализированы. Глобальные переменные, которые не инициализированы явно, получают значение по умолчанию, равное нулю.
А.7. Препроцессор Cи
Прежде чем исходный файл будет передан компилятору Cи, он автоматически обрабатывается
программой под названием препроцессор. Именно выход препроцессора, а не
оригинальная программа, подается на вход компилятора. Препроцессор выполняет
три основных преобразования в файле перед передачей его компилятору:
1. Включение файлов.
2. Определение и замена макросов.
3. Условная компиляция.
Все директивы препроцессора начинаются со знака числа (#) в 1-ом столбце.
Когда директива вида
встречается препроцессором, он включает файл prog.h, строка за строкой, в
программу, которая будет передана компилятору. Когда директива #include написана как
определяет макрос BLOCK_SIZE и присваивает ему значение 1024. С этого момента
каждое вхождение строки из 10 символов «BLOCK_SIZE» в файле будет
заменяться 4-символьной строкой «1024» до того, как компилятор увидит файл с программой. По соглашению имена макросов пишутся в верхнем регистре. Макросы могут иметь параметры, но на практике немногие это делают.
Третья особенность препроцессора — условная компиляция. В MINIX есть несколько
мест, где код написан специально для процессора 8088, и этот код не должен включаться при компиляции для другого процессора. Эти разделы выглядят как так:
Если символ i8088 определен, то операторы между двумя директивами препроцессора #ifdef i8088 и #endif включаются в выходные данные препроцессора; в противном случае они пропускаются. Вызывая компилятор с командой
или включив в программу заявление
мы определяем символ i8088, поэтому весь зависимый код для 8088 быть включен. По мере развития MINIX он может приобрести специальный код для 68000s и других процессоров, которые будут обрабатываться также.
В качестве примера того, как работает препроцессор, рассмотрим программу рис. A-7 (a). Она включает в себя один файл prog.h, содержимое которого выглядит следующим образом:
Представьте, что компилятор был вызван командой
После того, как файл прошел через препроцессор, вывод будет таким, как показано на Рис. A-7 (b).
Именно этот вывод, а не исходный файл, дается как вход в Cи компилятор.
Обратите внимание, что препроцессор выполнил свою работу и удалил все строки, начинающиеся со знаком #. Если компилятор был бы вызван так
то была бы включена другая печать. Если бы он был вызван вот так:
А.8. Идиомы
В этом разделе мы рассмотрим несколько конструкций, которые характерны для Cи, но не распространены в других языках программирования. Для начала рассмотрим петлю:
Переменные p и q обычно являются символьными указателями, а n является счетчиком. Цикл копирует n-символьную строку из места, на которое указывает q, в место, на которое указывает р. На каждой итерации цикла счетчик уменьшается, пока он не доходит до 0, и каждый из указателей увеличивается, поэтому они последовательно указывают на ячейки памяти с более высоким номером.
Еще одна распространенная конструкция:
которая устанавливает первые N элементов а в 0. Альтернативный способ написания этого цикла выглядит так:
В этой формулировке целочисленный указатель p инициализируется так, чтобы указывать на нулевой элемент массива. Цикл продолжается до тех пор, пока p не достиг адреса N-ого элемента массива. Конструкция указателя гораздо эффективнее, чем конструкция массива, и поэтому обычно используют ее.
Операторы присвоения могут появляться в неожиданных местах. Например,
сначала вызывает функцию f, затем присваивает результат вызова функции a и
наконец, проверяет, является ли оно истинным (ненулевым) или ложным (нулевым). Если а не равно нулю, то условие выполнено. Оператор
также сначало значение переменной b переменной a, а затем проверяет a, не является ли значение ненулевым. И этот оператор полностью отличается от
который сравнивает две переменные и выполняет оператор, если они равны.
Что значит си после названия книги


Содержание
Общие сведения


СИ была принята XI Генеральной конференцией по мерам и весам, некоторые последующие конференции внесли в СИ ряд изменений.
СИ определяет семь основных и производные единицы физических величин (далее — единицы), а также набор приставок. Установлены стандартные сокращённые обозначения для единиц и правила записи производных единиц.
Основные единицы: килограмм, метр, секунда, ампер, кельвин, моль и кандела. В рамках СИ считается, что эти единицы имеют независимую размерность, то есть ни одна из основных единиц не может быть получена из других.
Производные единицы получаются из основных с помощью алгебраических действий, таких как умножение и деление. Некоторым из производных единиц в СИ присвоены собственные названия, например радиану.
Приставки можно использовать перед названиями единиц; они означают, что единицу нужно умножить или разделить на определённое целое число, степень числа 10. Например, приставка «кило» означает умножение на 1000 (километр = 1000 метров). Приставки СИ называют также десятичными приставками.
Международные и русские обозначения
В России действует ГОСТ 8.417—2002, предписывающий обязательное использование единиц СИ. В нём перечислены единицы физических величин, разрешённые к применению, приведены их международные и русские обозначения и установлены правила их использования.
По этим правилам, при договорно-правовых отношениях в области сотрудничества с зарубежными странами, а также в поставляемых за границу вместе с экспортной продукцией технических и других документах разрешается применять только международные обозначения единиц. Применение международных обозначений обязательно также на шкалах и табличках измерительных приборов. В остальных случаях, например, во внутренних документах и обычных публикациях можно использовать либо международные, либо русские обозначения. Не допускается одновременно применять международные и русские обозначения, за исключением публикаций по единицам величин.
История


СИ является развитием метрической системы мер, которая была создана французскими учёными и впервые широко внедрена после Великой Французской революции. До введения метрической системы единицы выбирались независимо друг от друга. Поэтому пересчёт из одной единицы в другую был сложным. К тому же в разных местах применялись разные единицы, иногда с одинаковыми названиями. Метрическая система должна была стать удобной и единой системой мер и весов.
В 1875 г. была подписана Метрическая конвенция. Были начаты работы по разработке международных эталонов метра и килограмма.
В последующем были введены базовые единицы для физических величин в области электричества и оптики.
В 1960 XI Генеральная конференция по мерам и весам приняла стандарт, который впервые получил название «Международная система единиц (СИ)».
В 1971 XIV Генеральная конференция по мерам и весам внесла изменения в СИ, добавив, в частности, единицу количества вещества (моль).
Единицы СИ
Названия единиц СИ пишутся со строчной буквы, после обозначений единиц СИ точка не ставится, в отличие от обычных сокращений.
Основные единицы
| Величина | Единица измерения | Обозначение | ||
|---|---|---|---|---|
| русское название | международное название | русское | международное | |
| Длина | метр | metre (meter) | м | m |
| Масса | килограмм | kilogram | кг | kg |
| Время | секунда | second | с | s |
| Сила тока | ампер | ampere | А | A |
| Термодинамическая температура | кельвин | kelvin | К | K |
| Сила света | кандела | candela | кд | cd |
| Количество вещества | моль | mole | моль | mol |
Производные единицы
Производные единицы могут быть выражены через основные с помощью математических операций: умножения и деления. Некоторым из производных единиц, для удобства, присвоены собственные названия, такие единицы тоже можно использовать в математических выражениях для образования других производных единиц.
Математическое выражение для производной единицы измерения вытекает из физического закона, с помощью которого эта единица измерения определяется или определения физической величины, для которой она вводится. Например, скорость — это расстояние, которое тело проходит в единицу времени; соответственно, единица измерения скорости — м/с (метр в секунду).
Часто одна и та же единица может быть записана по-разному, с помощью разного набора основных и производных единиц (см., например, последнюю колонку в таблице Производные единицы с собственными названиями). Однако на практике используются установленные (или просто общепринятые) выражения, которые наилучшим образом отражают физический смысл величины. Например, для записи значения момента силы следует использовать Н·м, и не следует использовать м·Н или Дж.
| Единица измерения | Международное название | Обозначение | Величина в единицах СИ | |
|---|---|---|---|---|
| русское | международное | |||
| минута | minute | мин | min | 60 с |
| час | hour | ч | h | 60 мин = 3600 с |
| сутки | day | сут | d | 24 ч = 86 400 с |
| градус | degree | ° | ° | (π/180) рад |
| угловая минута | minute | ′ | ′ | (1/60)° = (π/10 800) |
| угловая секунда | second | ″ | ″ | (1/60)′ = (π/648 000) |
| литр | litre (liter) | л | l, L | 1/1000 м³ |
| тонна | tonne | т | t | 1000 кг |
| непер | neper | Нп | Np | безразмерна |
| бел | bel | Б | B | безразмерна |
| электронвольт | electronvolt | эВ | eV | ≈1,60217733×10 −19 Дж |
| атомная единица массы | unified atomic mass unit | а. е. м. | u | ≈1,6605402×10 −27 кг |
| астрономическая единица | astronomical unit | а. е. | ua | ≈1,49597870691×10 11 м |
| морская миля | nautical mile | миля | — [3] | 1852 м (точно) |
| узел | knot | уз | 1 морская миля в час = (1852/3600) м/с | |
| ар | are | а | a | 10² м² |
| гектар | hectare | га | ha | 10 4 м² |
| бар | bar | бар | bar | 10 5 Па |
| ангстрем | ångström | Å | Å | 10 −10 м |
| барн | barn | б | b | 10 −28 м² |
Кроме того, ГОСТ 8.417-2002 разрешает применение следующих единиц: град, световой год, парсек, диоптрия, киловатт-час, вольт-ампер, вар, ампер-час, карат, текс, гал, оборот в секунду, оборот в минуту. Разрешается применять единицы относительных и логарифмических величин, такие как процент, промилле, миллионная доля, фон, октава, декада. Допускается также применять единицы времени, получившие широкое распространение, например, неделя, месяц, год, век, тысячелетие.
Другие единицы применять не разрешается.
Тем не менее, в различных областях иногда используются и другие единицы.
Некоторые страны не приняли систему СИ, или приняли её лишь частично и продолжают использовать английскую систему мер или сходные единицы.
Кратные и дольные единицы
Десятичные кратные и дольные единицы образуют с помощью стандартных множителей и приставок СИ, присоединяемых к названию или обозначению единицы.
Введение в Си. Послание из прошлого столетия
Я несколько раз в своих комментариях ссылался на книгу Эндрю Таненбаума «Operating Systems Design and Implementation» на ее первое издание и на то, как в ней представлен язык Си. И эти комментарии всегда вызывали интерес. Я решил, что пришло время опубликовать перевод этого введения в язык Си. Оно по-прежнему актуально. Хотя наверняка найдутся и те, кто не слышал о языке программировании PL/1, а может даже и об операционной системе Minix.
Это описание интересно также и с исторической точки зрения и для понимания того, как далеко ушел язык Си с момента своего рождения и IT-отрасль в целом.
Хочу сразу оговориться, что мой второй язык французский:

Но это компенсируется 46-летним программистским стажем.
Итак, приступим, наступила очередь Эндрю Таненбаума.
Введение в язык Си (стр. 350 — 362)

Язык программирования Cи был создан Деннисом Ритчи из AT&T Bell Laboratories как язык программирования высокого уровня для разработки операционной системы UNIX. В настоящее время язык широко используется в различных областях. C особенно популярен у системных программистов, потому что позволяет писать программы просто и кратко.
Основной книгой, описывающая язык Cи, является книга Брайана Кернигана и Денниса Ритчи « Язык программирования Cи» (1978). Книги по языку Си писали Bolon (1986), Gehani (1984), Hancock and Krieger (1986), Harbison и Steele (1984) и многие другие.
В этом приложении мы попытаемся дать достаточно полное введение в Cи, так что те кто знаком с языками высокого уровня, такими как Pascal, PL/1 или Modula 2, смогут понять большую часть кода MINIX, приведенного в этой книге. Особенности Cи, которые не используются в MINIX, здесь не обсуждаются. Многочисленные тонкие моменты опущены. Акцент делается на чтении программ на Си, а не на написании кода.
А.1. Основы языка Си
Программа на Cи состоит из набора процедур (часто называемых функциями, даже если они не возвращают значений). Эти процедуры содержат объявления, операторы и другие элементы, которые вместе говорят компьютеру что надо делать. На рисунке A-1 показана небольшая процедура, в которой объявляются три целочисленные переменные и присваиваются им значения. Имя процедуры — main (главная). Процедура не имеет формальных параметров, на что указывает отсутствие каких-либо идентификаторов между скобками за именем процедуры. Тело процедуры заключено в фигурные скобки ( < >). Этот пример показывает, что Cи имеет переменные, и что эти переменные должны быть объявлены до использования. Cи также имеет операторы, в этом примере это операторы присваивания. Все операторы должны заканчиваться точкой с запятой (в отличие от Паскаля, который использует двоеточия между операторами, а не после них).
Комментарии начинаются с символов « / *» и заканчивается символами «* /» и могут занимать несколько строк.
Процедура содержит три константы. Константа 10 в первом присваивании
это обычная десятичная константа. Константа 015 является восьмеричной константой
(равно 13 в десятичной системе счисления). Восьмеричные константы всегда начинаются с начального нуля. Константа 0xFF является шестнадцатеричной константой (равной 255 десятичной). Шестнадцатеричные константы всегда начинаются с 0x. Все три типа используются в Cи.
А.2. Основные типы данных
Cи имеет два основных типа данных (переменных): целое и символ, объявляемые как int и char, соответственно. Нет отдельной булевой переменной. В качестве булевой переменной используется переменная int. Если эта переменная содержит 0, то это означает ложь/false, а любое другое значение означает истина/true. Cи также имеет и типы с плавающей точкой, но MINIX не использует их.
К типу int можно применять «прилагательные» short, long или unsigned, которые определяют (зависящий от компилятора) диапазон значений. Большинство процессоров 8088 используют 16-битные целые числа для int и short int и 32-битные целые числа для long int. Целые числа без знака (unsigned int) на процессоре 8088 имеют диапазон от 0 до 65535, а не от -32768 до +32767, как это у обычных целых чисел (int). Символ занимает 8 бит.
Спецификатор register также допускается как для int, так и для char, и является подсказкой для компилятора, что объявленную переменную стоит поместить в регистр, чтобы программа работала быстрее.
Некоторые объявления показаны на рис. А — 2.
Преобразование между типами разрешено. Например, оператор
разрешен, даже если i имеет тип int, а flag_pole — long. Во многих случаях
необходимо или полезно принудительно проводить преобразования между типами данных. Для принудительного преобразования достаточно поставить целевой тип в скобках перед выражением для преобразования. Например:
предписывает преобразовать целое число i в long перед передачей его в качестве параметра в процедуру p, которая ожидает именно параметр long.
При преобразовании между типами следует обратить внимание на знак.
При преобразовании символа в целое число некоторые компиляторы обрабатывают символы как знаковые, то есть от — 128 до +127, тогда как другие рассматривают их как
без знака, то есть от 0 до 255. В MINIX часто встречаются такие выражения, как
которые преобразует с (символ) в целое число, а затем выполняет логическое И
(амперсанд) с восьмеричной константой 0377. В результате получается, что старшие 8 бит
устанавливаются в ноль, фактически заставляя рассматривать c как 8-битное число без знака, в диапазоне от 0 до 255.
А.3. Составные типы и указатели
В этом разделе мы рассмотрим четыре способа построения более сложных типов данных: массивы, структуры, объединения и указатели (arrays, structures, unions, and pointers). Массив — это коллекция/множество элементов одного типа. Все массивы в Cи начинаются с элемента 0.
объявляет массив a с 10 целыми числами, которые будут хранится в элементах массива от [0] до a [9]. Второе, массивы могут быть трех и более измерений, но они не используются в MINIX.
Структура — это набор переменных, обычно разных типов. Структура в Cи похож на record в Паскале. Оператор
объявляет s как структуру, содержащую два члена, целое число i и символ c.
Чтобы присвоить члену i структуры s значение 6, нужно записать следующее выражение:
где оператор точка указывает, что элемент i принадлежит структуре s.
Объединение — это также набор членов, аналогично структуре, за исключением того, что в любой момент в объединение может находится только один из них. Объявление
означает, что вы можете иметь целое число или символ, но никак не оба. Компилятор должен выделить достаточно места для объединения, чтобы в нем мог разместиться самый большой (с точки зрения занимаемой памяти) элемент объединения. Объединения используются только в двух местах в MINIX (для определения сообщения как объединения нескольких различных структур, и для определения дискового блока как объединения блока данных, блока i-узла, блока каталога и т. д.).
Указатели используются для хранения машинных адресов в Cи. Они используются очень и очень часто. Символ звездочка (*) используется для обозначения указателя в объявлениях. Объявление
объявляет целое число i, указатель на целое число pi, массив a из 10 элементов, массив b из 10 указателей на целые числа и указатель на указатель ppi на целое число.
Точные правила синтаксиса для сложных объявлений, объединяющих массивы, указатели и другие типы несколько сложны. К счастью, MINIX использует только простые объявления.
На рисунке A-3 показано объявление массива z структур struct table, каждая из которых имеет
три члена, целое число i, указатель cp на символ и символ с.
Массивы структур распространены в MINIX. Далее, имя table можно объявить как структуру struct table, которую можно использовать в последующих объявлениях. Например,
объявляет p указателем на структуру struct table и предлагает сохранить ее
в register. Во время выполнения программы p может указывать, например, на z [4] или
на любой другой элемент в z, все 20 элементов которой являются структурами типа struct table.
Чтобы сделать p указателем на z [4], достаточно написать
где амперсанд в качестве унарного (монадического) оператора означает «взять адрес того, что за ним следует ». Скопировать в целочисленную переменную n значение члена i
структуры, на которую указывает указатель р, можно следующим образом:
Обратите внимание, что стрелка используется для доступа к члену структуры через указатель. Если мы будем использовать переменную z, то тогда мы должны использовать оператор с точкой:
Разница в том, что z [4] является структурой, и оператор точки выбирает элементы
из составных типов (структуры, массивы) напрямую. С помощью указателей мы не выбираем участника напрямую. Указатель предписывает сначала выбрать структуру и только потом выбрать члена этой структуры.
Иногда удобно дать имя составному типу. Например:
определяет unshort как unsigned short (короткое целое число без знака). Теперь unshort может быть использован в программе как основной тип. Например,
объявляет короткое целое число без знака, указатель на короткое целое число без знака и
массив коротких целых без знака.
А.4. Операторы
Процедуры в Cи содержат объявления и операторы. Мы уже видели объявления, так что теперь мы будем рассматривать операторы. Назначение условного оператора и операторов цикла по существу такие же, как и в других языках. Рисунок А – 4 показывает несколько примеров из них. Единственное, на что стоит обратить внимание, это то, что фигурные скобки используются для группировки операторов, а оператор while имеет две формы, вторая из которых похожа на оператор repeat Паскаля.
Cи также имеет оператор for, но он не похож на оператор for в любом другом языке. Оператор for имеет следующий вид:
Тоже самое можно выразить через опертор while:
В качестве примера рассмотрим следующий оператор:
Этот оператор устанавливает первые n элементов массива a равными нулю. Выполнение оператора начинается с установки i в ноль (это делается вне цикла). Затем оператор повторяется до тех пор, пока i < n, выполняя при этом присваивание и увеличение i. Конечно, вместо оператора присвоения значения текущему элементу массива нуля может быть составной оператор (блок), заключенный в фигурные скобки.
Си имеет также оператор аналогичный case-оператору в языке Pascal. Это switch-оператор. Пример представлен на рисунке А-5. В зависимости от значения выражения, указанного в switch, выбирается тот или иной оператор cаse.
Если выражение не соответствует ни одному из операторов case, то выбирается оператор по умолчанию (default).
Если выражение не связано ни с одним оператором case и оператор default отсутствует, то выполнение продолжается со следующего оператора после оператора switch.
Следует отметить, что для выхода из блока case следует использовать оператор break. Если оператор break отсутствует, то будет выполняться следующий блок case.
Оператор break также действует внутри циклов for и while. При этом надо помнить, что если оператор break находится внутри серии вложенных циклов, выход осуществляется только на один уровень вверх.
Связанным оператором является оператор continue, который не выходит из цикла,
но вызывает завершение текущей итерации и начало следующей итерации
немедленно. По сути, это возврат к вершине цикла.
Cи имеет процедуры, которые могут вызываться с параметрами или без параметров.
Согласно Кернигану и Ричи (стр. 121), не разрешено передавать массивы,
структуры или процедуры в качестве параметров, хотя передача указателей на все это
допускается. Есть ли книга или нет ее (так и всплывет в памяти:- «Если жизнь на Марсе, нет ли жизни на Марсе»), многие компиляторы языка Си допускают структуры в качестве параметров.
Имя массива, если оно написано без индекса, означает указатель на массив, что упрощает передачу указателя массива. Таким образом, если a является именем массива любого типа, его можно передать в процедуру g, написав
Это правило действует только для массивов, на структуры это правило не расапространяется.
Процедуры могут возвращать значения, выполняя оператор return. Этот оператор может содержать выражение, результат выполнения которого будет возвращено в качестве значения процедуры, но вызвавшая процедура может смело игнорировать возвращаемое значение. Если процедура возвращает значение, то тип значение записывается перед именем процедуры, как показано на рис. A-6. Аналогично параметрам, процедуры не могут возвращать массивы, структуры или процедуры, но могут вернуть указатели на них. Это правило разработано для более эффективной реализации — все параметры и результаты всегда соответствуют одному машинному слову (в котором хранится адрес). Компиляторы, которые допускают использование структур в качестве параметров, обычно также допускают их использование в качестве возвращаемых значений.
C не имеет встроенных операторов ввода / вывода. Ввод/вывод реализуется путем вызова библиотечных функций, наиболее распространенные из которых проиллюстрированы ниже:
Первый параметр — это строка символов между кавычками (на самом деле это массив символов).
Любой символ, который не является процентом, просто печатается как есть.
Когда встречается процент, печатается следующий параметр в виде, определяемом буквой, следующей за процентом:
Также допускаются буквы D, 0 и X для десятичной, восьмеричной и шестнадцатеричной печати длинных чисел.
А.5. Выражения
Выражения создаются путем объединения операндов и операторов.
Арифметические операторы, такие как + и -, и реляционные операторы, такие как <
и > похожи на своих аналогов в других языках. Оператор %
используется по модулю. Стоит отметить, что оператор равенства это ==, а оператор неравенства это! =. Чтобы проверить равны ли a и b, можно написать так:
Си также позволяет объединять оператор присваивания с другими операторами, поэтому
Другие операторы также могут быть объединены таким образом.
Си имеет операторы для манипулирования битами слова. Разрешены как сдвиги, так и побитовые логические операции. Операторы сдвига влево и вправо являются <<
и >> соответственно. Побитовые логические операторы &, | и ^, которые являются логическим И (AND), включающим ИЛИ (OR) и исключающим ИЛИ (XOP) соответственно. Если i имеет значение 035 (восьмеричное), тогда выражение i & 06 имеет значение 04 (восьмеричное). Еще один пример, если i = 7, то
и получим 074 для j.
Другой важной группой операторов являются унарные операторы, каждый из которых принимает только один операнд. Как унарный оператор, амперсанд & получает адрес переменной.
Если p является указателем на целое число, а i является целым числом, оператор
вычисляет адрес i и сохраняет его в переменной p.
Противоположным взятию адреса является оператор, который принимает указатель в качестве входных данных и вычисляет значение, находящееся по этому адресу. Если мы только что присвоили адрес i указателю p, тогда *p имеет то же значение, что и i.
Другими словами, в качестве унарного оператора за звездочкой следует указатель (или
выражение, дающее указатель), и возвращает значение элемента, на который указывает. Если i имеет значение 6, то оператор
присвоит j число 6.
Оператор! (восклицательный знак – оператор отрицания) возвращает 0, если его операнд отличен от нуля, и 1, если его оператор равен 0.
Он в основном используется в операторах if, например
проверяет значение х. Если x равен нулю (false), то k присваивается значение 0. В действительности, оператор! отменяет условие, следующее за ним, так же, как оператор not в Паскаль.
является побитовым оператором дополнения. Каждый 0 в своем операнде
становится 1, а каждый 1 становится 0.
Оператор sizeof сообщает размер его операнда в байтах. Применительно к
массиву из 20 целых чисел a на компьютере с 2-байтовыми целыми числами, например sizeof a будет иметь значение 40.
Последняя группа операторов — это операторы увеличения и уменьшения.
означает увеличение р. На сколько увеличится p, зависит от его типа.
Целые числа или символы увеличиваются на 1, но указатели увеличиваются на
размер объекта, на который указывает Таким образом, если а является массивом структур, а р указатель на одну из этих структур, и мы пишем
чтобы заставить p указать на одну из структур в массиве, то после увеличения p
будет указывать на a[4] независимо от того, насколько велики структуры. Оператор
аналогичен оператору p++, за исключением того, что он уменьшает, а не увеличивает значение операнда.
где обе переменные являются целыми числами, исходное значение k присваивается n и
только после этого происходит увеличение k. В операторе
сначала увеличивается k, затем его новое значение сохраняется в n.
Таким образом, ++ (или —) оператор может быть записан до или после его операнда, что приводит к получению различных значений.
Последний оператор – это? (знак вопроса), который выбирает одну из двух альтернатив
разделеных двоеточием. Например, оператор,
сравнивает х с у. Если x меньше y, тогда i получает значение 6; в противном случае переменная i получает значение k + 1. Скобки не обязательны.
А.6. Структура программы
Программа на С состоит из одного или нескольких файлов, содержащих процедуры и объявления.
Эти файлы могут быть скомпилированы по отдельности в объектные файлы, которые затем линкуются друг с другом (с помощью компоновщика) для формирования исполняемой программы.
В отличие от Паскаля, объявления процедур не могут быть вложенными, поэтому все они записываются на «верхнем уровне» в файле программы.
Допускается объявлять переменные вне процедур, например, в начале файла перед первым объявлением процедуры. Эти переменные являются глобальными, и могут использоваться в любой процедуре во всей программе, если только ключевое слово static не предшествует объявлению. В этом случае эти переменные нельзя использовать в другом файле. Те же правила применяются к процедурам. Переменные, объявленные внутри процедуры, являются локальными для процедуры.
Процедура может обращаться к целочисленной переменной v, объявленной в другом файле (при условии, что переменная не является статической), объявляя ее у себя внешней:
Каждая глобальная переменная должна быть объявленным ровно один раз без атрибута extern, чтобы выделить память под нее.
Переменные могут быть инициализированы при объявлении:
Массивы и структуры также могут быть инициализированы. Глобальные переменные, которые не инициализированы явно, получают значение по умолчанию, равное нулю.
А.7. Препроцессор Cи
Прежде чем исходный файл будет передан компилятору Cи, он автоматически обрабатывается
программой под названием препроцессор. Именно выход препроцессора, а не
оригинальная программа, подается на вход компилятора. Препроцессор выполняет
три основных преобразования в файле перед передачей его компилятору:
1. Включение файлов.
2. Определение и замена макросов.
3. Условная компиляция.
Все директивы препроцессора начинаются со знака числа (#) в 1-ом столбце.
Когда директива вида
встречается препроцессором, он включает файл prog.h, строка за строкой, в
программу, которая будет передана компилятору. Когда директива #include написана как
то включаемый файл ищется в каталоге /usr/include вместо рабочего каталога. В Cи распространена практика группировать объявления, используемые несколькими файлами, в заголовочном файле (обычно с суффиксом .h), и включать их там, где они необходимы.
Препроцессор также позволяет определения макросов. Например,
определяет макрос BLOCK_SIZE и присваивает ему значение 1024. С этого момента
каждое вхождение строки из 10 символов «BLOCK_SIZE» в файле будет
заменяться 4-символьной строкой «1024» до того, как компилятор увидит файл с программой. По соглашению имена макросов пишутся в верхнем регистре. Макросы могут иметь параметры, но на практике немногие это делают.
Третья особенность препроцессора — условная компиляция. В MINIX есть несколько
мест, где код написан специально для процессора 8088, и этот код не должен включаться при компиляции для другого процессора. Эти разделы выглядят как так:
Если символ i8088 определен, то операторы между двумя директивами препроцессора #ifdef i8088 и #endif включаются в выходные данные препроцессора; в противном случае они пропускаются. Вызывая компилятор с командой
или включив в программу заявление
мы определяем символ i8088, поэтому весь зависимый код для 8088 быть включен. По мере развития MINIX он может приобрести специальный код для 68000s и других процессоров, которые будут обрабатываться также.
В качестве примера того, как работает препроцессор, рассмотрим программу рис. A-7 (a). Она включает в себя один файл prog.h, содержимое которого выглядит следующим образом:
Представьте, что компилятор был вызван командой
После того, как файл прошел через препроцессор, вывод будет таким, как показано на Рис. A-7 (b).
Именно этот вывод, а не исходный файл, дается как вход в Cи компилятор.
Обратите внимание, что препроцессор выполнил свою работу и удалил все строки, начинающиеся со знаком #. Если компилятор был бы вызван так
то была бы включена другая печать. Если бы он был вызван вот так:
то ни одна печать не была бы включена. (Читатель может поразмышлять о том, что случилось бы, если бы компилятор вызывался с обоими флагами -Dflags.)
А.8. Идиомы
В этом разделе мы рассмотрим несколько конструкций, которые характерны для Cи, но не распространены в других языках программирования. Для начала рассмотрим петлю:
Переменные p и q обычно являются символьными указателями, а n является счетчиком. Цикл копирует n-символьную строку из места, на которое указывает q, в место, на которое указывает р. На каждой итерации цикла счетчик уменьшается, пока он не доходит до 0, и каждый из указателей увеличивается, поэтому они последовательно указывают на ячейки памяти с более высоким номером.
Еще одна распространенная конструкция:
которая устанавливает первые N элементов а в 0. Альтернативный способ написания этого цикла выглядит так:
В этой формулировке целочисленный указатель p инициализируется так, чтобы указывать на нулевой элемент массива. Цикл продолжается до тех пор, пока p не достиг адреса N-ого элемента массива. Конструкция указателя гораздо эффективнее, чем конструкция массива, и поэтому обычно используют ее.
Операторы присвоения могут появляться в неожиданных местах. Например,
сначала вызывает функцию f, затем присваивает результат вызова функции a и
наконец, проверяет, является ли оно истинным (ненулевым) или ложным (нулевым). Если а не равно нулю, то условие выполнено. Оператор
также сначало значение переменной b переменной a, а затем проверяет a, не является ли значение ненулевым. И этот оператор полностью отличается от
который сравнивает две переменные и выполняет оператор, если они равны.