"Ох волна моя, волна, ты как С++ мощна"
Почти Пушкин
Касательно мощности C/С++.Да, действительно это очень мощные языки ,но их мощность заключается в их средствах низкого уровня,а они при разработке прикладных программ часто неприменимы.
Мощность - это, конечно, хорошо,но часто опасно.
Пример: #define int long синтаксически верно, РЅРѕ может привести Рє катастрафическим последствиям (хотя, Рє примеру, РїСЂРё переносе программ СЃ РѕРґРЅРѕР№ платформу РЅР° РґСЂСѓРіСѓСЋ это может понадобиться). Рли оператор goto. РўРѕ, что РѕРЅ РЅРµ включен РІ Java, РјРЅРѕРіРёРµ считают очень большим благом. Goto - это мощная возможность, РЅРѕ, как показал еще РІ семидесятых годах Дейкстра, РјСЏРіРєРѕ РіРѕРІРѕСЂСЏ, "РЅРµ рекомендованная" Рє использованию. Тем РЅРµ менее это возможность, Рё РѕРЅР° может быть РЅРµ лишней. РЇ считаю, что подобные низкоуровневые конструкции должны присутствовать, РЅРѕ РёРјРё РЅРµ следует злоупотреблять. Р’ тех редких случаях, РєРѕРіРґР° лично СЏ его использовал, это была попытка развития плохоспроектированной программы.
"Чтобы сделать карьеру программиста за границей нужно знать два языка: английский и C++"
Российский аспирант, побывавший в Вене.
"РЎ точки зрения теоретического программирования язык СЃРё - это Фортран 80 - ых. (Против такого уничижительного определения РЅРµ возражал Рё автор языка РЎРё - Р”. Ритчи). Ртот язык, сочетающий РІ себе РјРЅРѕРіРёРµ преимущества языка высокого СѓСЂРѕРІРЅСЏ Рё ассемблера, дал программистам, РїРѕ образному выражению некоторых, педаль газа, РЅРѕ заблокировал педаль тормоза. РќР° РЎРё компьютер может "мчаться" быстро, РЅРѕ рискованно. РўРѕ есть РЎРё, насаждая ссылочно - ассемблерное программирование, как Р±С‹ имеет вектор РІ сторону, противоположную той, которая определяется теорией Рё методологией языков программирования.
Поэтому и Си++ - это довольно странное сочетание некоторых черт ООП (здесь и далее - объектно - ориентированное программирование) и процедурного программирования"
К.Т.Н. Соловьев А.Е.
"Cи++ представляет собой интересный эксперимент по адаптации возможностей объектной технологии к традиционному языку программирования. ... поскольку Си++ - язык, требующий весьма интенсивной критики. Он представляет собой не слишком удачную реализацию объектно - ориентированной технологии, и поэтому его недостатки просто необходимо подвергать критическому анализу... Си++ приносит всем колоссальное разочарование - он вобрал в себя все плохие и старые средства, а также привнес в объектную технологию абсолютно ненужную сложность. Зачем нужен язык, насквозь пропитанный низкоуровневыми конструкциями? ".
Ян Джойнер
 Далее РїРѕ тексту "Наиболее верный путь Рє успеху - использование чистого объектно - ориентированного языка, обладающего интерфейсом СЃ языком CРё или СЃ РґСЂСѓРіРёРјРё низкоуровневыми языками. Рто обеспечит хорошие поддержку Рё сопровождение, переносимость Рё качество", что РІ принципе можно наблюдать РЅР° примере любого средства 4GL(того же Delphi) поддерживающего стандартные средства взаимодействия Windows такие как Dll,Dde, Ole. Простейший пример - обращение РёР· Delphi программы Рє Win API(ведь Windows написан РЅР° РЎРё(9X) Рё C++(NT)).
Рзначально созданный для разработки РћРЎ Unix, язык C получил широкое распространение. Рто наложило очень сильный отпечаток РЅР° язык.
Как возник язык С? Вначале был CPL: он был создан в середине 60 - х годов.
Язык не получил широкого распространения, но в процессе его создания появилась масса идей. Язык был беcтиповый, как и положено ассемблеру (ещё PDP 7).
Новая упрощенная версия языка называлась Basic CPL или BCPL. На нем была реализована MULTICS. Но в результате ее размеров и раздутости ей потребовалась замена.
 Часть идей из MULTICS была взята разработчиками Unix. К примеру, иерархическая файловая система. Замечу, что в прямом предшественнике DOS-CP/M её не было, как и в первой версии DOS.
