Зміст.
Анотація
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".
Анотація. Мова "C" (вимовляється "сі") - це універсальна мова програмування,
для якого характерні економічність вирази, сучасний потік управління
і структури даних, багатий набір операторів. Мова "C" не є ні мовою "дуже
високого рівня ", ні" великим "мовою, і не призначається для деякої
спеціальної області застосування. але відсутність обмежень і спільність мови роблять
його більш зручним і ефективним для багатьох завдань, ніж мови, імовірно
більш потужні. Мова "C", що спочатку призначався для написання операційної
системи "UNIX" на ЕОМ DEC PDP-11, був розроблений і реалізований на цій системі
Деннісом Річі. Операційна система, компілятор з мови "C" і по суті
всі прикладні програми системи "UNIX" (включаючи все програмне забезпечення, використане
при підготовці цієї книги) написані на "C". Комерційні компілятори
з мови "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 TABLEFOR F = 0, 20, ...,
300 */MAIN () (INT LOWER, UPPER, STEP; FLOAT FAHR, CELSIUS; LOWER = 0;/* LOWER
LIMIT OF TEMPERATURETABLE */UPPER = 300;/* UPPER LIMIT */STEP = 20;/* STEP SIZE
*/FAHR = LOWER; WHILE (FAHR = '0 '& C = '0' & C = '0 '& C 0 */INT X, N; (INT I,
P; P = 1; FOR (I = 1; I 0; VERSION 2 */INT X, N; (INT P; FOR (P = 1; N> 0; - N) P = P
* X; RETURN (P);) Аргумент N використовується як тимчасова мінлива; з не-го віднімається
одиниця до тих пір, поки він не стане нулем.Переменная I тут більше
не потрібна. щоб не відбувалося з Nвнутрі POWER це ніяк не впливає на аргумент,
з яким пер-воначально звернулися до функції POWER.Прі необхідності все-таки
можна домогтися, щоб функціяізменіла змінну з викликає програми. Ця программадолжна
забезпечити встановлення адреси змінної/технічни-ки, через покажчик
на змінну /, а в викликається функціінадо описати відповідний аргумент
як покажчик і ссы-латься до фактичної змінної опосередковано через нього. Ми
рас-дивимося це докладно у розділі 5.Когда як аргумент виступає ім'я масиву,
тофактіческім значенням, що передаються функції, є адресначала масиву.
/ Тут немає ніякого копіювання елементовмассіва /. За допомогою індексації і
адреси початку функція можетнайті і змінити будь-який елемент масиву. Це - тема
Наст-го розділу. * 32 - 1.9. Масиви символів. Мабуть найбільш загальним типом
масиву в "C" являетсямассів символів. Щоб проілюструвати використання
мас-сівов символів і обробляють їх функцій, давайте напішемпрограмму, яка
читає набір рядків і друкує саму довжин-ву з них. Основна схема програми
досить проста: WHILE (є ще рядок) IF (цей рядок довший найдовшою
ізпредидущіх) запам'ятати цей рядок і її длінунапечатать найдовшу строкуПо
цією схемою ясно, що програма природним образомраспадается на кілька
частин. Одна частина читає новуюстроку, інша перевіряє її, третій запам'ятовує,
а остальниечасті програми керують цим процессом.Поскольку все так прекрасно
ділиться, було б добре інапісать програму відповідним чином. Давайте сначаланапішем
окрему функцію GETLINE, яка буде ізвлекатьследующую рядок
з файлу вводу; це - узагальнення функцііGETCHAR. ми спробуємо зробити цю функцію
по возможностіболее гнучкою, щоб вона була корисною і в інших сітуаціях.Как
мінімум GETLINE повинна передавати сигнал про можливе по-явище кінця файлу;
більш загальний корисний варіант міг би пе-редавать довжину рядка або нуль, якщо зустрінеться
кінець файла.нуль не може бути довжиною рядка, тому що кожен рядок з-тримає
принаймні один символ; навіть рядок, содержащаятолько символ нової
рядка, має довжину 1.Коли ми знаходимо рядок, який довше самої дліннойіз
попередніх, то її треба десь запам'ятати. Це наводить Намислов про іншу функції,
COPY, яка буде копіювати но-ву рядок в місце храненія.Наконец, нам потрібна
основна програма для управленіяфункціямі GETLINE і COPY. Ось результат: # DEFINE
MAXLINE 1000/* MAXIMUM INPUTLINE SIZE */MAIN ()/* FIND LONGEST LINE */
(INT LEN;/* CURRENT LINE LENGTH */INT MAX;/* MAXIMUM LENGTH SEEN SO FAR */CHAR
LINE [MAXLINE];/* CURRENT INPUT LINE */CHAR SAVE [MAXLINE];/* LONGEST LINE,
SAVED */MAX = 0; WHILE ((LEN = GETLINE (LINE, MAXLINE))> 0) IF (LEN> MAX) (MAX
= LEN; COPY (LINE, SAVE);) IF (MAX> 0)/* THERE WAS A LINE */PRINTF ( "% S", SAVE);
) * 33 - GETLINE (S, LIM)/* GET LINE INTO S, RETURN LENGTH */CHAR S []; INT LIM;
(INT C, I; FOR (I = 0; I 0) IF (LEN> MAX) (MAX = LEN; COPY ();) IF (MAX> 0)/* THERE
WAS A LINE */PRINTF ( "% S", SAVE);) GETLINE ()/* SPECIALIZED VERSION */(INT
C, I; EXTERN CHAR LINE []; FOR (I = 0; I> == '0 '& S [I] =' A '& C J, ілогіческіе вирази,
пов'язані операціями & і!!, за оп-ределенію мають значення 1, якщо
вони істинні, і 0, якщо оніложни. Таким чином, надання ISDIGIT = C> = '0 '
& C> зсув вправо ^ доповнення (унарний операція) "" іммітірует вертикальну
черту.Побітовая операція AND часто використовується для маскірованіянекоторого безлічі
бітів; наприклад, оператор C = N 0177 * 52 - передає в 'з' сім молодших
бітів N, вважаючи інші рав-ними нулю. Операція 'е.' побітового OR використовується
для вклю-чення бітів: C = X е. MASKустанавлівает на одиницю ті біти в х, які
рівна одиниці MASK.Следует бути уважним і відрізняти побітового операції
'е.' від логічних зв'язок & і!! , Які подразуме-вають обчислення значення
істинності зліва направо. Наприклад, якщо х = 1, а Y = 2, то значення хYравно нулю
, У той час какзначеніе X & Yравно едініце./чому?/Операції зсуву> здійснюють
соответственносдвіг вліво і вправо свого лівого операнда на число бітовихпозіцій,
задаються правим операндом. Таким чином, г> (P +1- N)) ^ (^ 0> (P +1- N)
зрушує бажане поле в правий конецслова. Опис аргументу X як UNSIGNED
гарантує, чтопрі зсуві вправо що звільняються біти будуть заповнюватися ну-лями,
а не вмістом знакового біта, незалежно від того, жодних машині пропускається
програма. Всі біти константноговираженія ^ 0 рівні 1; зсув його на N позицій
вліво з по-міццю операції ^ 0> ^! Якщо е1 та е2 - вирази, то * 54 -
е1 оп = е2еквівалентное1 = (е1) оп (е2) за винятком того, що вираз е1 обчислюється
толькоодін раз. Зверніть увагу на круглі дужки навколо е2: X *= Y +
1тоX = X * (Y + 1) неX = X * Y + 1В Як приклад наведемо функцію BITCOUNT,
котораю підраховує кількість рівних 1 бітів у цілого аргументу. BITCOUNT (N)/* COUNT
1 BITS IN N */UNSIGNED N; (INT B; FOR (B = 0; N! = 0; N>> = 1) IF (N 01) B + +; RETURN (B);
) Не кажучи вже про стислості, такі оператори пріваіваніяімеют ту перевагу,
що вони краще відповідають образучеловеческого мислення. Ми говоримо:
"Додати 2 до I" або "збільшити I на 2", але не "взяти I, додати 2 і поместітьрезультат
знову в I ". Отже, I + = 2. Крім того, в громоздкіхвираженіях, подібних
YYVAL [YYPV [P3 + P4] + YYPV [P1 + P2]] + = 2Tакая операція привласнення полегшує
розуміння програми, тому що читач не повинен скрупульозно перевіряти, являютсялі
два довгих вирази дійсно однаковими, або за-думиваться, чому вони
не збігаються. Така операція присвоюються-вання може навіть допомогти компілятору отримати
більш ефектив-ву программу.Ми вже використали той факт, що операція прісваіваніяімеет
деяке значення і може входити до вираження; самийтіпічний
приклад * 55 - WHILE ((C = GETCHAR ())! = EOF) привласнення, що використовують інші операції
присвоювання (+=,-= і т.д.) також можуть входити до вираження, хоча це випад-ється
реже.Тіпом вирази привласнення є тип його левогооперанда.Упражненіе
2-9.В двійковій системі числення операція X (X-1) обнуляетсамий правий рівний
1 біт змінної X. (чому?) Іспользуйтеето зауваження для написання більш
швидкої версії функцііBITCOUNT. 2.11. Умовні вирази. ОператориIF (A> B) Z
= A; ELSEZ = B; звичайно обчислюють у Z максимум з а і в. Умовне вираз, записане
за допомогою тернарной операції "?:", предоставляетдругую можливість для запису
цієї та аналогічних конструк-цій. У виразі е1? Е2: е3сначала обчислюється
вираз е1. Якщо воно відмінно від нуля (істинно), то обчислюється вираз е2,
яке і становітсязначеніем умовного виразу. В іншому випадку обчислює-ся
е3, і воно стає значенням умовного виразу. Каж-дий раз обчислюється
тільки одне з вираження е2 і е3. Такімобразом, щоб покласти Z рівним максимуму
з а і в, можнонапісать Z = (A> B)? A: B;/* Z = MAX (A, B) */Слід підкреслити,
що умовне вираження дійсними-но є вираженням і може використовуватися
точно так само, як будь-який інший вираз. Якщо е2 і е3 мають різні
типи, то тип результату визначається за правилами перетворення, розглянутим раніше
в цьому розділі. наприклад, якщо F має тіпFLOAT, а N - тип INT, то вираз
(N> 0)? F: NІмеет тип DOUBLE незалежно від того, позитивно чи N ілінет.
* 56 - Так як рівень старшинства операції?: Дуже низький, прямо над присвоюванням,
то перше вираження в умовному ви-раженіі можна не укладати в круглі дужки.
Проте, ми все ж рекомендуємо це робити, так як дужки роблять условнуючасть
вираження більш заметной.Іспользованіе умовних виразів часто призводить до корот-ким
програмами. Наприклад, наступний нижче оператор циклу пе-чату N елементів
масиву, по 10 у рядку, розділяючи каждийстолбец одним пропуском і закінчуючи
кожний рядок (включаяпоследнюю) одним символом переведення рядка. OR (I = 0; I
. LEFT TO RIGHT! ^ + + - - (TYPE)