Tagi: Historia standaryzacji C, ANSI C, ISO C, C99, C11, ISO/IEC C, C.

pochodzenie

C i jest "koproduktem" z tworzenia systemu operacyjnego UNIX, który został opracowany w Bell Laboratories przez Kena Thompsona, Denisa Ritchie i spółkę. Thompson własnoręcznie napisał oryginalną wersję systemu UNIX, która działała na DEC PDP-7, jednym z pierwszych minikomputerów z zaledwie 8K słów pamięci głównej (w końcu był to rok 1969).

Podobnie jak inne ówczesne systemy operacyjne, UNIX został napisany w języku asemblera. Debugowanie programów asemblerowych jest naprawdę trudne i trudne do poprawienia, a UNIX nie był wyjątkiem. Thompson zdecydował, że do dalszego rozwoju systemu operacyjnego potrzebny jest język wysokiego poziomu i wymyślił mały język B. Thompson przyjął język BCPL, język dla programowanie systemu opracowany w połowie lat 60-tych. BCPL z kolei wywodzi się z Algolu 60, jednego z najwcześniejszych (i najbardziej wpływowych) języków.

Ritchie wkrótce dołączył do projektu UNIX i zaczął pisać w B. W 1970 Bell Labs zakupił PDP-11 do projektu. Ponieważ B był gotowy do działania na PDP-11, Thompson przepisał część UNIX na B. W 1971 stało się jasne, że B nie jest całkiem odpowiedni dla PDP-11, więc Ritchie zaczął tworzyć rozszerzoną wersję B. najpierw nazwał go NB (New B ), ale kiedy język stał się bardzo różny od B, nazwa została zmieniona na C. W 1973 język był na tyle stabilny, że można było w nim przepisać UNIX. Przejście do C przyniosło ważną korzyść: przenośność. Pisząc kompilator C dla każdej maszyny w Bell Labs, zespół programistów mógł przenieść na nie system UNIX.

Normalizacja

C nadal ewoluował w latach 70., zwłaszcza między 1977 a 1979 rokiem, kiedy opublikowano pierwszą książkę o C. Język programowania C, napisany przez Briana Kernighana i Denisa Ritchie i opublikowany w 1978 roku, stał się biblią programistów C. Wobec braku oficjalnego standardu, ta książka – znana również jako K&R lub „Biała Księga”, jak lubią ją nazywać fani C – stała się de facto standardem. W latach 70. było niewielu programistów C, a większość z nich była użytkownikami UNIXa. Jednak w latach 80. C wyszedł poza wąskie ramy świata UNIX-a. Kompilatory C stały się dostępne na różnych komputerach z różnymi systemami operacyjnymi. W szczególności C zaczęło się rozprzestrzeniać na szybko rozwijającej się platformie IBM PC.

Wraz ze wzrostem popularności pojawiły się problemy. Programiści, którzy pisali nowe kompilatory, wzięli za podstawę język opisany w K&R. Niestety w K&R niektóre cechy języka zostały opisane niejasno, więc kompilatory często interpretowały je według własnego uznania. Ponadto w książce nie było wyraźnego rozróżnienia między cechą języka a cechą systemu operacyjnego UNIX. Co gorsza, po publikacji K&R C nadal się rozwijało: dodawane były do ​​niego nowe funkcje i wycinane z niego stare. Wkrótce pojawiła się oczywista potrzeba kompleksowego, dokładnego i aktualnego opisu języka. Bez takiego standardu zaczęły pojawiać się dialekty języka, które przeszkadzały w przenoszeniu, najsilniejszej stronie języka.

Rozwój amerykańskiego standardu C rozpoczął się w 1983 roku pod auspicjami American National Standards Institute (ANSI). Po wielu poprawkach standard został ukończony w 1988 roku i formalnie przyjęty w grudniu 1989 roku jako ANSI X3.159-1989. W 1990 roku została zatwierdzona przez Międzynarodową Organizację Normalizacyjną (ISO) jako międzynarodowa norma ISO/IEC 9899:1990. Ta wersja języka jest powszechnie określana jako C89 lub C90, aby uniknąć pomyłek z oryginalną wersją C, powszechnie określaną jako K&R C.

Język uległ niewielkim zmianom w 1995 r. (zmiany są opisane w dokumencie powszechnie określanym jako Poprawka 1). Bardziej znaczące zmiany nastąpiły w 1999 roku, kiedy opublikowano normę ISO/IEC 9899:1999. Język opisany w tym standardzie jest powszechnie określany jako C99. Terminy „ANSI C”, „ANSI/ISO C” i „ISO C”, używane kiedyś do opisania C99, są niejednoznaczne ze względu na istnienie dwóch standardów.

W 2011 roku wraz z wersją języka C++ został wydany standard C11. Pomimo istnienia standardu 11, wiele kompilatorów nadal nie obsługuje w pełni nawet wersji C99, więc użycie standardu C11 zostanie wyraźnie stwierdzone.

Kiedy Twoja reputacja działa na Twój zysk

Zarządzanie społecznością