Доработали язык - получился B.
Разработали ОС - получилась Unix
Си разрабатывался как Кроссплатформенный ассемблер PDP 11 (многие опытные программисты знают его по отечественным аналогам), является некоторой смесью ассемблера с Паскалем, этим обедняются многие его особенности.
К примеру:
Отсутствует возможность напрямую работать с данными, не поддерживающимися процессором PDP (множества, строки, etc).
Присутствие явно PDP - ориентированных конструкций:
Функция poly, сводящаяся к аналогичной команде ассемблера. Вычисление же полиномов не является задачей первостепенной важности языка.
Постинскремент и прединскремент. На x86, к примеру, это ничего не дает. РA=B++ и A:=B; inc(b); приведут к командам ассемблера MOV a,b; inc b (естественно, непосредственно в коде это будут не имена переменных, а, к примеру, регистры).
В " .. что аномалии существующих вычислительных машин старательно воспроизводятся РІ языках программирования, причем это РїСЂРѕРёСЃС…РѕРґРёС‚ РІ ущерб интеллектуальной управляемости программ, выражаемых РЅР° таком языке.." Р.Дейкстра. "Дисциплина программирования"
Вирт писал что : "...язык должен определяться в терминах математических, абстрактных концепций Ртолько, если язык удовлетворяет этому критерию, он может считаться высокоуровневым."
Рзменяющиеся РѕС‚ платформы Рє платформе размеры типов данных.
Строки, оканчивающиеся нулем, позаимствованные из ассемблера (директива .asciz ассемблера PDP)
Отсутствие автоматической либо обязательной инициализации переменных. Плюс такого подхода - большая оптимальность кода, минус - необходимость производить инициализацию вручную. Отсутствие автоматической инициализации является потенциальной возможностью для разработки ПО, содержащего неустойчивые ошибки (в идеале компилятор должен отслеживать не производится ли чтение не инициализированной переменной и в случае, если проводится, обнулять ее).
Наличие множества "подводных камней"
scanf("%d %d",&n,&ar[n]);
Вы думаете, что будет введено целое n и n - ный элемент масива ar ?
Рто очень маловероятно. Скорее всего, РІСЃРµ аргументы scanf Р±СѓРґСѓС‚ вычислены РґРѕ того, как операция будет вызвана РЅР° выполнение. Подобных побочных эффектов РІ языке масса.
Другая "особенность"
char
В
В str[50]="qwertyuio";
int a=3;str[++a]=str[++a]=' ';
cout
str[a++]=str[a++]=' ';
cout
Результат:
qwe tyuio
qwert uio
По логике вещей должны быть добавлены два пробела. Но у C своя логика, так что это не ошибка компилятора, а особенность языка.
int i=0,ar[2]={10,11};
i=ar[i++];// А кто сразу скажет чему равно значение i
Хотите еще ? Формат вывода зависящей от типа:
short int x=55;
printf("%d\n",x);
Если заменить short int на longt int, то придется менять и printf("%d\n",x) на printf("%D\n",x)
Пример: предположим, что вместо i
В
В for (i=0; i=100; i++)
Цикл будет выполняться вечно (вместо 101 раза) т.к.
Отсутствует логический тип данных.
Выраженние i=100 равно 100(т.е. по не ноль - истина).
Поскольку C включает в себя элементы не только процедурного, но и функционального программирования такая конструкция вполне правильна и логична.
В РџРѕ мере развития РІ C включалось РІСЃРµ больше возможностей Рзначально язык РЅРµ имел средств даже для описания констант. РљРѕРіРґР° РЎРё стал применяться для решения серьезных задач, Рє нему добавили так называемые "директивы препроцессора", такие, как #define Рё #include.
С помощью define стали определять константы и inline подпрограммы,
А с помощью #include был реализован, хоть и примитивный, механизм модульности. Популярность функционального программирования тоже сыграла свою роль. В языке появились конструкции из функциональных языков.
Конечно, у этой особенности есть и более достойное применение
if (СЃh=getchar()!=ESC)
{..}
 Обобщу, что такие средств хоть и удобны в использовании и позволяют писать разработчику "красивые" программы, не способствуют безопасности этих программ и совсем не считаются простотой языка. Так что "Красиво"- не всегда хорошо.
