Завдяки чому склався такий статус мови З? Історично ця мова невіддільний від операційної системи Unix, яка в наші дні переживає своє друге народження. 60-і роки були епохою становлення операційних систем і мов програмування високого рівня. У той період для кожного типу комп'ютерів незалежно розроблялися ОС і компілятори, а нерідко навіть свої мови програмування (згадаємо, наприклад, PL / I). У той же час, спільність виникають при цьому проблем вже стала очевидною. Відповіддю на усвідомлення цієї спільності стала спроба створити універсальну мобільну операційну систему, а для цього знадобився не менше універсальний і мобільний мову програмування. Такою мовою став З, а Unix стала першою ОС, практично повністю написаною на мові високого рівня.
Тісний зв'язок з Unix дала мови З такий полігон для обкатки, якого не було в той час ні у одного іншої мови. Завдання системного програмування по праву вважалися в той час найскладнішими в галузі. Здебільшого вони були настільки машинно-залежними, що багато хто взагалі не мислили їх рішення інакше, ніж на асемблері. Мови високого рівня призначалися для прикладного програмування і лише дуже обмежено реалізовували функції, необхідні для системних робіт, причому найчастіше тільки для певного типу машин.
Мова С з самого початку створювався так, щоб на ньому можна було писати системні завдання. Творці С не стали розробляти абстрактну модель виконавця мови, а просто реалізували в ньому ті можливості, в яких найбільше потребували практиці системного програмування. Це в першу чергу були кошти безпосередньої роботи з пам'яттю, структурні конструкції управління і модульна організація програми. І по суті більше нічого в мову включено не було. Все інше було віднесено до бібліотеки часу виконання. Тому недоброзичливці інший раз відгукуються про мову С як про структурний асемблері. Але що б вони не базікали, підхід виявився дуже вдалим. Завдяки йому був досягнутий новий рівень по співвідношенню простоти і можливостей мови.
Є, втім, ще один фактор, який визначив успіх мови. Творці дуже вміло розділили в ньому машинно-залежні і незалежні властивості. Завдяки цьому більшість програм вдається писати універсально - їх працездатність не залежить від архітектури процесора і пам'яті. Нечисленні ж апаратно-залежні частини коду можна локалізувати в окремих модулях. А користуючись препроцесором, можна створювати такі модулі, які при компіляції на різних платформах будуть породжувати відповідний машинно-залежний код.
Багато суперечок викликав синтаксис мови С. Застосовані в ньому прийоми скорочення запису при надмірному використанні можуть зробити програму абсолютно нечитаною. Але, як говорив Дейкстра, - кошти не винні в тому, що їх безграмотно використовують. Насправді ж, запропоновані в С скорочення синтаксису відповідають найбільш часто зустрічається на практиці стереотипним ситуаціям. Якщо вважати скорочення ідіомами для виразного і компактного представлення таких ситуацій, то користь від них стає безумовною і очевидною.
Отже, С виник як універсальна мова системного програмування. Але він не залишився в цих рамках. До кінця 80-х років мова З, відтіснивши Fortran з позиції лідера, завоював масову популярність серед програмістів в усьому світі і став використовуватися в самих різних прикладних задачах. Чималу роль тут зіграло поширення Unix (а значить і С) в університетському середовищі, де проходило підготовку нове покоління програмістів.
Як і всі мови, С поступово вдосконалювався, але більшість удосконалень не носило радикального характеру. Найбільш істотним з них, мабуть, слід вважати введення суворої специфікації типів функцій, яка значно підвищила надійність межмодульного взаємодії на С. Все такі удосконалення були в 1989 році закріплені в стандарті ANSI який і понині визначає мову С.
Перші спроби виправити ці недоліки стали робитися ще на початку 80-х років. Уже тоді Бйорн Страуструп в ATT Bell Labs став розробляти розширення мови С під умовною назвою. Стиль ведення розробки цілком відповідав духу, в якому створювався і сама мова С, - в нього вводилися ті чи інші можливості з метою зробити більш зручною роботу конкретних людей і груп. Перший комерційний транслятор нової мови, який отримав назву C ++ з'явився в 1983 році. Він був препроцесором, який транслював програму в код на С. Однак фактичним народженням мови можна вважати вихід в 1985 році книги Страуструпа
Саме з цього моменту C ++ починає набирати усесвітню популярність.
Головне нововведення C ++ - механізм класів, що дає можливість визначати і використовувати нові типи даних. Програміст описує внутрішнє уявлення об'єкта класу і набір функцій-методів для доступу до цієї вистави. Однією із заповітних цілей при створенні C ++ було прагнення збільшити відсоток повторного використання вже написаного коду. Концепція класів пропонувала для цього механізм успадкування. Спадкування дозволяє створювати нові (похідні) класи з розширеним уявленням і модифікованими методами, не зачіпаючи при цьому скомпільований код вихідних (базових) класів. Разом з тим спадкування забезпечує один з механізмів реалізації поліморфізму - базової концепції об'єктно-орієнтованого програмування, згідно з якою, для виконання однотипної обробки різних типів даних може використовуватися один і той же код. Власне, поліморфізм - теж один з методів забезпечення повторного використання коду.
Введення класів не вичерпує всіх новацій мови C ++. У ньому реалізовані повноцінний механізм структурної обробки виключень, відсутність якого в С значно ускладнювало написання надійних програм, механізм шаблонів - витончений механізм макрогенерації, глибоко вбудований в мову, відкриває ще один шлях до повторної використовуваного коду, і багато іншого.
Все це призвело до того, що багато розробників змушені були самі досліджувати лабіринти мовної семантики і самостійно відшукувати успішно працюють ідіоми. Так, наприклад, на першому етапі розвитку мови багато творців бібліотек класів прагнули побудувати єдину ієрархію класів із загальним базовим класом Object. Ця ідея була запозичена з Smalltalk - одного з найбільш відомих об'єктно-орієнтованих мов. Однак вона виявилася абсолютно нежиттєздатною в C ++ - ретельно продумані ієрархії бібліотек класів виявлялися негнучкими, а робота класів - неочевидній. Для того щоб бібліотеками класів можна було користуватися, їх доводилося поставляти в початкових текстах.
Поява темплетний класів і зовсім спростувало цей напрям розвитку. Успадкуванням стали користуватися тільки в тих випадках, коли потрібно породження спеціалізованої версії наявного класу. Бібліотеки стали складатися з окремих класів і невеликих незв'язаних між собою ієрархій. Однак на цьому шляху стало знижуватися повторне використання коду, так як в C ++ неможливо полиморфное використання класів з незалежних ієрархій. Повсюдне ж застосування темплетов веде до неприпустимого зростання обсягу скомпільованої коду - не будемо забувати, темплети реалізуються методами макрогенерації.
Один із найважчих недоліків C ++, успадкований ним від синтаксису З, полягає в доступності компілятору опису внутрішньої структури всіх використаних класів. Як наслідок, зміна внутрішньої структури представлення якого-небудь бібліотечного класу призводить до необхідності перекомпіляції всіх програм, де ця бібліотека використовується. Це сильно обмежує розробників бібліотек в частині їх модернізації, адже, випускаючи нову версію, вони повинні зберігати двійкову сумісність з попередньою. Саме ця проблема змушує багатьох фахівців вважати, що C ++ непридатний для ведення великих і надвеликих проектів.
І все ж, незважаючи на перераховані недоліки і навіть на неготовність стандарту мови (це після п'ятнадцяти з гаком років використання!), C ++ залишається одним з найбільш популярних мов програмування. Його сила насамперед в практично повній сумісності з мовою С. Завдяки цьому програмістам C ++ доступні всі напрацювання, виконані на С. При цьому C ++ навіть без використання класів привносить в З ряд настільки важливих додаткових можливостей і зручностей, що багато хто користується їм просто як поліпшеним З .
Що стосується об'єктної моделі C ++, то поки ваша програма не стала дуже великий (сотні тисяч рядків), нею цілком можна користуватися. Намітилася останнім часом тенденція переходу до компонентного програмного забезпечення тільки підсилює позиції C ++. При розробці окремо взятих компонентів недоліки C ++ ще не виявляються, а зв'язування компонентів в працюючу систему проводиться вже не на рівні мови, а на рівні операційної системи.
У світлі всього сказаного перспективи C ++ не виглядають похмурими. Хоча і монополія на ринку мов програмування йому не світить. Мабуть, з упевненістю можна стверджувати лише те, що ще однією модернізації-розширення ця мова не переживе. Недарма, коли з'явилася Java, на неї звернули таку пильну увагу. Мова, близький по синтаксису до C ++, а значить, здається знайомим багатьом програмістам, був позбавлений від найбільш кричущих недоліків C ++, успадкованих їм з 70-х років. Однак не схоже, щоб Java справлялася з покладеної на неї деякими роллю.
Для того, щоб наочно продемонструвати використання описаних мов на практиці нами була обрана задача, в якій потрібно ввести зі стандартного вводу або з файлу ряд цілих чисел, а потім вивести тільки непарні з них, причому в зворотному порядку проходження. Це одна з найпростіших завдань, яка істотно вимагає для свого рішення роботи з масивами, циклами, розгалуженням і в / в, а також дозволяє продемонструвати виклики підпрограм. При цьому вона доступна для огляду і легко сприймається.