Tworzenie tonu głosu. Szybkie przetwarzanie zarówno negatywnych, jak i pozytywnych komentarzy w imieniu marki. Zarządzanie komunikacją według zadanych scenariuszy. Przekazywanie problematycznych momentów klientowi.

Agenci wpływu

Tworzenie i wdrażanie „wirtualów” na forach i in w sieciach społecznościowych. Istnieje baza danych rachunków pompowanych i rzeczywistych w ponad 300 witrynach.

Praca z recenzjami

Pisanie, koordynowanie i publikowanie recenzji marki w najlepszych witrynach i witrynach z recenzjami. Przetwarzanie i nakładanie negatywnych komentarzy na pozytywne. W wyniku wyniki wyszukiwania negatyw jest stopniowo zastępowany.

Monitorowanie mediów społecznościowych

Praca z systemami Youscan, IQbuzz, Brand Analytics. Kontrola wzmianek o marce. Identyfikacja kluczowych spostrzeżeń, szybka reakcja na negatywność. Niezbędne narzędzie do kontroli informacja zwrotna od klientów.

Analityka i Badania

Analiza pole informacyjne, badania kategorii produktów oraz głównych konkurentów marki. To narzędzie obejmuje zadania od kontroli reputacji i marketingu w czasie rzeczywistym po dogłębne badania.

SERM

Szczegółowa analiza wyniki wyszukiwania dla wybranych słów kluczowych. Zbieranie wzmianek o kliencie w sieciach społecznościowych, forach i serwisach informacyjnych. Opracowanie strategii postępowania z informacjami negatywnymi. Klient otrzymuje w pełni kontrolowaną emisję w TOP10.

Jaki jest status języka C? Historycznie język ten jest nierozerwalnie związany z systemem operacyjnym Unix, który obecnie przeżywa swoje odrodzenie. Lata 60. były erą powstawania systemów operacyjnych i języków programowania wysokiego poziomu. W tamtym czasie system operacyjny i kompilatory były opracowywane niezależnie dla każdego typu komputera, a często nawet własnych języków programowania (przypomnijmy np. PL/I). Jednocześnie ogólność problemów, które pojawiają się w tym przypadku, stała się już oczywista. Odpowiedzią na uświadomienie sobie tej wspólności była próba stworzenia uniwersalnego telefonu komórkowego system operacyjny, a do tego zajęło nie mniej uniwersalne i język mobilny programowanie. C stał się tym językiem, a Unix stał się pierwszym systemem operacyjnym napisanym prawie w całości w języku wysokiego poziomu.

Ścisły związek z Unixem dał C pole testowe, którego nie miał w tamtym czasie żaden inny język. Zadania programowania systemowego słusznie uważano wówczas za najbardziej złożone w branży. W większości były one tak zależne od maszyn, że wielu nawet nie myślało o swoim rozwiązaniu w inny sposób niż w asemblerze. Języki wysokiego poziomu były przeznaczone do programowania aplikacji i tylko w bardzo ograniczonym stopniu zaimplementowały funkcje niezbędne do praca systemu, a często tylko dla określonego typu maszyny.

Od samego początku język C był projektowany tak, aby można było w nim pisać zadania systemowe. Twórcy C nie zaczęli opracowywać abstrakcyjnego modelu executora języka, ale po prostu zaimplementowali w nim te cechy, które były najbardziej potrzebne w praktyce programowania systemowego. Były to przede wszystkim środki bezpośredniej pracy z pamięcią, strukturalne struktury kontrolne oraz modułowa organizacja programu. I właściwie nic więcej nie było zawarte w języku. Cała reszta została przeniesiona do biblioteki wykonawczej. Dlatego nieżyczliwi czasami mówią o języku C jako asemblerze strukturalnym. Ale bez względu na to, o czym rozmawiali, podejście okazało się bardzo udane. Dzięki niemu osiągnięto nowy poziom pod względem stosunku prostoty i możliwości języka.

Istnieje jednak inny czynnik, który zadecydował o sukcesie języka. Twórcy bardzo umiejętnie wyodrębnili w nim właściwości zależne od maszyny i niezależne. Dzięki temu większość programów można pisać uniwersalnie – ich wydajność nie zależy od architektury procesora i pamięci. Kilka części kodu zależnych od sprzętu można zlokalizować w: poszczególne moduły. Za pomocą preprocesora można tworzyć moduły, które po skompilowaniu do różne platformy wygeneruje odpowiedni kod zależny od maszyny.

Sporo kontrowersji wywołała składnia języka C. Użyte w nim skróty, jeśli są używane w nadmiarze, mogą sprawić, że program stanie się całkowicie nieczytelny. Ale, jak powiedział Dijkstra, - środków nie można winić za to, że są używane w sposób niepiśmienny. W rzeczywistości skróty składni zaproponowane w C odpowiadają najczęściej spotykanym w praktyce sytuacjom stereotypowym. Jeśli potraktujemy skróty jako idiomy dla wyrazistego i zwięzłego przedstawienia takich sytuacji, to ich użyteczność staje się bezwarunkowa i oczywista.