РР· РјРёРЅСѓСЃРѕРІ также следует отметить РЅРµ слишком читабельный синтаксис. Подумайте, что больше РіРѕРІРѕСЂРёС‚ end loop РІ АДЕ или "}" РІ C. Конечно, краткость - это хорошо, РЅРѕ платить Р·Р° нее такую цену....
Примеры:
Паскаль:
if Screen.Forms[I] is FormClass then begin
C++:
if (dynamic_cast(Screen - >Forms[I])){
A=(!CL&&!RC)?0 : (!LC?RC:LC)//"Очень понятное выражение"
*++* agrv //"Еще одно очень понятное выражение, при том синтаксически верное"
"Рнтуитивно понятный" синтаксис прекрасно подчеркивает следующий пример:
В
int i=5;
В
int *
const p3=&i;//Указатель константу
В
const int *
p3=&i;//Указатель на константу
 i=5;//Правильно
 *p3=5; Неверно! указатель на константу измененную в предыдущей строке.
char (*(*x2 ())[]) () //Срочно позовите криптоаналитика !!!
Рли работа СЃ перечислениями:
enum modes { LASTMODE , BW40 , C40, BW80, C80, MONO
} ;
В ..
В modes
e1=C80,e2;
В e1=e2*3;
//Очень осмысленный оператор на "ЯПВУ".
 //Ведь для "ЯПВУ" нет разницы, что int, что enum, что
bool
А что может значить, по Вашему мнению, команда a=24[ar]; ?
При условии, что int ar[50]; int a; она полностью эквивалентна a:=ar[24];
Как совершенно справедливо замечают поклонники C/C++ эти языки позволяют писать чрезвычайно краткие и выразительные программы. На счет краткости - безусловно.
А вот к какой выразительности может привести краткость, я сейчас покажу:
#include
#define Q r=R[*p++ - '0'];while(
#define B ;break;case
char*s="Qjou!s\\311^ - g\\311^ - n\\311^ - c\\::^ - q - ma%mO1JBHm%BQ - aP1J[O1HB%[Q
o)*|gps)
\ndbtf!aP2Q;m>aP2QaP4HC%T\
Qs\\q,,^>m,2aP4HC%SD12N1\nJNQm>s\\..q^aHC%NHb%GN1!D32P3%RN1UP1D12JPQUaP1H\
R%PN4\nQaP2Q,2aP4Hb%OD12D12N2!N3\nJVP3Q,,n\
\\(aP3Q(^*m>g\\(aP3Q(^
aP1Q*aHb%FN1\nQm>::::aHC%VP3Q>bupj)hfut)c**aHb%JD12JON1!Qjg)a%LN1UP1D12JIQUa\
P1HL%IQ*m>aN2!N2\nP2QP2Q>aN2\nP2Hbdd!b/d";int k;char R[4][99]
;main(c,v)char**v;{char*p,*r,*q;for(q=s;*q;q++)*q>' '&&(*q) - - ;{FILE*i=fopen(v
[1],"r"),*o=fopen(q - 3,"w");for(p=s;;p++)switch(*p++){B'M':Q(k=fgetc(i))!=EOF
&&k!=*p)*r++=k;if(k==EOF){fputs("}}\n",o);fclose(o);return system(q - 6);}*r=0
B'P':while(*p!='`')fputc(*p++,o)B'O':Q*r)fputc(*r++,o);p - - B'C':k=0;Q k
)(*r++=fgetc(i),k++);*r=0 B'I':k= *p;if(**R==k)goto G B'G':k= *p;G:p=s;while(
*p!='$'||p[1]!= k)p++;p++B'N':R[*p - '0'][0]++;}}}
Рта программа всего РІ 17 строчках текстового режима VGA(25X80) представляет СЃРѕР±РѕР№ полнофункциональный интерпретатор языка Basic, который поддерживает:
Переменные(имена от A до Z), которые инициализируются нулевыми значениями при запуске.
Цикл FOR var = exp TO exp ..NEXT var
Подпрограммы GOSUB exp и RETURN
Естественно, оператор GOTO(какой же Basic без GOTO)
Условия IF exp THEN exp
Комментарий REM any text
Оператор конец программы END
Присвоение var = exp
Р’РІРѕРґ INPUT variable
Рвывод PRINT string PRINT exp
Есть ли читатели, которые по - прежнему считают, что краткость - это всегда очень хорошо. А читабельность конструкций языка факт второстепенный ?
Р’ части ясности синтаксиса антиподом C/РЎ++ является язык АДА. Вместо бесконечных "}" пишется END LOOP, END IF, END CASE или END РРњРЇ_ПОДПРОГРАММЫ/ПАКЕТА. РЇ уже РЅРµ РіРѕРІРѕСЂСЋ, насколько "Переменная РўРРџРђ целый" читабельней чем "цел Переменная". Логично предположить, что платой Р·Р° краткость является читабельность программ, или платой Р·Р° читабельность программ является отсутствие краткости.
Хотя, что краткость в синтаксисе является сестрой таланта является крайне сомнительным. Отсутствие избыточности на уровне синтаксиса приходится компенсировать обильными комментариями (если, конечно, разработчик хочет иметь возможность разобраться в этом коде через пару месяцев).
Отмечу, что подобный синтаксис Microsoft положила в основу языка Visual Basic.
Ну и, конечно, отсутствие строгого контроля типов(хотя в этом есть и обратная сторона - в Pascal'е Вам придется для того, чтобы иметь возможность "прострелить себе ногу", явно указать на свое желание компилятору.
Распространенности C послужила:
Распространенность Unix.
Хорошее качество генерируемого кода. Особенно на PDP.
Достаточная "мощь" языка.
Сравнительная простота реализации компиляторов.
Краткость синтаксиса и его "красота" любима многими С/C++ - программистами, многие считают их чуть ли не основными преимуществами языка (то есть возможность написать ar[c++] вместо ar[c];inc(c) оказала большое влияние на популярность языка).
Широкие возможности разработки системного ПО(к примеру, адресная арифметика , битовые поля ). В этой низкоуровневости для многих разработчиков даже прикладного ПО есть некая прелесть, привлекающая к языку.
 Справедливости ради скажу, что именно такие низкоуровневые средства часто делают C/C++ более предпочтительным для задач системного программирования по сравнению с Паскалем(Правда, уже в Modula 2 появилась адресная арифметика).
Позже сам Керниган советовал разработчикам не использовать битовые поля, так как они "слишком платформозависимы".
Ртог - C хороший язык системного программирования, кроссассемблер, позволяющий очень эффективно использовать PDP, РЅРµ очень хорошо РїРѕРґС…РѕРґРёС‚ для разработки прикладного РџРћ. Замечу также, что некоторые разработчики "забавы ради" занижают уровень выбираемого для разработки языка(смотрите главу Рѕ человеческом факторе).
Перед разработчиками C стояла задача создать язык, обладающий преимуществами и ассемблера и ЯПВУ. С задачей они, в принципе, справились хорошо: правда, с плюсами оных были добавлены и их минусы.
C да и C++ не были и не будут безопасными языками, поскольку один из приоритетов этих языков - эффективность. Поэтому Страуструп не включил в C++ динамическую проверку типов. Как гласит базовый принцип ЯП, эффективность и безопасность несовместимы. Да и потери в эффективности не столь значительны для большинства задач.
Да и потеря не столь велика. Я провел небольшой эксперимент со следующей программой и её аналогом на Pacal.
#include
#include
#include
void
main()
{ unsigned long int i;
В
int
ar[10000];
В
time_t t,t2;
В
t = time(NULL);
В
В randomize();
//Многократное присвоение случайному элементу случайного значения
В
for (i=1;i
В ar[random(1000)]=random (32767);
//Многократное заполнение
В
массива числом 2
for (i=1;i
В ar[i%(1000)]=2;
В
t2 = time(NULL);
В
printf("Время выполнения= %d",t2 - t);
}
Как видно, программа очень интенсивно работает с массивом и контроль за выход границ массива должен, вероятно, замедлить работу. Ведь на каждое присвоение приходится проверка индекса массива.
Выводы могут оказаться для кого - то неожиданными:
Версия на C не показала более высокого быстродействия по сравнению с Pascal версией.
Быстродействия Pascal версии при отключении всех проверок увеличивалось на 7 - 8%.
Что вполне логично, т.к. проверка у процессоров 80x86 реализуются на аппаратном уровне. А прирост в 7 - 8% может дать использование компилятора с хорошей оптимизацией.
По данным Дмитрия Беленко, основанным на проводимом им эксперименте, разница между Delphi и C++ Builder даже вычислительных задачах составляет 4 - 5% .
Замечу что существует и с специальный проект Cyclone. Его разработчики - Корнельский университет и AT&T. Язык фактически представляет Си с проверкой потенциально опасных ситуаций, таких как переполнение буфера. В дистрибутив входит программа преобразования программ из Си в Cyclone которая может отыскать и найти потенциально опасные места программы. Основная цель разработчиков - создать язык пригодный для программирования безопасных приложений.
После появления и распространения ООП львиная доля С программистов перешли на С++ . В этом(и большом обьеме ПО уже написанном на С) я вижу одну из основных причин его распространенности.
 Отмечу что и C++ повлиял на C. К примеру enum С получил от С++, и при программировании на С он практически не используется, однако было отмечено, что С содержит такую конструкцию, поскольку она есть в ныне действующем стандарте языка.
В языке появились:
классы(classes);
шаблоны(templates);
пространства имен (namespaces);
перегрузка(overload);
потоки(streams);
исключения (exception)
ООП и современные компиляторы частично сгладили недостатки С. Появились классы для работы с такими типами данных, как строки и множества. В сомнительных(смотрите пример выше) ситуациях компилятор(далеко не любой) может выдать подсказку. Для лучшей читабельности IDE автоматически выровняет исходный текст(Первоначально этим занималась команда indent, которая существует и сейчас во многих клонах UNIX(в т.ч. Linux)). Специальные средства, к примеру, NuMega BoundsChecker позволяют отслеживать наиболее вероятные ошибки, такие, как выход за границы массива или утечка памяти. Программа lint(входит в Unix'ы) занимается исключительно ревизией исходного текста программы по поводу контроля типов.
Низкая скорость компиляции в результате отсутствие полноценного механизма модульности часто компенсируется механизмом предварительной компиляции заголовочных файлов.
"Software engineering - искусство программирования без умения это делать"
Рдсгар Дейкстра (Edsger Dijkstra)
В "Рспользования C++ для разработки прикладного РџРћ Рё вспомогательных средств для нейтрализации недостатков языка РїРѕРґРѕР±РЅРѕ использованию решета для переноски РІРѕРґС‹ Рё специальных средств для замыкания дыр РІ решете."
Автор
Хотя С++ частично сгладил недостатки(просто прикрыв их своими средствами, сами недостатки никуда не делись) к нему он прибавил и свои:
Главный - черезмерная сложность Рё размер языка(это СЂРѕРґРЅРёС‚ его СЃ РђРґРѕР№, хотя сложность РђРґС‹ вызвана разнообразием средств, Р° РЅРµ РёС… дублированием). Даже реализация РћРћРџ подвергается интенсивной критике. РЇ для примера рассмотрю множественное наследование. Сам РІРѕРїСЂРѕСЃ Рѕ необходимости включения множественного наследования РІ язык является достаточно спорным. Р’ частности стоит проблема наличия одноименных методов Сѓ родителей класса. Возникает РІРѕРїСЂРѕСЃ: что вызывать? Первый попавшийся ? Рли РІСЃРµ РїРѕ очереди ? РќР° практике это решается написанием Сѓ РЅРѕРІРѕРіРѕ класса метода, который непосредственно реализует нужную логику, правда тогда возникает РІРѕРїСЂРѕСЃ Рѕ адекватности самого множественного наследования. Ведь его смысл РІ автоматическом вызове методов (Рё доступе Рє полям) классов предков. Если же разработчику приходится указывать конкретный класс - предок, то множественное наследование РІ значительной степени теряет смысл. Остаются лишь такие частности как возможность обращения Рє protected элементов классов предков, РЅРѕ соответствующая модификация программы это РЅРµ проблема. Реализацию множественного наследования тоже нельзя назвать тривиальным делом, РѕРЅР° значительно сложней реализации "единичного наследования".
Большая избыточность средств - т.е. для решения одной задачи я могу использовать большое количество идентичных средств.
Кстати, многие средства языка, которые, по мнению его поклонников, появились в C++, были заимствованы из других языков. К примеру, аналог шаблонов - пакеты - были в АДЕ до создания C++. Обработка исключительных ситуаций присутствует в АДЕ и даже в PL/1.Перезагрузка операций также присутствовала в АДЕ.
 Огромное разнообразие средств, которые дублируют друг друга , нравится многим поклонникам C++.Они считают, что это делает язык более удобным для использования. Считать так- это их право. Вероятно, для кого-то это действительно так.
Приведу авторитетное мнение Кена Томпсона (одного из разработчиков C и Unix):
"При работе с языками C++ и Java у меня возникало определенное беспокойство, когда я просил сделать что - либо, а в ответ получал: "Хорошо, вы делаете это так - то или можете сделать так - то". Совершенно очевидно, если вы в состоянии сделать что - то столь разнообразными способами и все эти способы более не менее эквивалентны, значит в системе заложено слишком много возможностей."
 C тоже избыточен. Пример цикла без тела: for(a=1,b=70;a
Как заметил У. Вульф, "Факт наличия тех или иных возможностей в некотором ЯП не может служить критерием для оценки этого языка. Большой набор хороших самих по себе возможностей, собранных воедино без общей идеи, без определенного единообразия и без элегантности, не приводит к появлению хорошего ЯП."
Средства поддержки совместимости с С.С одной стороны это большой плюс(очень много ПО написано на C), с другой, для обьектно - ориентированного программирования они не нужны.
Пример: введение классов(при их использовании) делает ненужным записи(struct) и вариантные записи(union) , тем не менее по соображениям совместимости они присутствуют.
С++ является надмножеством C , т.е. некая высокоуровневая оболочка к языку системного программирования. Но база для этой оболочки все та же - C.
К примеру, добавлены классы для работы со строками, но сами строки реализованы через указатели. Конечно, здесь есть и плюс-широта средств языка. Но она не компенсирует получившуюся громоздкость.
Макросредства ассемблеров тоже являются высокоуровневой оболочкой и позволяют использовать конструкции, характерные для ЯПВУ (типа циклов) в программах на ассемблере. Замечу, что и на макросредствах ассемблера без использования непосредственно команд процессора можно создавать достаточно сложные системы. Но это не делает Ассемблер языком высокого уровня.
"Писать плохие программы на С++ значительно легче, чем хорошие."
Общепризнанный факт.
Громоздкость С++ Бьярн Страуструп объясняет следующим образом:
"Следовательно, универсальный язык программирования должен поддерживать различные СЃРїРѕСЃРѕР±С‹ мышления Рё стили программирования. Рто разнообразие есть следствие, как разнородности решаемых задач, так Рё многообразия путей РёС… решения. C++ поддерживает широкий спектр стилей программирования Рё поэтому более заслуживает название мультипарадигменного, нежели объектно - ориентированного языка...
Мне представляется, что языки, опирающиеся на какую - либо одну парадигму,ограничивают свободу программиста. Платой за простоту оказывается смирительная рубашка, сковывающая интеллект разработчика.."
Т.е. получается, если разные разработчики используют разные стили программирования,то полную поддержку всех стилей нужно включать в язык.
Продолжая идею, замечу - для решения разных задач необходимы разные алгоритмы. Поэтому в STL необходимо включить алгоритмы решения задач из всех областей человеческой деятельности, где используется язык C++ !!!
Рђ РІ разных РћРЎ интерфейсы разработчика существенно различаются(сравните Win32 API Рё POSIX).Рто тоже необходимо отобразить РІ языке.!!!
Страуструп недавно в интервью высказался за включение в язык средств разработки баз данных и интерфейса пользователя (как в Java). Конечно, включить все, что бывает в ЯП в один язык - идея хорошая, но Вам она ничего не напоминает ? Вспомните судьбу "грандиознейшего проекта всех времен и народов - языка АДА". Вопрос о границе, где кончаются средства языка и начинаются другие средства, затронут в разделе "О маленьких и больших языках".
Рпоследнее - что Р±С‹ РЅРё писал Страуструп, факт остается фактом. C++ полностью практически РЅРёРєРѕРіРґР° Рё никем РЅРµ применяется. Рспользуются лишь ограниченные подмножества языка, поддерживающие определенный стиль разработки. Как РѕРЅ сам заметил, "Для того, чтобы писать хорошие программы РЅР° C++, необязательно знать его полностью"
 В принципе, люди от естественных языков берут лишь очень небольшую часть. Но в программировании такой подход может иметь большие негативные последствия. К примеру, может появиться необходимость модификации программного кода написанного одним разработчиком, использующим 20 % языка другим, использующим другие 20 % языка(другую часть).
С++ вобрал в себя средства для поддержки очень широкого спектра технологий разработки и стилей программирования. На нем можно разрабатывать с почти одинаковой [не]успешностью, используя и линейное , и обьектно - ориентированное программирование.
 Линейное программирование - архаичный способ разработки программ без использования таких структур языка, как циклы. Зато интенсивно используется оператор GO TO. Был вытеснен структурным программированием.
Собственной идеологии язык не имеет. Поддерживается множество парадигм. Разработчик должен выбрать то, что необходимо лично ему, а об остальном он может спокойно забыть.
Даже уровень языка однозначно определить невозможно. Он поддерживает как низкоуровневые структуры данных(битовые поля) и методы программирования (адресная арифметика), так и высокоуровневые структуры данных( - ассоциативный массив) и методы программирования(ООП).
Всё это делает язык крайне универсальным (и даже уникальным), пригодным для решения очень широкого круга задач. Другой вопрос, что такая универсальность для львиной доли практических задач не нужна. Да и вынести низкоуровневый код, в отдельный модуль написанный, допустим, на ассемблере не составляет проблем.
Процитирую один абзац из первой части.
"В таком случае я могу предложить отменить все разновидности и модели самолетов. Роставить одну. Самую "крутую". К примеру, стратегический бомбардировщик - невидимку B - 2.Правда, людей придется перевозить в бомболюках, хотя много народу не поместится. Да и стоимость билетов учитывая то, что изготовление одного самолета стоит более двух миллиардов долларов будет немаленькая. Слишком немаленькая, чтобы практически использовать этот вид транспорта."
А как удобно управлять таким самолетом ! Ведь средства управления он должен включить в себя от всех типов самолетов. Вот и придется пилоту постоянно переключаться с панели управления вооружением на панель регулировки температуры и влажности в салоне самолета.
Важно отметить, что в этом заключается одно из ключевых различий с Виртовской линией Pascal/Modula/Oberon. На Pascal'е можно очень хорошо использовать процедурную декомпозицию, но использовать линейное программирование неудобно.
На Обероне аналоги (а тем более на Java) очень трудно писать, не используя ООП. Не ОО, имеющие ОО аналоги средства, изъяты из языка.
 К примеру, без вариантной записи, используя возможность наследования расширяемых записей, т.е. классов, можно спокойно обходиться.
Тем не менее, Оберон остается универсальным языком. Конечно, не таким универсальным, как C++(в смысле не мультипарадигменный). Но природа программ, да и программистов такова, что универсальных программ, да и программистов не существует. Представьте себе игру, которая занимается не только подсчетом денег заработанных игроками, но и чтением/записью сохраненных игр посредствам работы с портами ввода - вывода(т.е. то, чем занимается низкоуровневый драйвер на ассемблере).
Рли разработчика, который поочередно разрабатывает то этот драйвер, то бухгалтерский РђР Рњ. Конечно, РѕР±Рµ программы можно РїСЂРё желании написать РЅР° C++, РЅРѕ используемые РїСЂРё разработке средства Р±СѓРґСѓС‚ разные. Да Рё программы Р±СѓРґСѓС‚ уступать аналогичным, написанным РЅР° ассемблере(работать будет быстрее) Рё, Рє примеру, Delphi (разработка займет меньше времени).
С другой стороны, именно всеобъемлемость средств C++ и отсутствие четкой идеологии языка послужили его распространению. Каждый может выбирать стиль программирования по душе. C++ это сундук в котором каждый находит то сто нужно ему. В этом состоит одно из ключевых отличий от таких языков, как Pascal и Java, которые в значительной степени диктуют стиль программирования разработчику.
С одной стороны, подобное навязывание стиля - это плохо, т.к. ограничивает свободу разработчика. Но если посмотреть с другой точки зрения: вряд ли рядовой разработчик придумает что - нибудь лучшее, чем предлагают разработчики языка (среды, CASE средства и т.д.), а если и придумает, то лучше воплотить эту технологию в чем - то доступном другим разработчикам, например, ЯП.
Если ориентироваться не на разработчиков, а на задачи, то мы увидим еще одно "НО". Разные технологии в разной степени применимы к разным задачам. К примеру, ООП не дает заметного выигрыша в вычислительных математических задачах. Но ведь и заметного проигрыша тоже нет ?
К тому же каждый язык имеет свою сферу применения. Никто не предлагает писать на Perl модули ОС. Да и программисты, пишущие на Perl, и программисты, пишущие модули ОС - обычно разные люди.
 В случае языка АДА подобная всеобъемлемость имела практическую необходимость. Ведь АДА была призвана заменить (и заменила) все языки (а их было несколько сотен, используемые в US DOD(министерстве обороны США) и всех организациях, работающих на него. Соответственно, такая же универсальность нужна C++ лишь в том случае, если он призван вытеснить не меньше языков. Правда, US DOD нужен был единый стандартный язык, а кому нужен C++ ?
У Страуструпа есть такая идея: "Пользователь не обязан знать ничего, кроме того подмножества языка, которое он явно применяет для написания программы"
Рдея хорошая, РЅРѕ, Рє сожалению, стопроцентно нереализуемая. Рлементарные операции СЃРѕ строками требуют знакомства СЃ STL Рё шаблонами. Конечно, можно писать РІ стиле C, РЅРѕ тогда исчезают преимущества C++ перед РЅРёРј. Для использования массивов СЃ проверкой РЅР° выход индекса РёР· диапазона необходимо использовать STL Рё перегрузку операций шаблона.
В одном из интервью Страуструп приводит следующие потенциальные направления развития C++:
"Параллелизм: я сторонник библиотечной реализации потоков и параллельного выполнения операций без разделения памяти.
Отображение типов: неплохо было бы обеспечить библиотечную организацию интерфейса с информацией расширенных типов.
Типизация: хотелось бы, чтобы в библиотеку Standard Library были включены функции поддержки расширенных типов, однако конкретных предложений у меня нет.
Хеш - таблицы: конечно, необходимо интегрировать некоторые варианты популярной схемы hash_map.
Ограничения для аргументов - шаблонов: все это просто, универсально и элегантно реализуется в рамках существующего стандарта Си++.
Операторы контроля: многие из наиболее важных операторов контроля - верификация кода и обработка ошибок - можно было бы реализовать в виде шаблонов. Некоторые из них следует включить в библиотеку Standard Library.
Сопоставление с регулярными выражениями: хотелось бы видеть в стандартном варианте языка библиотеку определения соответствия шаблонам.
Сборка мусора: в стандарте Си++ нужно явно определить технологию, позволяющую игнорировать "скрытые указатели", а также конкретизировать порядок обработки деструкторов.
Графический интерфейс пользователя: хорошо было бы иметь стандартные конструкции GUI, но не знаю, насколько это реально в сложившейся ситуации.
Независимость от платформы: хотелось бы, чтобы Standard Library поддерживала более широкий набор интерфейсов с общими системными ресурсами, например, с каталогами и сокетами."
Еще одна проблема заслуживающая упоминания - это путь распространения C++. Очевидно, что тут повлияли распространенность Си, широта средств языка и областей его применения. Достаточно большой вопрос - насколько на распространение C++ повлияла рекламная поддержка ?
Вот что говорит сам Страуструп по этому поводу:
"Си++ приобрел массу приверженцев там, где это было нужнее всего: миллионы программистов используют его в качестве своего основного инструмента.
Удивительно, но этого удалось добиться, не имея и по существу без финансовых затрат. Однако, с другой стороны, сообщество сторонников Си++ оказалось разобщенным и крайне уязвимым для выпадов враждебной пропаганды. Мне кажется, все дело здесь в том, что хороший код часто остается незамеченным - даже его пользователями. Посмотрите на программы, написанные на Си++, например, на приложения Netscape или на Internet Explorer. Компании, разрабатывающие программы для решения реальных задач - в частности, для управления телекоммуникациями, контроля за различными механизмами и имитационного моделирования, - предпочитают не говорить, на каком языке написаны их приложения.
 О том, что приложение написано не на C++, как правило, тоже никто не говорит. О количестве ошибок в упомянутых продуктов я не говорю.
К сожалению, это развязывает руки тем, кто пропагандирует альтернативные средства, а также любителям теоретических рассуждений.
Язык Си++ никогда не поддерживался каким - то одним лидером отрасли. Каждый крупный производитель дополняет (и так было всегда) стандарт Си++ своими собственными элементами. Си++ никогда не являлся предметом маркетинговой стратегии. Если какие - то маркетинговые мероприятия и проводились, то только организациями, продающими что - то другое (например, среду для разработки программного обеспечения), включающее в себя Си++ в качестве составляющего компонента. Сообщество Си++ скорее страдало от чрезмерной популярности этого языка: он постоянно становился , ведь в современном мире, живущем по законам коммерции, честная борьба - большая редкость.
У сообщества Си++ никогда не было координирующего центра, финансовые возможности которого позволяли бы ему заниматься популяризацией языка. Кто и из каких соображений готов голосовать за Си++? Ркак довести эту информацию до программистов, преподавателей, менеджеров? Буквально на днях я слушал выступление профессора перед студентами, в котором он категорически отрицал существование стандарта Си++! Жаль, что даже спустя два года после ратификации этого стандарта сплошь и рядом возникают подобные недоразумения."
Приведу и другую точку зрения.
РњРЅРѕРіРёРµ приверженцы C++ считают его языком для профессионалов. Рто так.
Но они переходят дальше и производят ошибочное следствие, что единственный язык для профессионалов - это C++.
Яблоко - это фрукт. Но это не значит, что любой фрукт есть яблоко.
Поклонники Си даже сочинили стишок
 "У любого ты спроси
Будь хоть трижды ламер
программируешь на Си
Ты - крутой программер"
Я cчитаю что определять крутость программиста по языку - по крайней мере некорректно. Можно писать хорошие программы на Basic и ужасные на C++. Кроме того, аргумент против C++ в религиозных войнах о его рекламной распространенности тоже появился, вероятно не с неба.
В заключение отмечу что:
В тоже время нужно признать, что C++ является наиболее мощным, вероятно за исключением Ad'ы языком из широко используемых.
Он же является на момент написания обзора наиболее популярным языком. Хотя это не бесспорно. Почему см. страницу XXX. Хотя последние годы его потеснила Java.Сейчас теснит и C#.
Он же является наиболее критикуемым языком.
Он же содержит огромное наибольшее количество недостатков и подводных камней нередко делающих программы на нем менее надежными.
P.S.
Хотелось бы знать мнения читателей по поводу:
доля того или иного языка в программной индустрии (измеренная в стоимости проектов, стоимости продаваемых программных продуктов, количестве программистов, может еще в чем...)
влияние языка на стоимость проекта, стоимость сопровождения, надежность.
принципы, по которым в индустрии выбираются языки
сферы, где существует конкуренция языков - и области, где "все поделено"
тенденции и прогнозы (например - "через N лет мы все будем в сфере A - писать на B, в сфере C - на D, и т.п."
Очень приветствуются аргументированные ответы ссылки на научные исследования,книги и статьи.
Очень интересны результаты разработок(и практический опыт приобретенный при разработке оных) однотипного(а лучше одинакового ПО) на разных ЯП и его влиянии на их стоимость/время разработки/устойчивость и скорость работы приложений/...
При этом хорошо бы рассматривать ЯП не как вещь в себе, а в связи с другим ПО(от отладчика уровня ядра до Case средств).
Рнтересен сравнительный анализ РЇРџ Рё компиляторов Рё вообще РІСЃС‘ что СЃ этим связанно. Р’ частности СЃРІСЏР·СЊ СЃ психологией. Очень интересно отличие "Сѓ нас" Рё " Р·Р° Р±СѓРіСЂРѕРј".
Рнтересуют также координаты людей Рё организаций, РІ чьи профессиональные Рё научные интересы РІС…РѕРґСЏС‚ РЇРџ.
Список литературы
Для подготовки данной работы были использованы материалы с сайта http://www.bugtraq.ru/