Анотація.
Мова "C" (вимовляється "сі") - це універсальна мова програмування, для якого характерні економічність вирази, сучасний потік управління і структури даних, багатий набір операторів. Мова "C" не є ні мовою "дуже високого рівня", ні "великим" мовою, і не призначається для деякої спеціальної області застосування. але відсутність обмежень і спільність мови роблять його більш зручним і ефективним для багатьох завдань, ніж мови, ймовірно більш потужні.
Мова "C", що спочатку призначався для написання операційної системи "UNIX" на ЕОМ DEC PDP-11, був розроблений і реалізований на цій системі Деннісом Річі. Операційна система, компілятор з мови "C" і по суті всі прикладні програми системи "UNIX" (включаючи все програмне забезпечення, використане при підготовці цієї книги) написані на "C". Комерційні компілятори з мови "C" існують також на деяких інших ЕОМ, включаючи IBM SYSTEM/370, HONEYWELL 6000, INTERDATA 8/32. Мова "C", однак, не пов'язаний з якими-небудь певними апаратними засобами або системами, і на ньому легко писати програми, які можна пропускати без змін на будь-який ЕОМ, що має "C"-компілятор.
Ця книга призначена для того, щоб допомогти читачеві навчитися програмувати на мові "C". Вона стримає навчальний вступ, мета якого - дозволити новим користувачам почати програмувати як можна швидше, окремі розділи по всіх основних особливостей мови та довідкове керівництво. Навчання побудоване в основному на читанні, написанні і розборі прикладів, а не голою формулюванні правил. Приклади, наведені в книзі, здебільшого є закінченими реальними програмами, а не окремими фрагментами. Всі приклади були перевірені безпосередньо з тексту книги, де вони надруковані у вигляді, придатному для введення в машину. Крім вказівок про те, як зробити використання мови більш ефективним, ми також намагалися, де це можливо, проілюструвати корисні алгоритми та принципи гарного стилю і розумної розробки.
Ця книга не є введенням до програмування; вона передбачає певне знайомство з основними поняттями програмування такими як змінні, оператори присвоювання, цикли, функції. Проте і новачок у програмуванні повинен виявитися в стані читати підряд і освоїтися з мовою, хоча при цьому була б корисною допомогу більш досвідченого колеги.
З нашого досвіду, "C" показав себе приємним, виразним і різнобічним мовою на широкому безлічі різноманітних програм. Його легко вивчити, і він не втрачає своїх якостей з ростом досвіду програміста. Ми сподіваємося, що ця книга допоможе вам добре його використовувати.
Вдумлива критика та пропозиції багатьох наших друзів і колег дуже багато додали як для самої книги, так і для нашого задоволення при її написанні. Зокрема, Майк Біапсі, Джим Блю, Стью Фельдман, Доуг Мак-Ілрой, Білл Рум, Боб Розин і Ларрі Рослер ретельно прочитали безліч варіантів. Ми також зобов'язані Елю Ахо, Стіву Борну, Деву Дворак, Чаку Хелею, Деббі Хелей, Маріон Харрісу, Ріку Холт, Стіву Джонсону, Джону Машею, Бобу митця, Ральфу Мьюа, Пітеру Нельсону, Еллиоту Пінсон, Біллу Плагеру, Джеррі Співакові, Кену Томпсону і Пітеру Вейнбергеру за корисні зауваження на різних етапах і Майку Лоску і Джо Осанна за неоціненну допомогу при друкуванні книги. Брайен В. Керніган Денніс М. Річі
Зміст.
Анотація
0.1. Введення
1. Навчальний введення
1.1. Починаємо
1.2. Змінні і арифметика
1.3. Оператор FOR
1.4. Символічні константи
1.5. Набір корисних програм
1.5.1. Введення і виведення символів
1.5.2. Копіювання файлу
1.5.3. Підрахунок символів
1.5.4. Підрахунок рядків
1.5.5. Підрахунок слів
1.6. Масиви
1.7. Опції
1.8. Аргументи - виклик за значенням
1.9. Масиви символів
1.10. Область дії: зовнішні змінні
1.11. Резюме
2. Типи, операції та вирази
2.1. Імена змінних
2.2. Типи і розміри даних
2.3. Константи
2.3.1. Символьна константа
2.3.2. Вирази зі сталими
2.3.3. Рядкова константа
2.4. Описи
2.5. Арифметичні операції
2.6. Операції відносини і логічні операції
2.7. Перетворення типів
2.8. Операції збільшення та зменшення
2.9. Побітового логічні операції
2.10. Операції та вирази привласнення
2.11. Умовні вирази
2.12. Старшинство і порядок обчислення
3. Потік управління
3.1. Оператори і блоки
3.2. IF - ELSE
3.3. ELSE - IF
3.4. Перемикач
3.5. Цикли - WHILE і FOR
3.6. Цикл DO - WHILE
3.7. Оператор BREAK
3.8. Оператор CONTINUE
3.9. Оператор GOTO і мітки
4. Функції і структура програм
4.1. Основні відомості
4.2. Функції, що повертають нецілим значення
4.3. Ще про аргументи функцій
4.4. Зовнішні змінні
4.5. Правила, що визначають область дії
4.5.1. Область дії
4.6. Статичні змінні
4.7. Регістрові змінні
4.8. Блочна структура
4.9. Ініціалізація
4.10. Рекурсія
4.11. Препроцесор мови "C"
4.11.1. Включення файлів
4.11.2. Mакроподстановка
5. Покажчики та масиви
5.1. Покажчики та адреси
5.2. Покажчики та аргументи функцій
5.3. покажчики і масиви
5.4. Адресна арифметика
5.5. покажчики символів та функції
5.6. Покажчики - не цілі
5.7. Багатовимірні масиви
5.8. Масиви вказівників; покажчики покажчиків
5.9. Ініціалізація масивів покажчиків
5.10. Покажчики та багатовимірні масиви
5.11. Командний рядок аргументів
5.12. Покажчики на функції
6. Структури
6.1. Основні відомості
6.2. Структури та функції
6.3. Масиви структур
6.4. Покажчики на структури
6.5. Структури, що мають посилання на себе
6.6. Пошук в таблиці
6.7. Поля
6.8. Об'єднання
6.9. Визначення типу
7. Введення і виведення
7.1. Звернення до стандартної бібліотеці
7.2. Стандартний введення і виведення - функції GETCHAR і PUTCHAR
7.3. Форматний висновок - функція PRINTF
7.4. Форматний введення - функція SCANF
7.5. Форматне перетворення в пам'яті
7.6. Доступ до файлів
7.7. Обробка помилок - STDERR і EXIT
7.8. Введення і виведення рядків
7.9. Кілька різноманітних функцій
7.9.1. Перевірка виду символів і перетворення
7.9.2. Функція UNGETC
7.9.3. Звернення до системи
7.9.4. Управління пам'яттю
8. Інтерфейс системи UNIX
8.1. Дескриптори файлів
8.2. Низькорівневий введення/виведення - оператори READ і WRITE
8.3. Відкриття, створення, закриття і розщеплення (UNLINK)
8.4. Довільний доступ - SEEK і LSEEK
8.5. Приклад - реалізація функцій FOPEN і GETC
8.6. Приклад - роздруківка довідників
8.7. Приклад - розподільник пам'яті
9. Додаток а: довідкове керівництво по мові 'C'.
9.1. Введення
10. Лексичні угоди
10.1. Коментарі
10.2. Ідентифікатори (імена)
10.3. Ключові слова
10.4. Константи
10.4.1. Цілі константи
10.4.2. Явні довгі константи
10.4.3. Символьні константи
10.4.4. Плаваючі константи
10.5. Строки
10.6. Характеристики апаратних засобів
11. Синтаксична нотація
12. Що в імені тобі моєму?
13. Об'єкти і L-значення
14. Перетворення
14.1. Символи і цілі
14.2. Типи FLOAT і DOUBLE
14.3. Плаваючі і цілочисельні величини
14.4. Покажчики та цілі
14.5. Ціле без знака
14.6. Арифметичні перетворення
15. Вирази
15.1. Первинні вирази
15.2. Унарні операції
15.3. Мультиплікативний операції
15.4. Адитивні операції
15.5. Операції зсуву
15.6. Операції відносини
15.7. Операції рівності
15.8. Побітового операція 'і'
15.9. Побітового операція виключає 'або'
15.10. Побітового операція включає 'або'
15.11. Логічна операція 'і'
15.12. Операція логічного 'або'
15.13. Умовна операція
15.14. Операція присвоювання
15.15. Операція кома
16. Описи
16.1. Специфікатор класу пам'яті
16.2. Специфікатор типу
16.3. Описувачі
16.4. Сенс описувачів
16.5. Опис структур та об'єднань
16.6. Ініціалізація
16.7. Імена типів
16.8. TYPEDEF
17. Оператори
17.1. Операторний вираз
17.2. Складовою оператор (або блок)
17.3. Умовні оператори
17.4. Оператор WHILE
17.5. Оператор DO
17.6. Оператор FOR
17.7. Оператор SWITCH
17.8. Оператор BREAK
17.9. Оператор CONTINUE
17.10. Оператор повернення
17.11. Оператор GOTO
17.12. Приречений оператор
17.13. Порожній оператор
18. Зовнішні визначення
18.1. Зовнішнє визначення функції
18.2. Зовнішні визначення даних
19. Правила, що визначають область дії
19.1. Лексична область дії
19.2. Область дії зовнішніх ідентифікаторів
20. Строки управління компілятором
20.1. Заміна лексем
20.2. Включення файлів
20.3. Умовна компіляція
21. Неявні опису
22. Знову про типи
22.1. Структури та об'єднання
22.2. Опції
22.3. Масиви, покажчики та індексація
22.4. Явні перетворення покажчиків
23. Константні вирази
24. Міркування про переносимості
25. Анахронізми
26. Підсумок синтаксичних правил
26.1. Вирази
26.2. Описи
26.3. Оператори
26.4. Зовнішні визначення
26.5. Препроцесор
27. Присвоєння структури
28. Тип перерахування
29. Таблиця зображень недрукованих символів мови "C".
0.1. Введення.
Мова "C" є універсальною мовою програмування. Він тісно пов'язаний з операційною системою "UNIX", так як був розвинений на цій системі і тому що "UNIX" та її програмне забезпечення написано на "C". Сам мова, однак, не
пов'язаний з якою-небудь однією операційною системою або машиною;
і хоча його називають мовою системного програмування, так
як він зручний для написання операційних систем, він з рівним
успіхом використовувався при написанні великих обчислювальних
програм, програм для обробки текстів і баз даних.
Мова "C" - це мова щодо "низького рівня". В
такій характеристиці немає нічого образливого, це просто
означає, що "C" має справу з об'єктами того ж виду, що й
більшість ЕОМ, а саме, з символами, числами і адресами.
Вони можуть об'єднуватися і пересилатися за допомогою звичайних
арифметичних і логічних операцій, що здійснюються реаль-
нимі ЕОМ.
У мові "C" відсутні операції, що мають справу Непос-
редственно зі складовими об'єктами, такими як рядки симво-
лов, множини, списки або з масивами, які розглядаються як
ціле. Тут, наприклад, немає ніякого аналога операціях PL/1,
оперують з цілими масивами та рядками. Мова не наданих
тавляет ніяких інших можливостей розподілу пам'яті,
окрім статичного визначення і механізму стеков, забезпечують-
ваемого локальними змінних функцій; тут немає ні
"Куп" (HEAP), ні "збирання сміття", як це передбачається в
Алгол-68. Нарешті, сам по собі "C" не забезпечує ніяких
можливостей вводу-виводу: тут немає операторів READ або
WRITE і ніяких вбудованих методів доступу до файлів. Всі ці
механізми високого рівня повинні забезпечуватися явно викликаючи-
емимі функціями.
Аналогічно, мова "C" пропонує тільки прості, після-
послідовно конструкції потоків управління: перевірки, цикли,
групування і підпрограми, але не мультипрограмування,
паралельні операції, синхронізацію або співпрограми.
Хоча відсутність деяких з цих коштів може вигля-
діти як гнітюча неповноцінність ( "виходить, що я повинен
звертатися до функції, щоб порівняти два рядки символів
?!"), Але утримання мови в скромних розмірах дає реальні
переваги. Так як "C" відносно малий, він не вимагає
багато місця для свого опису і може бути швидко вивчений.
Компілятор з "C" може бути простим і компактним. Крім то-
го, компілятори легко пишуться; при використанні сучасної
технології можна очікувати написання компілятора для нової ЕОМ
за пару місяців і при цьому виявиться, що 80 відсотків прог-
Рамі нового компілятора буде спільною з програмою для вже
існуючих компіляторів. Це забезпечує високий ступінь
мобільності мови. Оскільки типи даних і стуктури управ-
ня, які є в "C", безпосередньо підтримуються біль-
шінством існуючих ЕОМ, бібліотека, необхідна під час
прогону ізольованих програм, виявляється дуже маленькою.
На PDP -11, наприклад, вона містить тільки програми для
32-бітового множення і ділення і для виконання програм
введення та виведення послідовностей. Звичайно, кожна реалі-
ція забезпечує вичерпну, сумісну бібліотеку функ-
ций для виконання операцій введення-виведення, обробки рядків і
розподілу пам'яті, але так як звернення до них здійснюва-
ється тільки явно, можна, якщо необхідно, уникнути їх визо-
ва; ці функції можуть бути компактно написані на самому "C".
* 8 -
Знову ж таки через те, що мова "C" відображає можливості
сучасних комп'ютерів, програми на "C" виявляються достатньо
точно ефективними, тому що не виникає спонукання писати
натомість програми на мові асемблера. Найбільш переконай-
тільних прикладом цього є сама операційна система
"UNIX", яка майже повністю написана на "C". З 13000
рядків програми системи тільки близько 800 рядків самого низько-
го рівня написані на асемблері. Крім того, по суті
все прикладне програмне забезпечення системи "UNIX" напи-
Сано на "C"; переважна більшість користувачів системи
"UNIX" (включаючи одного з авторів цієї книги) навіть не знає
мови асемблера PDP-11.
Хоча "C" відповідає можливостям багатьох ЕОМ, він не
залежить від будь-якої конкретної архітектури машини і в силу
це без особливих зусиль дозволяє писати "перенесення" прог-
Рамі, тобто програми, які можна пропускати без зраді-
ний на різних апаратних засобах. У наших колах став
вже традицією перенесення програмного забезпечення, розроблений-
ного на системі "UNIX", на системи ЕОМ: HONEYWELL, IBM і
INTERDATA. Фактично компілятори з "C" і програмне забезпе-
безпечення під час прогону програм на цих чотирьох системах,
мабуть, набагато більш сумісні, ніж стандартні вер-
оці Фортрану американського національного інституту стандар-
тов (ANSI). Сама операційна система "UNIX" тепер працює
як на PDP-11, так і на INTERDATA 8/32. За винятком прог-
Рамм, які неминуче виявляються в деякій мірі ма-
шинно-залежними, таких як компілятор, асемблер і налагодити-
чик. Написаний на мові "C" програмне забезпечення Іден-
тично на обох машинах. Усередині самої операційної системи
7000 рядків програми, виключаючи математичне забезпечення
мови асемблера ЕОМ та управління операціями вводу-виводу,
співпадають на 95 відсотків.
Програмістам, знайомим з іншими мовами, для порівняй-
ня і протиставлення може виявитися корисним згадка
декількох історичних, технічних та філософських аспектів
"C".
Багато хто з найбільш важливих ідей "C" походять від горазо-
до більш старого, але все ще цілком життєвого мови BCPL,
розробленого Мартіном Річардсом. Побічно мова BCPL надав
вплив на "C" через мову "B", написаний Кеном Томпсоном у
1970 році для першого операційної системи "UNIX" на ЕОМ
PDP-7.
Хоча мова "C" має кілька спільних з BCPL характерних
особливостей, він жодним чином не є діалектом пос-
Ледней. І BCPL і "B" - "безтіпние" мови; єдиним ви-
будинок даних для них є машинне слово, а доступ до дру-
Гим об'єктів реалізується спеціальними операторами або обра-
щеніем до функцій. У мові "C" об'єктами основних типів дан-
них є символи, цілі числа декількох розмірів і чис-
ла з плаваючою точкою. Крім того, є ієрархія вироби
водних типів даних, що створюються покажчиками, масивами,
структурами, об'єднаннями та функціями.
* 9 -
Мова "C" включає основні конструкції потоку управ-
ня, необхідні для добре структурувати програм: группи-
вання операторів, прийняття рішень (IF), цикли з перевіркою
завершення на початку (WHILE, FOR) або в кінці (DO) і вибір
одного з безлічі можливих варіантів (SWITCH). (Всі ці
можливості забезпечувалися і в BCPL, хоча і за кілька
відмінному синтаксисі; ця мова передчував що наступила
через кілька років моду на структурний програмування).
У мові "C" є покажчики і можливість адресної
арифметики. Аргументи передаються функцій за допомогою копі-
вання значення аргументу, і викликана функція не може
змінити фактичний аргумент на що викликає програмі. Якщо
бажано добитися "виклику за посиланням", можна неявно пере-
дати покажчик, і функціязможе змінити об'єкт, на який
цей покажчик вказує. Імена масивів передана вказівкою-
ем початку масивів, так що аргументи на кшталт масивів ефекти-
тивно викликаються за посиланням.
До будь-якої функції можна звертатися рекурсивно, і її ло-
Кальне змінні звичайно "автоматичні", тобто Створюються
заново при кожному зверненні. Опис однієї функції не може
міститися всередині іншого, але змінні можуть описуватися в
відповідно до звичайної блокової структурою. Опції в "C" -
програмі можуть транслюватися окремо. змінні по від-
носіння до функції можуть бути внутрішніми, зовнішніми, а з-
Вестн тільки в межах одного вихідного файлу, або пів-
ністю глобальними. Внутрішні змінні можуть бути автомати-
тичні або статичними. Автоматичні змінні для
більшої ефективності можна поміщати в регістри, але об'яв-
ня регістра є тільки вказівкою для компілятора і ні-
як не пов'язане з конкретними машинними регістрами.
Мова "C" не є мовою до строгих типами в сенсі
Паскаль чи Алгол 68. Він порівняно поблажливий до пре-
утворення даних, хоча і не буде автоматично перетворення
вивать типи даних з буйною невимушеністю мови PL/1.
Існуючі компілятори не передбачають жодної перевірки
під час виконання програми індексів масивів, типів аргу-
ментів і т.д.
У тих ситуаціях, коли бажана сувора перевірка ти-
пов, використовується спеціальна версія компілятора. Ця прог-
Рамі називається LINT очевидно, тому вона вибирає шматочки
пуху з вашої програми. Програма LINT не генерує машин-
ного коду, а робить дуже строгу перевірку всіх тих сторін
програми, які можна проконтролювати під час компіля-
ції і завантаження. Вона визначає невідповідність типів, несов-
местімость аргументів, невикористані або очевидним обра-
зом неініціалізовані змінні, потенційні труднощі
переносимості і т.д. Для програм, які благополучно про-
ходять через LINT, гарантується відсутність помилок типу при-
мірно з тією ж повнотою, як і для програм, написаних,
наприклад, на Алгол-68. Інші можливості програми LINT
будуть відзначені, коли випаде відповідний випадок.
* 10 -
Нарешті, мова "C", подібно до будь-якої іншої мови, має
свої недоліки. Деякі операції мають невдале старшин-
ство; деякі розділи синтаксису могли б бути краще; су-
ступає по кілька версій мови, що відрізняються невеликими де-
талями. Проте мова "C" зарекомендував себе як исклю-
ве ефективний і виразний мова для широкого раз-
нообразія застосувань програмування.
Зміст книги організовано наступним чином. Глава
1 є навчальним введенням в центральну частину мови "C".
Мета - дозволити читачеві стартувати так швидко, як тільки
можливо, тому що ми твердо переконані, що єдиний спо-
соб вивчити нову мову - писати нею програми. При цьому,
однак, передбачається робоче володіння основними елементами
програмування; тут не пояснюється, що таке ЕОМ чи
компілятор, не пояснюється сенс виразів типу N = N 1. Хоча
ми і намагалися, де це можливо, продемонструвати корисну
техніку програмування. Ця книга не призначається бути
довідковим керівництвом щодо структур даних і алгоритмів;
там, де ми змушені були зробити вибір, ми концентрірова-
лися на язиці.
У розділах з 2-го по 6-у різні аспекти "C" викладаються
більш детально і трохи більш формально, ніж у розділі 1,
хоча наголос, як і раніше робиться на розборі прикладів за-
кінчених, корисних програм, а не на окремих фрагментах.
У розділі 2 обговорюються основні типи даних, оператори і
вирази. У розділі 3 розглядаються керуючі оператори:
IF-ELSE, WHILE, FOR і т.д. Глава 4 охоплює функції і
структуру програми - зовнішні змінні, правила визначено-
них областей дії опису і т.д. У главі 5 обговорюються
покажчики і адресна арифметика. Глава 6 містить докладний
опис структур та об'єднань.
У главі 7 описується стандартна бібліотека введення-ви-
вода мови "C", яка забезпечує стандартний інтерфейс з
операційною системою. Ця бібліотека введення-виведення підтримай-
ється на всіх машинах, на яких реалізовано "C", так що
програми, що використовують її для вводу, виводу та інших сис-
темних функцій, можуть переноситися з однієї системи на іншу
по суті без змін.
У главі 8 описується інтерфейс між "C" - програмами
і операційною системою "UNIX". Наголос робиться на введення-виведення,
систему файлів і переносимість. Хоча деякі частини цієї
голови специфічні для операційної системи "UNIX", програм-
Місто, що не використовують "UNIX", все ж таки повинні знайти тут по-
лізниць матеріал, у тому числі деяке уявлення про те,
як реалізована одна версія стандартної бібліотеки і пропозиції
вання для досягнення переносимості програми.
Додаток A містить довідкове керівництво по мові
"C". Воно є "офіційним" викладом синтаксису і се-
Мантіка "C" і (виключаючи чийсь власний компілятор)
остаточним арбітром для всіх двозначностей і упущень
у попередніх розділах.
* 11 -
Так як "C" є, що розвиваються мовою, реалізований-
вим на безлічі систем, частина матеріалу цієї книги мо-
жет не відповідати цьому станом розробки на ка-
кой-то конкретної системи. Ми намагалися уникати таких проб-
лем і застерігати про можливі труднощі. У сумнівних
випадках, однак, ми зазвичай віддавали перевагу описувати ситуацію
для системи "UNIX" PDP-11, так як вона є середовищем для
більшості програмують на мові "C". У додатку а
також описані розбіжності в реалізаціях мови "C" на основ-
них системах.
1. Навчальний введення.
Давайте почнемо з швидкого введення в мову "C". Наша
мета - продемонструвати суттєві елементи мови на ре-
альних програмах, не грузнучи при цьому в деталях, формальних
правилах та виключень. У цій главі ми не намагаємося викласти
мова повністю або хоча б суворо (зрозуміло, що наводяться
приклади будуть коректними). Ми хочемо якомога швидше доважили-
ти вас до такого рівня, на якому ви були б у стані
писати корисні програми, і щоб досягти цього, ми СОСР-
дотачіваемся на основному: змінних і константи, аріфметі-
ке, операторів передачі управління, функції та елементарних
відомостях про введення і виведення. Ми абсолютно свідомо залишаючи-
ем за межами цієї глави багато елементів мови "C", кото-
рие мають першорядне значення при написанні великих
програм, у тому числі покажчики, сртуктури, більшу частину з
багатого набору операторів мови "C", кілька операторів
передачі управління і незліченна кількість деталей.
Такий підхід має, звичайно, свої недоліки. Самим су-
суспільних є те, що повний опис будь-якого конкретних
ного елемента мови не викладається в одному місці, а поясню-
ня, в силу стислості, можуть призвести до неправильного істол-
ковані. Крім того, через неможливість використовувати всю
міць мови, приклади виявляються не настільки короткими і елегантна-
нимі, як вони могли б бути. І хоча ми намагалися звести ці
недоліки до мінімуму, все ж таки їх майте на увазі.
Інший недолік полягає в тому, що подальші глави
будуть неминуче повторювати деякі частини цього розділу. Ми на-
деемся, що таке повторення буде швидше допомагати, ніж раз-
дражать.
В усякому разі, досвідчені програмісти мають опинитися
в стані проекстраполіровать матеріал даного розділу на
свої власні програмістські потреби. Початківці ж повинні
на додаток писати аналогічні маленькі самостійні
програми. І ті, й інші можуть використовувати цей розділ як
каркас, на який будуть навішуватись більш докладні описи-
ня, що починаються з голови 2.
1.1. Hачінаем. Єдиний спосіб освоїти нову мову
програмування - писати нею програми. Перша програм-
ма, яка повинна бути написана, - один для всіх мов:
надрукувати слова: HELLO, WORLD.
Це - найбільш істотний бар'єр; щоб подолати його,
ви повинні зуміти завести десь текст програми, успішно його
скомпілювати, завантажити, прогнати і знайти, де виявилася
ваша видача. Якщо ви навчилися справлятися з цими технічни-
кими деталями, все інше порівняно просто.
* 12 -
Програма друку "HELLO, WORLD" на мові "C" має вигляд:
MAIN ()
(
PRINTF ( "HELLO, WORLDN");
)
Як пропустити цю програму - залежить від використовуваної
вами системи. Зокрема, на операційній системі "UNIX" ви
повинні завести вихідну програму у файлі, ім'я якого
закінчується на ". C", наприклад, HELLO.C, і потім скомпілі-
ровать її по команді
CC HELLO.C
Якщо ви не допустили будь-якої недбалості, такий як
пропуск символу або неправильне написання, компіляція пройом-
дет без повідомлень і буде створений виконуваний файл з ім'ям
а.OUT. Прогон його по команді
A. OUT
призведе до висновку
HELLO, WORLD
На інших системах ці правила будуть іншими; проконсула-тіруйтесь з місцевим авторитетом.
Вправа 1-1.
Пропустіть цю програму на вашій системі. Спробуйте
не включати різні частини програми і подивіться які з-
спілкування про помилки ви при цьому отримаєте.
Тепер деякі пояснення до самій програмі. Будь-яка
"C"-програма, яким би не був її розмір, складається з однієї
або більш "функцій", що вказують фактичні операції
комп'ютера, які повинні бути виконані. Функції в мові
"C" подібні до функцій і підпрограм Фортрану та процедур
PL/1, Паскаль і т.д. У нашому прикладі такою функцією є
MAIN. Зазвичай ви можете давати функцій будь-які імена по вашому
розсуд, але MAIN - це особливе ім'я; виконання вашої прог-
Рамі починається спочатку з функції MAIN. Це означає, що
кожна програма повинна в якомусь місці містити функцію з
ім'ям MAIN. Для виконання певних дій функція
MAIN зазвичай звертається до інших функцій, частина з яких
знаходиться в тій же самій програмі, а частина - в бібліотеках,
містять раніше написані функції.
* 13 -
Одним способом обміну даними між функціями є
передача за допомогою аргументів. Круглі дужки, наступні
за ім'ям функції, містять в собі список аргументів; тут
маIN - функція без аргументів, що вказується як (). Опе-
ратора, що становлять функцію, полягають у фігурні дужки
(І), які аналогічні DO-END в PL/1 або BEGIN-END в ал-
голі, Паскаль і т.д. Звернення до функції здійснюється ука-
заніем її імені, за яким слідує ув'язнений в круглі
дужки список аргументів. тут немає ніяких операторів CALL,
як в фортране або PL/1. Круглі дужки повинні присутності-
вати і в тому випадку, коли функція не має аргументів.
Рядок
PRINTF ( "HELLO, WORLDN");
є зверненням до функції, яка викликає функцію
з ім'ям PRINTF і аргуметом "HELLO, WORLDN". Функція PRINTF
є бібліотечної функцією, яка видає вихідні дан-
ные на термінал (якщо тільки не вказано якесь інше міс-
то призначення). У даному випадку друкується рядок символів,
що є аргументом функції.
Послідовність з будь-якої кількості символів, зак-
люченних в подвоєні лапки "...", називається 'символьної
рядком 'або' рядкової константою '. Поки ми будемо вико-
вать символьні рядки тільки в якості аргументів для
PRINTF та інших функцій.
Послідовність N у наведеній рядку є
позначенням на мові "C" для 'символу нового рядка', кото-
рий служить вказівкою для переходу на терміналі до лівого краю
наступний рядок. Якщо ви не включите N (корисний експери-
мент), то виявите, що ваша видача не закінчиться перех-
будинок терміналу на новий рядок. Використання послідовник-
ності N - єдиний спосіб введення символу нового рядка
в аргумент функції PRINTF; якщо ви спробуєте щось
зразок
PRINTF ( "HELLO, WORLD
");
то "C"-компілятор буде друкувати злорадні діагностичні
повідомлення про відсутніх лапках.
Функція PRINTF не забезпечує автоматичного переходу
на новий рядок, так що багаторазове звернення до неї можна
використовувати для поетапної зборки вихідний рядка. Наша пер-
ша програма, що друкує ідентичну видачу, з точно таким
же успіхом могла б бути написана у вигляді
MAIN ()
(
PRINTF ( "HELLO,");
PRINTF ( "WORLD");
PRINTF ( "N");
)
* 14 -
Підкреслимо, що N представляє тільки один символ. Ус-
ловний 'послідовності', подібні N, дають загальний і до-
пускають розширення механізм для представлення важких для
друку або невидимих символів. Серед інших символів в мові
"C" передбачені наступні: т - для табуляції, B - для
повернення на одну позицію, "- для подвійної лапки і для
самої зворотного косою риси.
Вправа 1-2.
Проведіть експерименти для того, щоб дізнатися що виро-
зойдет, якщо в рядку, що є аргументом функції PRINTF
міститиметься X, де X - деякий символ, який не входить
в вищенаведений список.
1.2. Змінні і арифметика.
Наступна програма друкує наведену нижче таблицю
температур за Фаренгейтом та їх еквівалентів за стоградусной
шкалою Цельсія, використовуючи для перекладу формулу
C = (5/9) * (F-32).
0 -17.8
20 -6.7
40 4.4
60 15.6
... ...
260 126.7
280 137.8
300 140.9
Тепер сама програма:
/ * PRINT FAHRENHEIT-CELSIUS TABLE
FOR F = 0, 20, ..., 300 */
MAIN ()
(
INT LOWER, UPPER, STEP;
FLOAT FAHR, CELSIUS;
LOWER = 0;/* LOWER LIMIT OF TEMPERATURE
TABLE */
UPPER = 300;/* UPPER LIMIT */
STEP = 20;/* STEP SIZE */
FAHR = LOWER;
WHILE (FAHR
CELSIUS = (5.0/9.0) * (FAHR -32.0);
PRINTF ( "% 4.0F% 6.1FN", FAHR, CELSIUS);
FAHR = FAHR + STEP;
)
)
* 15 -
Перші два рядки
/ * PRINT FAHRENHEIT-CELSIUS TABLE
FOR F = 0, 20, ..., 300 */
є коментарем, який у цьому випадку коротко пояс-
вується, що робить програма. Будь-які символи між/* і */иг-
норіруются компілятором; можна вільно користуватися комер-
таріямі для полегшення розуміння програми. Коментарі мо-
гут з'являтися в будь-якому місці, де можливий пробіл або пере-
хід на новий рядок.
У мові "C" всі змінні повинні бути описані до їх іс-
користування, зазвичай це робиться на початку функції до першого
виконуваного оператора. Якщо ви забудете вставити опис,
то отримаєте діагностичне повідомлення від компілятора. Описи-
ня складається з типу і списку змінних, що мають цей тип,
як в
INT LOWER, UPPER, STEP;
FLOAT FAHR, CELSIUS;
Тип INT означає, що всі змінні списку цілі; тип
FLOAT призначений для чисел з плаваючою точкою, тобто для
чисел, які можуть мати дробову частину. Точність як INT,
TAK і FLOAT залежить від конкретної машини, на якій ви ра-
працювати. На PDP-11, наприклад, тип INT відповідає 16-бито-
вому числа зі знаком, тобто числу, лежить між -32768 і
32767. Число типу FLOAT - це 32-бітове число, що має
близько семи значущих цифр і що лежить в діапазоні від 10е-38 до
10е 38. У розділі 2 наводиться список розмірів для інших ма-
шин.
У мові "C" передбачено кілька інших основних ти-
пов даних, крім INT і FLOAT:
CHAR символ - один байт
SHORT коротке ціле
LONG довге ціле
DOUBLE плаваюче з подвійною точністю
Розміри цих об'єктів теж машинно-незалежні; деталі
наведені у розділі 2. Є також масиви, структури та об-
'едіненія цих основних типів, покажчики на них і функ-
ції, які їх повертають; з усіма ними ми зустрінемося в
свій час.
Фактично обчислення в програмі перекладу температур
починаються з операторів присвоювання
LOWER = 0;
UPPER = 300;
STEP = 20;
FAHR = LOWER;
які надають змінним їх початкові значення. кожен зо-
ділову оператор закінчується крапкою з комою.
Кожен рядок таблиці обчислюється однаковим чином,
так що ми використовуємо цикл, що повторюється один раз на будів-
ку. У цьому призначення оператора WHILE:
WHILE (FAHR
....< br />
)
* 16 -
перевіряється умова у дужках. Якщо воно істинно
(FAHR менше або рівне UPPER), то виконується тіло циклу
(всі оператори, укладені у фігурні дужки (і)). Потім
знову перевіряється ця умова і, якщо воно істинно, знову ви-
виконується тіло?? ікла. Якщо ж умова не виконується (FAHR
перевершує UPPER), цикл закінчується і відбувається перехід
до виконання оператора, наступного за оператором циклу. Так
як в цій програмі немає жодних подальших операторами
рів, то виконання програми завершується.
Тіло оператора WHILE може складатися з одного або більше
операторів, укладених у фігурні дужки, як у програмі
перекладу температур, або з одного оператора без дужок,
як, наприклад, в
WHILE (I
I = 2 * I;
В обох випадках оператори, керовані оператором WHILE,
зрушені на одну табуляцію, щоб ви могли з першого погляду
бачити, які оператори знаходяться всередині циклу. Такий зсув
підкреслює логічну структуру програми. Хоча в мові
"C" допускається цілком довільне розташування опера-
торів в рядку, що підходить зсув і використання прогалин
значно полегшують читання програм. Ми рекомендуємо писати
тільки один оператор на рядку і (звичайно) залишати пробіли
навколо операторів. Розташування фігурних дужок менш сущес-
ничих; ми вибрали один з декількох популярних стилів. Ви-
беріть відповідний для вас стиль і потім використовуйте його пос-
ледовательно.
Основна частина роботи виконується в тілі циклу. Темпера-
туру за Цельсієм обчислюється і присвоюється змінної
CELAIUS оператором
CELSIUS = (5.0/9.0) * (FAHR-32.0);
причина використання виразу 5.0/9.0 замість виглядає
простіше 5/9 полягає в тому, що в мові "C", як і в багатьох
гих інших мовах, при діленні цілих відбувається усікання,
що складається у відкиданні дробової частини результату. Таким об-
разом, результат операції 5/9 дорівнює нулю, і, звичайно, в цьому
випадку всі температури виявилися б рівними нулю. Десяткова
крапка в константі вказує, що вона має тип з плаваючою
точкою, так що, як ми й хотіли, 5.0/9.0 одно 0.5555 ... .
Ми також писали 32.0 замість 32, незважаючи на те, що так
як мінлива FAHR має тип FLOAT, ціле 32 автоматично
б перетворилося до типу FLOAT (у 32.0) перед вирахуванням.
З точки зору стилю розумно писати плаваючі константи з
явною десяткового точкою навіть тоді, коли вони мають цілі
значення, підкреслює їх плаваючу природу для просмат-
Ріва програму і забезпечує те, що компілятор буде
дивитися на речі так само, як і Ви.
* 17 -
Докладні правила про те, в якому випадку цілі перетворення
ються до типу з плаваюшей точкою, наведені в розділі 2. Зараз
ж відзначимо, що присвоювання
FAHR = LOWER;
перевірка
WHILE (FAHR
працюють, як очікується, - перед виконанням операцій цілі
перетворюються на плаваючу форму.
Цей же приклад повідомляє трохи більше про те, як працює
PRINTF. Функція PRINTF фактично є універсальною
функцією форматних перетворень, яка буде повністю
описана в розділі 7. Її першим аргументом є рядок сім-
волів, яка має бути надрукована, причому кожен знак%
вказує, куди повинен підставлятися кожен з інших