Tak więc C pojawił się jako język programowania systemów ogólnego przeznaczenia. Ale nie mieścił się w tych granicach. Pod koniec lat 80. język C, odsuwając Fortran z czołowej pozycji, zyskał masową popularność wśród programistów na całym świecie i zaczął być używany w wielu różnych zadaniach użytkowych. Istotną rolę odegrało tutaj rozpowszechnienie Unixa (a więc C) w środowisku uniwersyteckim, gdzie szkolono nowe pokolenie programistów.

Jak wszystkie języki, C ewoluował z biegiem czasu, ale większość ulepszeń nie była radykalna. Być może najistotniejsze z nich należy uznać za wprowadzenie ścisłej specyfikacji typów funkcji, co znacznie zwiększyło niezawodność interakcji międzymodułowej w C. Wszystkie takie ulepszenia zostały zapisane w 1989 roku w standardzie ANSI, który wciąż definiuje Język C.

Ale jeśli wszystko jest tak bezchmurne, to dlaczego wszystkie inne języki są nadal używane, co wspiera ich istnienie? Piętą achillesową języka C było to, że był on zbyt niski dla zadań, które w latach 90. stawiały na porządku dziennym. A ten problem ma dwa aspekty. Z jednej strony w język wbudowano narzędzia zbyt niskopoziomowe - przede wszystkim pracował on z pamięcią i arytmetyką adresową. Nie bez powodu zmiana pojemności procesorów ma bardzo bolesny wpływ na wiele programów C. Z drugiej strony w C brakuje narzędzi wysokiego poziomu - abstrakcyjnych typów danych i obiektów, polimorfizmu, obsługi wyjątków. W konsekwencji w programach C często dominuje technika realizacji zadania.

Pierwsze próby naprawienia tych niedociągnięć zaczęto podejmować na początku lat osiemdziesiątych. Już wtedy Bjorn Stroustrup z AT & T Bell Labs zaczął rozwijać rozszerzenie języka C pod nazwą warunkową. Styl programowania był dość zgodny z duchem, w jakim powstał sam język C – wprowadzono do niego pewne cechy, aby uczynić go bardziej wygodna praca konkretne osoby i grupy. Pierwszy komercyjny tłumacz nowego języka, nazwanego C++, pojawił się w 1983 roku. Był to preprocesor, który przetłumaczył program na kod C. Jednak wydanie książki Stroustrupa w 1985 roku można uznać za faktyczne narodziny języka. To właśnie od tego momentu C++ zaczął zdobywać popularność na całym świecie.

Główną innowacją C++ jest mechanizm klas, który umożliwia definiowanie i używanie nowych typów danych. Programista opisuje wewnętrzną reprezentację obiektu klasy i zestaw funkcji metody dostępu do tej reprezentacji. Jednym z cenionych celów przy tworzeniu C++ była chęć zwiększenia odsetka ponownego wykorzystania już napisanego kodu. Koncepcja klas oferowała do tego mechanizm dziedziczenia. Dziedziczenie umożliwia tworzenie nowych (pochodnych) klas z rozszerzoną reprezentacją i zmodyfikowanymi metodami bez wpływu na skompilowany kod oryginalnych (podstawowych) klas. Jednocześnie dziedziczenie zapewnia jeden z mechanizmów implementacji polimorfizmu - podstawową koncepcję programowania obiektowego, zgodnie z którą w celu wykonania tego samego typu przetwarzania różne rodzaje danych, można użyć tego samego kodu. W rzeczywistości polimorfizm jest również jedną z metod zapewniających ponowne użycie kodu.

Wprowadzenie klas nie wyczerpuje wszystkich innowacji języka C++. Posiada pełnoprawny mechanizm obsługi wyjątków strukturalnych, którego brak w C znacznie utrudniał pisanie niezawodnych programów, silnik szablonów, wyrafinowany mechanizm generowania makr głęboko osadzony w języku, otwierający kolejną ścieżkę do ponownego wykorzystania kodu, i wiele więcej.

Tak więc ogólna linia rozwoju języka miała na celu rozszerzenie jego możliwości poprzez wprowadzenie nowych konstrukcji wysokopoziomowych przy zachowaniu możliwie pełnej kompatybilności z operacjami ANSI C., tak aby programista faktycznie przestał pracować bezpośrednio z pamięcią i jednostkami zależnymi od systemu. Język nie zawiera jednak mechanizmów zmuszających programistę do poprawnej struktury programu, a autorzy nie wydali żadnych systematycznych zaleceń dotyczących stosowania jego dość wyrafinowanych konstrukcji. Nie zadbali na czas i o stworzenie standardowej biblioteki klas, która implementuje najpopularniejsze struktury danych.

