Historie a vývoj jazyka C (od C až po
C#)
(kolokviální
práce do předmětu
Historie a vývojové trendy ve výpočetní technice, Pavel Černohorský,
2003)
Programovací jazyk C
Vraťme se nyní na chvilku do
šedesátých let minulého století, do doby
kdy v USA probíhaly veliké změny. Nás ale budou zajímat události jiné,
které určitě nebyly tolik známy mezi veřejností, ale které přesto možná
nepřímo ovlivnily vývoj společnosti, ve které dnes žijeme. Dalo by se
říct, že se v téhle době totiž začal rodit programovací jazyk, který ve
značné míře určil směr, kterým se bude ubírat programování a tím i
způsob využití počítačů, které nesporně ovlivňují život každého z nás,
po několik dalších dekád.
Počátky jazyka C byly neoddělitelně spjaty s operačním systémem
UNIX,
který vznikl roku 1968 v
Bellových
laboratořích v Murray Hill, New
Jersey. Brzy po vzniku UNIXu začal Ken Thompson na počítači
PDP-7 firmy
DEC
vytvářet jednoho z předchůdců jazyka C - programovací jazyk B.
Podívejme se ale ve stručnosti ještě kousek víc do historie na větší
část vývojové větve „Céčka“. V roce 1963 byl na univerzitách Cambridge
a University of London vytvořen jazyk CPL (oficiálně Combined
Programming Language, neoficiálně však prý zkratka původně vznikla ze
slov "Cambridge Plus London"), který částečně vycházel z Algolu 60. Byl
však prý příliš složitý k naučení i k implementaci a tak byl proto o
čtyři roky později, roku 1967, na univerzitě v Cambridge zjednodušen
Martinem Richardsem s cílem zachovat jeho dobré vlastnosti a vznikl tak
jazyk BCPL (Basic Combined Programming Language). Tento jazyk byl
beztypový (typ byl určován podle kontextu využití proměnné). Pro
ilustraci přikládám ukázku kódu pro výpočet faktoriálů prvních 10ti
přirozených čísel v jazyce BCPL:
// FACTORIAL
GET "LIBHDR"
LET START () BE $(
LET F(N) = N=0 -> 1, N*F(N-1)
FOR I = 1 TO 10 DO WRITEF("F(%N), = %N*N", I, F(I))
FINISH
$)
(kód je převzat z otevřeného archivu
konferencí spolku Lysator, The Academic Computer Society při Linköping
University ve Švédsku [6] - kód psal Alan Watson)
A nyní se konečně dostáváme k
programovacímu jazyku B, který byl
vyvinut, jak již bylo předesláno, Kenem Thompsonem z Bellových
laboratoří. Tento jazyk byl stejně jako jeho předchůdce beztypový a
stejně jako jeho předchůdce trpěl několika významnými neduhy. Jednou z
největších bylo, že soustavným zjednodušováním vznikl jazyk limitovaný,
vhodný pouze pro řešení určitých problémů. Později, po příchodu
počítače
PDP-11 byl
jazyk přeimplementován spolu s UNIXem pro tento
stroj (pro srovnání s dnešními počítači, přestože byl PDP-11 o hodně
lepší než předcházející PDP-7, měl pouze 25KB paměti, ze kterých systém
využíval 16KB, a byl v něm jeden pevný disk velikosti 512KB). Při
tehdejším přenosu UNIXu z PDP-7 na PDP-11 byl vážným problémem fakt, že
UNIX byl napsán v jazyce nízké úrovně (přesněji jazyce symbolických
instrukcí) a byl proto špatně přenositelný. Byly proto návrhy pro
přepis UNIXu do jiného jazyka (B byl kandidátem), ale tyto myšlenky
byly smeteny ze stolu kvůli tomu, že B byl pomalý a nevhodný pro psaní
operačního systému (problémy s adresováním po slovech, ne po bytech
jako počítač PDP-11). Toto byly rámcově nejdůležitější důvody pro
počátek práce na následovníku jazyka B v roce 1971 - ne zrovna
nápaditě, však ve shodě s vývojem, pojmenovaném C.
Autorem jazyka C se stal Dennis M. Ritchie
[13] z
Bellových laboratoří. Roku
1972 tedy světlo světa spatřil nový programovací jazyk, který se
navrátil k některým obecným principům CPL, které byly v BCPL a B
ztraceny. Byl tedy vytvořen jazyk s bohatými datovými typy, přičemž
zůstala zachována jednoduchost a přímý přístup k hardware. Pro
ilustraci rozdílů jazyků BCPL, B a C zde ještě uvedu jeden kousek kódu
napsaný v těchto třech programovacích jazycích (kód byl převzat beze
změny, pozornější z vás si však jistě všimnou, že obsahuje chybu a
nepočítá to, co o sobě hlásá, pro ilustraci rozdílů mezi jazyky však
postačí):
kód psaný v jazyce C:
/* infact -- initializes elements from fact[0] = 0! up to
* fact[n] = n!. Returns n!. */
float infact (n) int n;
/* or, of course, the newer float infact (int n) */
{
float f = 1;
int i;
extern float fact[];
for (i = 0; i <= n; ++i)
fact[i] = f *= i;
return f;
}
#define TOPFACT 10
float fact[TOPFACT+1];
kód psaný v jazyce B:
infact (n)
{
auto f, i, j; /* no initialization for auto variables */
extrn fact; /* "What would I do differently if designing
* UNIX today? I'd spell creat() with an e."
* -- Ken Thompson, approx. wording */
f = 1.; /* floating point constant */
j = 0.;
for (i = 0; i <= n; ++i) {
fact[i] = f =#* j; /* note spelling =#* not #*= */
j =#+ 1.; /* #+ for floating add */
}
return (f); /* at least, I think the () were required */
}
TOPFACT = 10; /* equivalent of #define, allows numeric values only */
fact[TOPFACT];
kód psaný v jazyce BCPL:
MANIFEST ${ TOPFACT = 10 $) // Equivalent of "const int TOPFACT = 10"
LET infact (n) = VALOF
$(
LET f, j = 1., 0.
FOR i = 0 TO n // Declares i for the next block only
$(
f #*:= j; // := is assign, = is compare
fact!i := f; // assignment doesn't return a value
j #+:= 1.
$)
RESULTIS f
$)
AND fact = VEC TOPFACT; // As in B, allocates 0 to TOPFACT
(kódy jsou převzaty z otevřeného
archivu konferencí spolku Lysator, The Academic Computer Society při
Linköping University ve Švédsku [6] - kód pro C a B
psal Mark Brader,
kód pro BCPL psal Clive D.W. Feather)
Dennis Ritchie byl ve své době znám
jako systémový programátor,
pracoval například na vývoji operačních systémů a na překladačích
programů. Není proto divu, že navrhl jazyk C jako relativně
nízkoúrovňový jazyk, vhodný jak k přesnému vyjádření algoritmu a k
systémovému programování, tak jako jazyk schopný abstrahovat od
počítačové architektury. Není mým cílem vypisovat všechny vlastnosti
jazyka C, avšak zmíním alespoň ty základní:
- rychlost - kód generovaný většinou kompilátorů je velmi efektivní
- strukturovanost - jazyk poskytuje všechny důležité struktury
moderního programovacího jazyka - if, switch, různé druhy cyklů
- možnost manipulace s daty na úrovni bitů
- možnost využití ukazatelů a jejich aritmetiky
- modulární programování - snadná rozšiřitelnost a
přizpůsobitelnost jazyka
- přenositelnost
- a mnoho dalších...
Jazyk C se stal po velmi krátké době
natolik populární, že do něj byl přepsán téměř celý UNIX a další
programy. Zároveň začaly vznikat překladače nového jazyka pro různý v
té době dostupný hardware. To s sebou však neslo problémy - jazyk C
nebyl nijak standardizován a mnoho překladačů si při jeho
implementaci přidalo různé další specifické vlastnosti. Tím ale vznikly
potíže s přenositelností kódu, jednou z velkých předností „Céčka“.
V průběhu 70tých let až do roku 1978 se jazyk C vyvíjel do formy,
kterou bychom dnes pravděpodobně nazvali „tradiční C“, někdy též
„pre-ANSI C“. Ve zmiňovaném roce vydalo nakladatelství Prentice-Hall
knihu Briana Kernighana a Dennise Ritchieho
The C Programming Language, později
též běžně označovanou „K&R C“. Dalo by se říct, že se tato kniha
stala první neoficiální „normou“ jazyka C a tak překladače vytvořené po
jejím uveřejnění (a upravené starší překladače) již obsahovaly
všeobecně sjednocené nové vlastnosti. Pro zajímavost uvedu, že v této
době obsahoval jazyk 27 klíčových slov.
K další významné změně v rysech jazyka a k dalšímu sjednocování došlo
roku 1982, kdy Americký institut národních standardů (American National
Standard Institute - ANSI
[10]) ustanovil komisi
X3J11 pro standardizaci jazyka C, která měla za úkol sestavit normu pro
jazyk i jeho knihovny (jazyk sám o sobě je totiž, dalo by se říct,
velmi jednoduchý, jeho síla a schopnosti spočívají právě v bohatosti
knihoven) a vytvořit tak jednoznačnou a na hardwaru nezávislou definici
jazyka. A tak byla roku 1989 formálně přijata norma American National
Standard X3.159-1989, spíše známá pod názvem ANSI C. Tato norma si
kladla za cíl ujasnit některé nepřesnosti jazyka vzniklé při rozvoji
jednotlivých kompilátorů, rozšířit jazyk o nové vlastnosti, které se od
roku 1978 objevily a přitom měla být zachována jednoduchost jazyka.
Požadavky byly v podstatě splněny, pro zajímavost dodám, že tato verze
jazyka již obsahovala 47 klíčových slov. Norem ANSI bylo během let
více, ale tato je nejznámější a nejpoužívanější z nich. Byla zároveň
brzy pro svém vzniku převzata organizací ISO (International
Organization for Standardization
[11]) i jako vzor
pro evropskou normu označovanou ISO/IEC 9899-1990. V současné době
nejnovější normou je ISO/IEC 9899:1999 (pro zajímavost má norma 550
stran a lze se na ni podívat například na adrese
[12]),
bohužel trvalo poměrně dlouho, než ji nejčastěji rozšířené překladače
začaly podporovat a ještě dnes se můžeme setkat s neúplnou či špatnou
podporou této specifikace. V době psaní tohoto pojednání (listopad
2003) se však již dá programovat podle této normy a nové překladače by
neměly mít větší problémy.
Programovací jazyk C++
Teď, když jsme se podrobněji
seznámili s jednou z legend počítačového světa, která žije již třicet
let (což je v oblasti výpočetní techniky opravdu velmi dlouhá doba),
můžeme se podívat i na mladšího bratříčka opěvovaného „Céčka“.
Pojmenování mladší bratříček se však pro jazyk C++ moc nehodí, možná
spíše mladší, ale „chytřejší a tlustší“ bratříček. S jistou nepřesností
by se totiž dalo říct, že je spíše nadmnožinou jazyka C. Kromě spousty
vylepšení zavádí jedno hlavní, které z něj dělá skoro až jiný
programovací jazyk - možnost objektového přístupu.
Jazyk C++ je tedy odvozen z velké části z jazyka C, dále pak třeba z
jazyka
Algol 68
(přetěžování operátorů, deklarování proměnné blízko jejímu prvnímu
využití), z jazyka
Simula
67 (princip tříd, virtuálních funkcí) a z dalších.
Autorem C++ se stal Bjarne Stroustrup z Bellových laboratoří, který na
jazyce začal pracovat na počátku 80tých let. Původně byl jazyk C++
vyvíjen pro vyřešení jedné konkrétní simulace s velice specifickými
požadavky, které napovídaly spíše na využití jiného jazyka než C. Do
roku 1983 přidal Stroustrup další vlastnosti do jazyka C a vzniklo tak
něco, co on sám nazval "C with Classes" (C s třídami). Roku 1983 nový
jazyk poprvé opustil prostory Bellových laboratoří a na svou pouť
světem se vydal pod označením C++, které bylo tehdy prvně použito.
A jak to bylo s dalším vývojem a standarty? Nedlouho po publikování
jazyka, přesněji v říjnu 1985 vyšla také kniha Bjarnea Stroustrupa
The C++ Programming Language (za
povšimnutí stojí analogie se jménem knihy Kernighana a Ritchieho) a
došlo k prvnímu uvolnění komerčního překladače jazyka C++. Do léta roku
1987 pak procházel jazyk přirozeným vývojem a úpravami, přesto však
nedošlo ke ztrátě zpětné kompatibility s C a tak mohli programátoři
celého světa dále využívat milióny svých už jednou těžce napsaných
řádků kódu. V roce 1989 byl, jak už bylo zmíněno v předcházející
kapitole, standardizován jazyk C, což posloužilo zároveň jako příspěvek
k přesnému ujasnění strukturovanosti C++. Od roku 1990 začala pracovat
komise ANSI institutu a organizace ISO pod označením X3J16 (jejímž
členem i sám tvůrce jazyka) na vytvoření standardu s cílem ujednotit
vlastnosti jazyka a umožnit tak vznik překladačů schopných bezpečně
přeložit přenositelný kód. Práce komise trvala větší část 90tých let,
kdy zažilo C++ dobu svého největšího rozmachu a stalo se
nejpoužívanějším jazykem pro vývoj aplikací této doby. Koncept
standardu ANSI byl nakonec vydán roku 1997 a vlastní norma byla
schválena i organizací ISO jako ISO/IEC 14882:2003. Někdy je norma
souhrnně označována jako ANSI/ISO C++. V současné době je nejnovější
dostupná verze normy ISO/IEC 14882:2003, vydaná tento rok.
Ještě bych si zde dovolil odkázat na stránky Bjarnea Stroustrupa -
Stroustrup: FAQ
[14], kde vysvětluje některé své
zajímavé názory a postoje ohledně C++, jeho minulosti i budoucnosti ve
světě dalších novějších jazyků (dozvíte se například názory Bjarnea na
garbage collection (automatický management paměti použitý například v
platformě .NET a tím v jazyku C#), nebo o tom, že Bjarne vůbec
neočekával jakýkoliv úspěch svého jazyka).
Programovací jazyk C#
A jak začít pojednání o historii
jazyka C# (čteno [cí-šarp])? Předchozí kapitolu o C++ jsem začal
srovnáním s C, teoreticky bych tedy měl teď začít srovnávat jazyka C# s
jazykem C++, ale nebude tomu tak. Kdybych se snažil srovnat jazyk C# a
C++, bylo by to jako srovnávat dva úplně různé a skoro nijak
nesouvisející jazyky (nepočítáme-li jméno), ať si firma Microsoft,
tvůrce C#, tvrdí co chce (označuje totiž C# za vývojové pokračování C a
C++, proto je C# také zařazen do tohoto pojednání). C# toho má totiž s
C++ společného mnohem méně, nežli mělo kdysi C++ s C. C++ bylo, jak
bylo již řečeno, nadmnožinou C, avšak kompilátorem C# byste program
psaný v C++ rozhodně nezkompilovali. Pokud bych měl jazyk C# k něčemu
přirovnat, srovnal bych ho pravděpodobně s Javou, které měl také, jak
se říká, být přímým konkurentem (marketing společnosti Microsoft zde
opravdu výrazně zasáhl, velmi brzy po uvolnění C# byly k dispozici i
nástroje pro konverzi zdrojových kódů z Javy do C#).
Ale nyní již k vlastní historii C#, která je neoddělitelně spjata s
platformou Microsoft .NET. Vraťme se do roku 1993, kdy byly uvedeny
modely COM (Component Object Model - softwarová architektura umožňující
vystavět aplikace z binárních komponent) a DCOM (Distributed Component
Object Model - protokol umožňující komunikovat softwarovým komponentám
přes síť (včetně internetu pomocí HTTP protokolu)). Tyto dva modely se
postupem času roku 1997 spojily do COM+, což bylo rozšíření původního
COM rozhraní. Umožňovalo softwarovým komponentám psaným v různých
jazycích, aby spolu komunikovaly. Tato myšlenka byla použita roku 1999,
kdy se Microsoft zmiňuje o technologii .NET - platformě skládající ze z
tak zvaného CLR (Common Language Runtime) a z knihovny tříd systému
.NET Framework (někdy nazývaných Base Class Library - BCL). CLR má být
společným běhovým prostředím pro programy psané v různých jazycích,
díky CLR spolu mohou jednotlivé části programu (nebo celé programy)
navzájem spolupracovat, přestože byly napsány každý v jiném
programovacím jazyce. Toho je dosaženo tím, že aby programovací jazyk
mohl produkovat kód kompatibilní s CLR, musí vyhovovat specifikacím CLS
(Common Language Specifications). A zde právě přichází na řadu C#. Je
to první jazyk navržený přesně podle systému CLS a tím umožňuje asi
nejlépe využít veškeré jeho možnosti. Přestože s jistými úpravami
vyhovuje specifikaci CLS více programovacích jazyků, které jsou pro
prostředí .NET upravovány, C# je tomuto prostředí šitý přesně na míru.
Pokud kompilujete program v C#, výsledkem není přímo strojový kód
proveditelný procesorem, ale kód v jazyku MSIL (Microsoft Intermediate
Language), který je teprve pomocí CLR přeložen do nativního kódu
procesoru. Nejedná se tedy o jazyk interpretovaný, jako třeba Java, ze
které se C# hodně inspiroval, ale ve výsledku přímo o spustitelný kód,
i když generovaný automaticky až těsně před spuštěním programu.
Z hlediska vývoje, bych teď uvedl několik dat. Dne 22. června 2000
uvedl Bill Gates na konferenci Forum 2000 svou vizi platformy .NET.
(přestože první beta verze byla hotová již v roce 1999). O 4 dny
později, tj. 26. června 2000, ohlašuje Microsoft uvedení jazyka C# a
počátek jeho standardizace. V první polovině roku 2001 je dokončení
kompilátoru pro jazyk C# a celá platforma .NET 1.0 je oficiálně
uvolněna pro veřejnost 15. ledna 2002 (partnerům MS byla dostupná již
mnohem dříve, včetně všech vývojových beta verzí). Finální verze normy
ISO pro jazyk C# potom byla publikována 2. dubna 2003 jako ISO/IEC
23270. V současné době jsou k dispozici kompilátory jazyka C# verze 1.1
(např. Visual Studio 2003) a k nahlédnutí na stránkách společnosti
Microsoft je návrh specifikace jazyka C# 2.0, který má obsahovat
spoustu nových vlastností, jako jsou například Generika (obdoba
Templates v C++). Koho by tato problematika zajímala více, doporučuji
nahlédnout na MSDN (Microsoft Development Network)
[9].
Nový přístup k překladu programu do strojového kódu přímo před jeho
spuštěním má své příznivce i odpůrce a teprve čas ukáže, kdo měl
pravdu. Ale prozatím vše nasvědčuje tomu, že se platforma .NET a s ní i
jazyk C# rozšíří. Platformu začaly totiž podporovat i firmy jako
Borland (oznámil podporu v únoru roku 2002) a již vydal (velmi nedávno
- 6. června 2003) vlastní verzi vývojového prostředí pro jazyk C#.
Zároveň probíhá převod platformy .NET a jazyku C# na OS Linux - za
zmínku stojí např. projekt Mono
[15].
Pokud bude vývoj pokračovat současným tempem, jazyk C# se asi brzy
dostane do povědomí jako silný nástroj pro vývoj aplikací všeho druhu a
možná právě jemu bude patřit budoucnost.
Použité zdroje:
[1] - Kolektiv autorů: Programování v jazyku C (JZD
Agrokombinát Slušovice, 1987)
[2] - Samuel P. Harbison a Guy L. Steele Jr.: Referenční příručka
jazyka C (Science, 1996)
[3] - William H. Murray & Chris H. Pappas: Microsoft C/C++ 7: The
complete Reference (McGraw-Hill, 1992)
[4] - Dr. Harvey M. Deitel & Paul J. Deitel: C How to Program
- Third Edition (Deitel & Associates, Inc., 2001)
[5] - Tom Archer: Myslíme v jazyku C# (Grada, 2001)
[6] - Lysator, The Academic Computer Society - http://www.lysator.liu.se
[7] - HitMill (IT Training for Students and Developers) - http://www.hitmill.com
[8] - CplusPlus.com - http://www.cplusplus.com
[9] - MSDN (Microsoft Development Network) - http://msdn.microsoft.com
Zajímavé odkazy:
[10] - American National Standard Institute - http://www.ansi.org
[11] - International Oraganization for Standardization
- http://www.iso.org
[12] - ISO/IEC 9899:1999 - http://www.cl.cam.ac.uk/~mgk25/volatile/ISO-C-FDIS.1999-04.pdf
[13] - Dennis M. Ritchie Home Page - http://www.cs.bell-labs.com/who/dmr/index.html
[14] - Stroustrup: FAQ - http://www.research.att.com/~bs/bs_faq.htm
[15] - The Mono Project - http://www.go-mono.com