p>
void p>
main () p>
(unsigned long int i; p>
p>
int p>
ar [10000]; p>
p>
time_t t, t2; p>
p>
t = time (NULL); p>
p>
randomize (); p>
// Багаторазове
привласнення випадкового елементу випадкового значення p>
p>
for (i = 1; i <429496; i + +) p>
ar [random (1000)] = random (32767); p>
// Багаторазове
заповнення p>
p>
масиву числом
2 p>
for (i = 1; i <429496; i + +) p>
ar [i% (1000)] = 2; p>
p>
t2 = time (NULL); p>
p>
printf ( "Час
виконання =% d ", t2 - t); p>
) p>
Як видно,
програма дуже інтенсивно працює з масивом і контроль за вихід кордонів
масиву повинен, імовірно, сповільнити роботу. Адже на кожне присвоєння
доводиться перевірка індексу масиву. p>
Висновки можуть
виявитися для кого - то несподіваними: p>
Версія на C не
показала більш високої швидкодії в порівнянні з Pascal версією. p>
швидкодії
Pascal версії при відключенні всіх перевірок збільшувалася на 7 - 8%. p>
Що цілком
логічно, тому що перевірка у процесорів 80x86 реалізуються на апаратному рівні. А
приріст у 7 - 8% може дати використання компілятора з гарною оптимізацією. p>
За даними
Дмитра Беленко, заснованим на проведеному їм експерименті, різниця між Delphi
і C + + Builder навіть обчислювальних завданнях становить 4 - 5%. p>
Зауважу що
існує і з спеціальний проект Cyclone. Його розробники - Корнельський
університет і AT & T. Мова фактично являє Сі з перевіркою
потенційно небезпечних ситуацій, таких як переповнення буферу. У дистрибутив
входить програма перетворення програм з Сі в Cyclone яка може відшукати
і знайти потенційно небезпечні місця програми. Основна мета розробників --
створити мову придатний для програмування безпечних додатків. p>
Після появи
і розповсюдження ООП левова частка З програмістів перейшли на С + +. У цьому (і
великому обсязі ПЗ вже написаному на С) я бачу одну з основних причин його
поширеності. p>
Відзначу що і C + + вплинув на C. Приміром enum
З отримав від С + +, і при програмуванні на С він практично не використовується,
однак було відзначено, що С містить таку конструкцію, оскільки вона є в
нині чинному стандарті мови. p>
У мові
з'явилися: p>
класи
(classes); p>
шаблони
(templates); p>
простору
імен (namespaces); p>
перевантаження
(overload); p>
потоки
(streams); p>
виключення
(exception) p>
ООП і
сучасні компілятори частково згладили недоліки С. З'явилися класи для
роботи з такими типами даних, як рядки і безлічі. У сумнівних (дивіться
приклад вище) ситуаціях компілятор (далеко не будь-який) може видати підказку. Для
кращої читабельності IDE автоматично вирівняє вихідний текст (Спочатку
цим займалася команда indent, яка існує і зараз у багатьох клонах
UNIX (в т.ч. Linux)). Спеціальні средства, наприклад, NuMega BoundsChecker
дозволяють відстежувати найбільш ймовірні помилки, такі, як вихід за межі
масиву або витік пам'яті. Програма lint (входить в Unix'и) займається
виключно ревізією вихідного тексту програми з приводу контролю типів. p>
Низька швидкість
компіляції в результаті відсутність повноцінного механізму модульності часто
компенсується механізмом попередньої компіляції заголовків файлів. p>
"Software engineering - мистецтво програмування без уміння це
робити " p>
Едсгар Дейкстра (Edsger Dijkstra) p>
"Використання C + + для розробки прикладного ПЗ та допоміжних
засобів для нейтралізації недоліків мови подібно до використання решета для
перенесення води і спеціальних засобів для замикання дір у решеті. " p>
Автор p>
Хоча С + +
частково згладив недоліки (просто прикривши їх своїми засобами, самі
недоліки нікуди не поділися) до нього він додав і свої: p>
Головний --
надмірне складність і розмір мови (це ріднить його з Адою, хоча складність Ади
викликана різноманітністю засобів, а не їх дублюванням). Навіть реалізація ООП
інтенсивної піддається критиці. Я для прикладу розгляну множинне
спадкування. Саме питання про необхідність включення множинного спадкоємства
в мову є досить спірним. Зокрема стоїть проблема наявності однойменних
методів у батьків класу. Виникає питання: що викликати? Перший-ліпший?
Чи все по черзі? На практиці це вирішується написанням в нового класу
методу, який безпосередньо реалізує потрібну логіку, щоправда тоді виникає
питання про адекватності самого множинного спадкоємства. Адже його зміст у
автоматичному виклику методів (та доступ до полів) класів предків. Якщо ж
розробнику доводиться вказувати конкретний клас - предок, то множина
спадкоємство в значній мірі втрачає сенс. Залишаються лише такі зокрема
як можливість звернення до protected елементів класів предків, але
відповідна модифікація програми це не проблема. Реалізацію
множинного спадкоємства теж не можна назвати тривіальним справою, вона
значно складніше реалізації "одиничного успадкування". p>
Велика
надмірність засобів - тобто для вирішення однієї задачі я можу використовувати
велику кількість ідентичних коштів. p>
До речі, багато
засоби мови, які, на думку його прихильників, з'явилися в C + +, були запозичені
з інших мов. Наприклад, аналог шаблонів - пакети - були в пеклі до створення
C + +. Обробка виняткових ситуацій присутній у пекло і навіть у
PL/1.Перезагрузка операцій також була присутня в пеклі. p>
Величезна різноманітність засобів, які
дублюють один одного, подобається багатьом шанувальникам C + +. Вони вважають, що це
робить мову більш зручним для використання. Вважати так-це їхнє право. Ймовірно,
для кого-то це дійсно так. p>
Наведу
авторитетна думка Кена Томпсона (одного з розробників C і Unix): p>
"При роботі з мовами C + + і Java в мене виникало певне
занепокоєння, коли я просив зробити що - небудь, а у відповідь отримував: "Добре,
ви робите це так - то чи можете зробити так - то ". Цілком очевидно,
якщо ви в змозі зробити що - то настільки різноманітними способами і всі ці
способи не менш еквівалентні, значить в системі закладено занадто багато
можливостей. " p>
C теж надмірний. Приклад циклу без тіла:
for (a = 1, b = 70; a <50; ar [a + +] = a + b, b -). По суті тут for виконує роль while. p>
Як зазначив У.
Вульф, "Факт наявності тих чи інших можливостей у деякому ЯП не може
служити критерієм для оцінки цієї мови. Великий набір хороших самих по собі
можливостей, зібраних воєдино без загальної ідеї, без певного однаковості
і без елегантності, не призводить до появи хорошого ЯП. " p>
Засоби
підтримки сумісності з С.С одного боку це великий плюс (дуже багато ПЗ
написано на C), з іншого, для об'єктно - орієнтованого програмування вони
не потрібні. p>
Приклад:
введення класів (при їх використанні) робить непотрібним записи (struct) і
варіантні записи (union), проте з міркувань сумісності вони
присутні. p>
С + + є
надмножеством C, тобто якась Високорівнева оболонка до мови системного
програмування. Але база для цієї оболонки все та ж - C. p>
Приміром, додані
класи для роботи з рядками, але самі рядки реалізовані через покажчики.
Звичайно, тут є і плюс-широта засобів мови. Але вона не компенсує
що вийшла громіздкість. p>
Макросредства
асемблером теж є високорівневої оболонкою і дозволяють використовувати
конструкції, характерні для ЯПВУ (типу циклів) у програмах на асемблері.
Зауважу, що і на макросредствах асемблера без використання безпосередньо
команд процесора можна створювати досить складні системи. Але це не робить
Асемблер мовою високого рівня. p>
"Писати погані програми на С + + значно легше, ніж
хороші. " p>
Загальновизнаний факт. p>
Громіздкість
С + + Б'ярне Страуструп пояснює наступним чином: p>
"Отже,
універсальна мова програмування повинна підтримувати різні способи
мислення та стилі програмування. Ця різноманітність є наслідком, як
різнорідності розв'язуваних задач, так і різноманіття шляхів їх вирішення. C + +
підтримує широкий спектр стилів програмування і тому більш заслуговує
назва мультипарадигмова, ніж об'єктно - орієнтованого мови ... p>
Мені
видається, що мови, що спираються на яку - або одну
парадигму, обмежують свободу програміста. Платою за простоту виявляється
гамівна сорочка, що сковує інтелект розробника .. " p>
Тобто
виходить, якщо різні розробники використовують різні стилі
програмування, то повну підтримку всіх стилів потрібно включати в мову. p>
Продовжуючи ідею,
зауважу - для вирішення різних завдань необхідні різні алгоритми. Тому в STL
необхідно включити алгоритми рішення задач з усіх областей людської
діяльності, де використовується мова C + +! p>
А в різних ОС
інтерфейси розробника істотно відрізняються (порівняйте Win32 API і POSIX). Це
теж необхідно відобразити в мові.!!! p>
Страуструп
нещодавно в інтерв'ю висловився за включення в мову засобів розробки баз даних
і інтерфейсу користувача (як в Java). Звичайно, включити все, що буває в ЯП
в одну мову - ідея гарна, але Вам вона нічого не нагадує? Згадайте долю
"грандіозного проекту всіх часів і народів - мови АДА". Питання про
кордоні, де закінчуються засоби мови і починаються інші засоби, порушено у
розділі "Про маленьких і великих мовах". p>
І останнє --
що б не писав Страуструп, факт залишається фактом. C + + повністю практично
ніколи і ніким не застосовується. Використовуються лише обмежені підмножини
мови, що підтримують певний стиль розробки. Як він сам зауважив,
"Для того, щоб писати гарні програми на C + +, необов'язково знати його
повністю " p>
У принципі, люди від природних мов беруть
лише дуже невелику частину. Але в програмуванні такий підхід може мати
великі негативні наслідки. Наприклад, може з'явитися необхідність
модифікації програмного коду написаного одним розробником, що використовує 20
% Мови іншим, що використовують інші 20% мови (іншу частину). p>
С + + увібрав у
себе кошти для підтримки дуже широкого спектру технологій розробки і стилів
програмування. На ньому можна розробляти з майже однаковою
[не] успішністю, використовуючи і лінійне, і об'єктно - орієнтоване
програмування. p>
Лінійне програмування - архаїчний спосіб
розробки програм без використання таких структур мови, як цикли. Зате
інтенсивно використовується оператор GO TO. Був витіснений структурним
програмуванням. p>
Власною
ідеології мова не має. Підтримується безліч парадигм. Розробник повинен
вибрати те, що необхідно особисто йому, а про решту він може спокійно забути. p>
Навіть рівень
мови однозначно визначити неможливо. Він підтримує як низькорівневі
структури даних (бітові поля) і методи програмування (адресна арифметика),
так і високорівневі структури даних (