Wszystko to doprowadziło do tego, że wielu programistów zostało zmuszonych do samodzielnego eksplorowania labiryntów semantyki języka i samodzielnego poszukiwania skutecznych idiomów. Tak więc na przykład na pierwszym etapie rozwoju języka wielu twórców bibliotek klas starało się zbudować pojedynczą hierarchię klas ze wspólną klasą bazową Object. Pomysł ten został zapożyczony od Smalltalk - jednego z najbardziej znanych języków obiektowych. Okazało się to jednak całkowicie nieopłacalne w C++ - rozbudowane hierarchie bibliotek klas okazały się nieelastyczne, a praca klas nie była oczywista. Aby biblioteki klas były użyteczne, musiały być dostarczone w kodzie źródłowym.

Pojawienie się klas szablonowych całkowicie odrzuciło ten kierunek rozwoju. Dziedziczenie zaczęto stosować tylko w przypadkach, gdy wymagane było wygenerowanie wyspecjalizowanej wersji istniejącej klasy. Biblioteki zaczęły składać się z oddzielnych klas i małych, niepowiązanych hierarchii. Jednak ponowne użycie kodu zaczęło spadać, ponieważ C++ nie pozwala na polimorficzne użycie klas z niezależnych hierarchii. Powszechne stosowanie szablonów prowadzi do niedopuszczalnego wzrostu ilości kompilowanego kodu – nie zapominajmy, że szablony są implementowane za pomocą metod generowania makr.

Jedną z najgorszych wad C++, odziedziczoną po składni C, jest dostępność dla kompilatora opisu wewnętrznej struktury wszystkich użytych klas. W efekcie zmiana wewnętrznej struktury reprezentacji jakiejś klasy bibliotecznej prowadzi do konieczności przekompilowania wszystkich programów, w których ta biblioteka jest używana. To znacznie ogranicza deweloperów bibliotek w zakresie ich modernizacji, ponieważ wypuszczanie Nowa wersja, muszą zachować zgodność binarną z poprzednim. To właśnie ten problem sprawia, że ​​wielu ekspertów uważa, że ​​C++ nie nadaje się do dużych i bardzo dużych projektów.

A jednak pomimo wymienionych niedociągnięć, a nawet niedostępności standardu językowego (to po ponad piętnastu latach użytkowania!), C++ pozostaje jednym z najpopularniejszych języków programowania. Jego siła tkwi przede wszystkim w niemal całkowitej zgodności z językiem C. Dzięki temu wszystkie osiągnięcia dokonane w C są dostępne dla programistów C++.C++, nawet bez użycia klas, sprowadza do C kilka ważnych dodatkowe funkcje i udogodnienia, z których wiele osób korzysta po prostu jako ulepszone C.

Dotyczący model obiektowy C++, to dopóki twój program nie stał się bardzo duży (setki tysięcy linijek), całkiem możliwe jest jego użycie. Ostatni trend przejścia na komponent oprogramowanie tylko wzmacnia pozycję C++. Podczas opracowywania poszczególnych komponentów niedociągnięcia C++ jeszcze się nie pojawiają, a wiązanie komponentów w działający system nie odbywa się już na poziomie języka, ale na poziomie systemu operacyjnego.

W świetle wszystkiego, co zostało powiedziane, perspektywy dla C++ nie wyglądają ponuro. Chociaż monopol na rynku języków programowania mu nie świeci. Być może możemy tylko z całą pewnością powiedzieć, że język ten nie przetrwa kolejnej modernizacji-rozszerzenia. Nie bez powodu, kiedy pojawiła się Java, poświęcono jej tak wiele uwagi. Językowi bliskiemu składnią C++, a zatem pozornie znanemu wielu programistom, oszczędzono najbardziej rażących niedociągnięć C++, które odziedziczył po latach 70-tych. Wydaje się jednak, że Java nie spełnia roli, jaką wyznaczyli jej niektórzy.

Szczególna rola języków C/C++ we współczesnym programowaniu sprawia, że ​​niemal bezcelowe jest podawanie konkretnych adresów w Internecie, pod którymi można znaleźć materiały na ich temat. Takich miejsc jest zbyt wiele. Jeśli jednak chcesz dowiedzieć się więcej o ewolucji C++, zacznij od krótkiego artykułu http://citforum.syzran.ru/programming/prg96/76.shtml.

Aleksandrze Siergiejewu, [e-mail chroniony]
Artykuł z magazynu BYTE/Rosja, marzec 2000

W celu wizualnego zademonstrowania użycia opisanych języków w praktyce wybraliśmy zadanie, w którym należało wpisać ze standardowego wejścia lub z pliku szereg liczb całkowitych, a następnie wyprowadzić tylko nieparzyste, a w Odwrotna kolejność. Jest to jeden z najprostszych problemów, który wymaga dużo pracy z tablicami, pętlami, rozgałęzieniami i we/wy, aby go rozwiązać, a także pozwala zademonstrować wywołania podprogramów. Jednocześnie jest widoczny i łatwo dostrzegalny.

Listing 1. C

1 #zawiera /* Połącz funkcje I/O */ 2 3 void main(void) 4 ( 5 int M; /* Tablica 10 liczb całkowitych, licząc od 0 */ 6 int N; 7 for (N=0; N<10; ++N) /* Вводим не более 10 чисел */ 8 if (EOF == scanf ("%d, M+N)) 9 break; /* Если конец файла, прерываем цикл */ 10 11 for (-N; N>=0; --N) /* Przeprowadź pętlę przez tablicę w odwrotnej kolejności */ 12 if (M[N]%2) /* w kolejności i wypisz nieparzyste */ 13 printf("%d\n", M[N]) ; czternaście)

  • Linia 3. W C/C++ wykonywanie programu zawsze rozpoczyna się od funkcji main.
  • Linie 7 i 11. Nagłówek pętli zawiera średnik wskazujący ustawienie początkowe, warunek kontynuacji i regułę ponownego obliczania parametru pętli. Operacje ++ oraz -/- - najsłynniejszy ze skrótów języka C, oznaczający przyrost i dekrementację zmiennej, czyli zwiększanie i zmniejszanie jej wartości o jeden.
  • Linia 8. Funkcjonować scanf wprowadza, zgodnie z formatem określonym przez pierwszy parametr, wartości zmiennych, których adresy są określone przez pozostałe parametry. Tutaj adres, pod którym wprowadzana jest wartość, jest obliczany za pomocą arytmetyki adresu, na adres lokalizacji tablicy M dodano przesunięcie N elementy. Ten sam efekt można uzyskać pisząc &M[N].
  • Linia 12. Operacja % oblicza pozostałą część dzielenia. Stan operatora jeśli jest uważany za spełniony, jeśli wartość liczbowa wyrażenia jest niezerowa.
  • Linia 13. Funkcjonować printf- drukowanie według formatu działa podobnie scanf, ale zamiast adresów przekazywane są wartości do wyprowadzenia.
1 #zawiera 23 szablon class Array 4 (5 public: Array (T Size=1) : M (nowy T), N(Size), n(0) () 6 Array (void) ( usuń M;) 7 T Count (void) const ( return n; ) 8 T operator (int i) const ( return M[i]; ) 9 void Add (T Data); 10 private: 11 T* M; // adres pamięci rozproszonej 12 int N, n; // N - rozproszone n - używane 13); 14 15 szablon nieważna tablica ::Add(T Data) 16 ( if (N-n) // Jeśli wszystkie przydzielone 17 ( int* P = new T; // miejsce jest używane, przydziel więcej 18 for (int i=0; i A; // Tablica liczb całkowitych o zmiennej wielkości 28 while (1) // Nieskończona pętla 29 ( int N; 30 cin >> N; // cin - standardowy strumień wejściowy 31 if (cin.eof()) break; // Wyjście z pętla według końca pliku 32 A.Add(N); // Dodaj wprowadzoną liczbę do tablicy 33 ) 34 for (int N=A.Count()-1; N>=0; --N) // Pętla przez tablicę 35 if ( A[N]%2) 36 cout<i zwolnij pamięć
  • Linie 3-13. Klasa szablonu jest zadeklarowana Szyk z parametrem T. Jest to tablica typów obiektów o zmiennej wielkości T. Oczywiście w naszym zadaniu nie ma potrzeby używania klasy template. Chcieliśmy jednak zademonstrować, jak C++ tworzy polimorficzną strukturę danych, która może współpracować z dowolnym typem elementu.
  • Linia 5. Konstruktor klas. Inicjuje reprezentację obiektu. Na przykład w terenie M wprowadzany jest adres bloku pamięci zleconego przez operację; nowy T.
  • Linia 8. Przykład przeciążenia operacji. Funkcjonować operator zostanie wywołana, gdy na prawo od obiektu klasy pojawią się nawiasy kwadratowe szyk.
  • Linia 9. Ta funkcja jest najważniejsza we wdrożeniu. Dodaje elementy do tablicy, rozszerzając ją w razie potrzeby. Ponieważ jest bardziej złożony niż inne, jego definicja została usunięta z opisu klasy. Funkcje opisane w treści klasy są implementowane w C++ nie przez wywołanie, ale przez podstawienie wbudowane. Przyspiesza to program, chociaż zwiększa jego rozmiar.
  • Linie 15-24. Definicja funkcji Tablica::Dodaj(T)(przy okazji, to jej pełne imię).
  • Linia 27. Utwórz obiekt typu szyk. Wzornik Aggau sparametryzowany według typu int.

Dlaczego C++

C++ jest obecnie uważany za dominujący język używany do tworzenia komercyjnych produktów oprogramowania. W ostatnich latach ta dominacja została nieco zachwiana podobnymi twierdzeniami z języka programowania, takiego jak Java, ale wahadło opinii publicznej odwróciło się w drugą stronę i wielu programistów, którzy porzucili C++ na rzecz Javy, niedawno wróciło do jego dawnej sympatii. W każdym razie te dwa języki są tak podobne, że ucząc się jednego z nich, automatycznie opanujesz 90% drugiego.

C# to nowy język opracowany przez firmę Microsoft dla platformy sieciowej. W istocie C# jest rodzajem C++ i pomimo szeregu fundamentalnych różnic języki C# i C++ pokrywają się w około 90%. Prawdopodobnie minie dużo czasu, zanim C# stanie się poważnym konkurentem C++; ale nawet jeśli tak, to znajomość języka C++ będzie znaczącą zaletą.

C++ to język programowania ogólnego przeznaczenia. Jego naturalnym zakresem jest szeroko rozumiane programowanie systemowe. Ponadto C++ jest z powodzeniem stosowany w wielu obszarach aplikacji, które wykraczają daleko poza określony zakres. Implementacje C++ są teraz dostępne na każdej maszynie, od najprostszego mikrokomputera do największego superkomputera i dla praktycznie wszystkich systemów operacyjnych.

Powstanie i ewolucja języka C++

Bjorn Stroustrup jest twórcą języka C++ i twórcą pierwszego tłumacza. Jest pracownikiem AT&T Bell Laboratories Research Computing Center w Murray Hill (New Jersey, USA). Uzyskał tytuł magistra matematyki i inżynierii komputerowej na Uniwersytecie Aarus (Dania) oraz doktorat z informatyki na Uniwersytecie Cambridge (Anglia). Specjalizuje się w systemach rozproszonych, systemach operacyjnych, modelowaniu i programowaniu. Wraz z M. A. Ellisem jest autorem kompletnego przewodnika po języku C++ - "A Guide to C++ with Notes".

Oczywiście C++ wiele zawdzięcza językowi C, który jest zachowany jako jego podzbiór. Zachowane są również wszystkie niskopoziomowe narzędzia zawarte w C, zaprojektowane do rozwiązywania najbardziej palących problemów programowania systemu. C z kolei wiele zawdzięcza swojemu poprzednikowi, BCPL. Komentarz języka BCPL został przywrócony do C++. Innym źródłem inspiracji był język SIMULA-67; to od niego zapożyczono pojęcie klas (wraz z klasami pochodnymi i funkcjami wirtualnymi). Zdolność C++ do przeciążania operatorów i swoboda umieszczania deklaracji wszędzie tam, gdzie operator może się pojawić, przypomina język Algol-68.

Wcześniejsze wersje języka, zwane „C z klasami”, były używane od 1980 roku. Język ten powstał, ponieważ autor musiał pisać programy symulacyjne sterowane przerwaniami. Język SIMULA-67 jest do tego idealny, oprócz wydajności. Do dużych zadań modelowania używano języka „C z klasami”. Następnie możliwości pisania na nim programów, dla których zasoby czasowe i pamięciowe są krytyczne, zostały poddane rygorystycznym testom. W tym języku brakowało przeciążania operatorów, referencji, funkcji wirtualnych i wielu innych funkcji. Po raz pierwszy C++ opuścił grupę badawczą, w której pracował autor, w lipcu 1983 roku, ale w tym czasie wiele funkcji C++ nie było jeszcze opracowanych.

Nazwa C++ (C plus plus) została ukuta przez Ricka Maskittiego latem 1983. Nazwa ta odzwierciedla ewolucyjny charakter zmian w języku C. Zapis ++ odnosi się do operacji inkrementacji C. Nieco krótsza nazwa C+ to błąd składni. Ponadto był już używany jako nazwa zupełnie innego języka. Semantycy C uważają, że C++ jest gorszy niż ++C. Język nie nazywa się D, ponieważ jest rozszerzeniem C i nie próbuje rozwiązywać żadnych problemów przez porzucanie funkcji C. Inną interesującą interpretację nazwy C++ można znaleźć w dodatku do .

C++ został pierwotnie pomyślany tak, aby autor i jego przyjaciele nie musieli programować w asemblerze, C lub innych nowoczesnych językach wysokiego poziomu. Jego głównym celem jest uproszczenie i uprzyjemnienie procesu programowania dla indywidualnego programisty. Do niedawna nie było planu rozwoju C++ na papierze. Projekt, realizacja i dokumentacja szły ręka w rękę. Nigdy nie było „projektu C++” ani „komitetu projektowego C++”. Dlatego język ewoluował i nadal ewoluuje w taki sposób, aby przezwyciężyć wszystkie problemy, które napotkali użytkownicy. Impulsem do rozwoju są również dyskusje autora o wszelkich problemach z przyjaciółmi i współpracownikami.

Od czasu opublikowania pierwszego wydania tej książki język C++ przeszedł znaczące zmiany i udoskonalenia. Chodzi głównie o ujednoznacznienie przeciążenia, łączenie i zarządzanie pamięcią. Wprowadzono jednak drobne zmiany w celu zwiększenia zgodności z językiem C. Wprowadzono również pewne uogólnienia i znaczące rozszerzenia, takie jak dziedziczenie wielokrotne, funkcje składowe ze specyfikacjami statycznymi i stałymi, chronione składowe (chronione), szablony typów i obsługa specjalnych sytuacje. Wszystkie te rozszerzenia i ulepszenia miały na celu uczynienie z C++ języka, w którym można tworzyć i używać bibliotek. Wszystkie zmiany zostały opisane w .

Inne rozszerzenia wprowadzone w latach 1985-1991 (takie jak wielokrotne dziedziczenie, statyczne funkcje składowe i czysto wirtualne funkcje) wyłoniły się z uogólnień doświadczenia programowania w C++, a nie z innych języków.

Rozszerzenia języka dokonane w ciągu tych sześciu lat miały przede wszystkim na celu zwiększenie wyrazistości C++ jako języka abstrakcji danych i programowania obiektowego w ogóle, a także jako środka do tworzenia wysokiej jakości bibliotek ze zdefiniowanymi przez użytkownika typami danych.

Około 1987 roku stało się jasne, że prace nad standaryzacją C++ są nieuchronne i że należy natychmiast rozpocząć ich tworzenie.

AT&T Bell Laboratories było głównym współtwórcą tej pracy. Około stu przedstawicieli około 20 organizacji studiowało i komentowało to, co stało się nowoczesną wersją podręcznika referencyjnego i materiału źródłowego dla standaryzacji ANSI. C++. Ostatecznie, z inicjatywy Hewlett-Packarda, w grudniu 1989 r., w ramach ANSI utworzono Komitet X3J16. Oczekuje się, że prace normalizacyjne C++ w ANSI (American Standard) staną się integralną częścią prac normalizacyjnych ISO (International Standards Organization).

C++ ewoluował wraz z rozwojem niektórych podstawowych klas.

Historia stworzenia

Język powstał na początku lat 80., kiedy pracownik Bell Labs, Björn Stroustrup, opracował szereg ulepszeń języka C na własne potrzeby. Kiedy Stroustrup rozpoczął pracę w Bell Labs pod koniec lat 70. nad problemami w teorii kolejek (w odniesieniu do modelowania rozmów telefonicznych), odkrył, że próby wykorzystania istniejących wówczas języków modelowania były nieskuteczne, a użycie wysoce wydajnych języków maszynowych były zbyt trudne ze względu na ich ograniczoną wyrazistość. Na przykład język Simula ma funkcje, które byłyby bardzo przydatne do tworzenia dużego oprogramowania, ale jest zbyt wolny, a język BCPL jest wystarczająco szybki, ale zbyt zbliżony do języków niskiego poziomu i nie nadaje się do tworzenia dużego oprogramowania.

Przywołując doświadczenia swojej pracy doktorskiej, Stroustrup postanowił uzupełnić język C (następca BCPL) o możliwości dostępne w języku Simula. Język C, będący podstawowym językiem systemu UNIX, na którym działały komputery Bell, jest szybki, bogaty w funkcje i przenośny. Stroustrup dodał do tego możliwość pracy z klasami i obiektami. W rezultacie praktyczne problemy modelowania okazały się dostępne zarówno pod względem czasu opracowania (dzięki wykorzystaniu klas typu Simula), jak i czasu obliczeń (ze względu na prędkość C). Pierwszymi dodatkami do C były klasy (z enkapsulacją), dziedziczenie klas, silne sprawdzanie typów, funkcje inline i domyślne argumenty. Wczesne wersje języka, pierwotnie nazywane „C z klasami”, są dostępne od 1980 roku.

Tworząc C z klasami, Stroustrup napisał program cfront, kompilator, który konwertuje kod źródłowy C z klasami na zwykły kod źródłowy C. Umożliwiło to pracę nad nowym językiem i wykorzystanie go w praktyce, korzystając z infrastruktury już dostępnej w UNIX do rozwoju w C. Nowy język, niespodziewanie dla autora, zyskał dużą popularność wśród kolegów i wkrótce Stroustrup nie mógł już go osobiście wspierać, odpowiadając na tysiące pytań.

Tworząc C++, Bjorn Stroustrup chciał
  • Uzyskaj uniwersalny język ze statycznymi typami danych, wydajnością i przenośnością C.
  • Bezpośrednio i kompleksowo obsługuje wiele stylów programowania, w tym programowanie proceduralne, abstrakcję danych, programowanie obiektowe i programowanie ogólne.
  • Daj programiście wolność wyboru, nawet jeśli daje mu to możliwość dokonania błędnego wyboru.
  • Zachowaj kompatybilność z C tak bardzo, jak to możliwe, umożliwiając w ten sposób łatwe przejście z programowania do C.
  • Unikaj pomyłek między C i C++: każda konstrukcja dozwolona w obu językach musi oznaczać to samo w każdym z nich i prowadzić do tego samego zachowania programu.
  • Unikaj funkcji, które są zależne od platformy lub nie są uniwersalne.
  • „Nie płać za to, czego nie używasz” — żadna funkcja językowa nie powinna powodować obniżenia wydajności programów, które jej nie używają.
  • Nie wymagają zbyt skomplikowanego środowiska programistycznego.

Wybór C jako podstawy do stworzenia nowego języka programowania tłumaczy się tym, że język C:

1. jest językiem uniwersalnym, zwięzłym i stosunkowo niskiego poziomu;
2. nadaje się do rozwiązywania większości problemów systemowych;
3. wykonywane wszędzie i na wszystkim;
4. interfejsy ze środowiskiem programistycznym UNIX.

— B. Stroustrupa. Język programowania C++. Sekcja 1.6

Pomimo wielu dobrze znanych niedociągnięć języka C, Stroustrup wybrał go jako bazę, ponieważ „C ma swoje problemy, ale język opracowany od zera miałby je, a my znamy problemy C”. Ponadto umożliwiło to szybkie uzyskanie prototypu kompilatora (cfront), który tłumaczył tylko dodane elementy składni na oryginalny język C.

Wraz z rozwojem C++ włączono inne funkcje, które nakładały się na możliwości konstrukcji C, w związku z czym wielokrotnie podnoszona była kwestia porzucenia zgodności języka przez usunięcie przestarzałych konstrukcji. Jednak kompatybilność została zachowana z następujących powodów:

  • zachowanie obecnego kodu, oryginalnie napisanego w C i bezpośrednio przeniesionego do C++;
  • wyeliminowanie konieczności przekwalifikowania programistów, którzy wcześniej studiowali C (muszą tylko nauczyć się nowych narzędzi C++);
  • eliminacja pomyłek między językami, gdy są one używane razem („jeśli dwa języki są używane razem, ich różnice powinny być minimalne lub tak duże, aby nie można było pomylić języków”).

Do 1983 roku do języka dodano nowe funkcje, takie jak funkcje wirtualne, przeciążanie funkcji i operatorów, referencje, stałe, kontrola użytkownika nad zarządzaniem wolną pamięcią, ulepszone sprawdzanie typu i nowy styl komentarzy (//). Powstały język nie jest już tylko rozszerzoną wersją klasycznego C i został przemianowany z C z klasami na „C++”. Jego pierwsze komercyjne wydanie miało miejsce w październiku 1985 roku.

Wynikowa nazwa języka pochodzi od jednoargumentowego postfiksowego operatora inkrementacji C++ (zwiększenie wartości zmiennej o jeden).

Przed rozpoczęciem oficjalnej standaryzacji język został opracowany głównie przez Stroustrup w odpowiedzi na prośby społeczności programistów. Funkcję standardowych opisów językowych pełniły drukowane prace Stroustrupa dotyczące C++ (opis języka, instrukcja obsługi itd.).

Historia standardów

W 1985 roku ukazało się pierwsze wydanie The C++ Programming Language, zawierające pierwszy opis języka, co było niezwykle ważne ze względu na brak oficjalnego standardu.


W 1989 została wydana wersja C++ 2.0. Jego nowe funkcje obejmowały wielokrotne dziedziczenie, klasy abstrakcyjne, statyczne funkcje składowe, funkcje stałe i chronione elementy członkowskie. W 1990 roku opublikowano „Commented Reference Guide to C++”, który później stał się podstawą standardu. Ostatnie aktualizacje obejmowały szablony, wyjątki, przestrzenie nazw, nowe rzutowania i typ logiczny.

Biblioteka standardowa C++ również ewoluowała wraz z nią. Pierwszym dodatkiem do standardowej biblioteki C++ były strumienie I/O, zapewniające możliwość zastąpienia tradycyjnych funkcji C printf i scanf. Później najbardziej znaczącym rozwojem standardowej biblioteki było włączenie Standardowej Biblioteki Szablonów.

W 1998 roku norma językowa ISO/IEC 14882:1998 (znana jako C++98) została opublikowana przez C++ Standards Committee (grupa robocza ISO/IEC JTC1/SC22/WG21). Standard C++ nie opisuje sposobu nazywania obiektów, niektórych szczegółów obsługi wyjątków i innych funkcji związanych z implementacją, co powoduje, że kod obiektowy generowany przez różne kompilatory jest niezgodny. Jednak wiele standardów zostało stworzonych przez strony trzecie dla określonych architektur i systemów operacyjnych.

W 2005 roku opublikowano Biblioteczny Raport Techniczny 1 (w skrócie TR1). Chociaż nie jest to oficjalnie część standardu, raport opisuje rozszerzenia standardowej biblioteki, których autorzy spodziewali się uwzględnić w następnej wersji języka C++. Obsługa TR1 poprawia się w prawie wszystkich obsługiwanych kompilatorach C++.

Od 2009 roku trwają prace nad aktualizacją poprzedniego standardu, wstępną wersją nowego standardu była najpierw C++09, a rok później C++0x, dziś C++11, która zawierała dodatki do rdzenia językowego i rozszerzenie do standardowej biblioteki, zawierające większość TR1.

C++ wciąż ewoluuje, aby sprostać współczesnym wymaganiom. Jedną z grup, które rozwijają język C++ i przesyłają do komitetu standaryzacyjnego C++ propozycje jego ulepszenia jest Boost, która zajmuje się również ulepszaniem możliwości języka poprzez dodawanie do niego funkcji metaprogramowania.

Nikt nie posiada praw do języka C++, jest bezpłatny. Jednak sam dokument standardu językowego (z wyjątkiem wersji roboczych) nie jest dostępny bezpłatnie.