C (programovací jazyk) - C (programming language)


z Wikipedie, otevřené encyklopedie

C
Text ve světle modré serif tiskacími písmeny na bílém pozadí a velmi velké světle modré sans-serif písmenem C.
Programovací jazyk C (často označované jako „K & R“), klíčovou knihu o C
Paradigma Imperativ ( procesní ), strukturované
Navrhl Dennis Ritchie
Vývojář Dennis Ritchie a Bell Labs (tvůrci); ANSI X3J11 ( ANSI C ); ISO / IEC JTC1 / SC22 / WG14 (ISO C)
se poprvé objevila 1972 ; Před 46 lety ( 1972 )
stabilní verze
C18 / 06 2018 ; před 6 měsíci ( 2018 - 06 )
Typing disciplína Statická , slabý , manifest , nominální
OS Cross-platform
přípony souborů .c , .h
hlavními implementace
K & R, GCC , Clang , Intel C , Microsoft Visual C ++ , Pelles C , Watcom C
dialekty
Cyclone , Unified Parallel C , Split-C , Cilk , C *
ovlivněny
B ( BCPL , CPL ), ALGOL 68 , montáž , PL / I , FORTRAN
ovlivněn
Četné : AMPL , AWK , csh , C ++ , C- , C # , Objective-C , D , Go , Java , JavaScript , Julia , Limbo , LPC , Perl , PHP , Pike , výroba , Python , Ring , Rust , Seed7 , Vala , Verilog (HDL), Nim

C ( / s / , jako je tomu v písmene c ) je pro všeobecné účely , nezbytné počítač programovací jazyk , podporující strukturovaného programování , lexikální variabilní rozsah a rekurze , zatímco statického typu systém brání mnoha nežádoucí operací. Podle návrhu, C poskytuje konstrukty, které mapují účinně typické strojových instrukcí , a proto se nacházejí trvalé použití v aplikacích, které byla dříve kódované v assembleru , včetně operačních systémů , stejně jako různé aplikační software pro počítače od superpočítačůvestavěných systémů ,

C byl původně vyvinut Dennis Ritchie v letech 1969 a 1973 v Bell Labs , a použít k re-implementovat Unix operační systém. Od té doby se stal jedním z nejpoužívanějších programovacích jazyků všech dob, s C kompilátory od různých výrobců jsou k dispozici pro většinu stávajících počítačových architektur a operačních systémů. C byl standardizován podle American National Standards Institute (ANSI) od roku 1989 (viz ANSI C ) a následně ze strany Mezinárodní organizace pro normalizaci (ISO).

C je nezbytně nutné procedurální jazyk. To byl navržen tak, aby se sestavují pomocí relativně jednoduché kompilátor , aby low-level přístup k paměti , poskytovat jazykové konstrukty, které mapují účinně strojových instrukcí , a vyžadují minimální podporu run-time . Přes své schopnosti na nízké úrovni, jazyk byl navržen tak, aby podporovat cross-platform programování. Standardy -kompatibilní C program, který je napsán s přenositelností v mysli, může být sestaven pro velmi širokou škálu počítačových platforem a operačních systémů s několika změnami svého zdrojového kódu. Jazyk se stal k dispozici na velmi širokou škálu platforem, od vestavěných mikrořadičůpo superpočítače .

Přehled

Dennis Ritchie (vpravo), vynálezce C programovací jazyk, s Kenem Thompsonem

Jako většina imperativních jazycích v ALGOL tradici, C má zařízení pro strukturované programování a umožňuje lexikální proměnné rozsah a rekurze, zatímco statický typový systém brání mnoha nechtěných operací. V jazyce C, všechny spustitelný kód je obsažen uvnitř podprogramů , které se nazývají „funkce“ (i když ne v pravém slova smyslu funkcionální programování ). Parametry funkce jsou vždy předány podle hodnoty. Pass-By-Reference je simulována v C explicitně průchodu ukazatel hodnoty. C zdrojový text programu je volný formát , pomocí středník jako prohlášení zakončení a složenými závorkami pro seskupování bloků příkazů .

Jazyk C také vykazuje následující vlastnosti:

  • K dispozici je malé, pevně stanovený počet klíčových slov, včetně úplnou sadu ovládání průtoku primitivů: for, if/else, while, switch, a do/while. Uživatelsky definované jména nejsou odlišeny od klíčových slov jakéhokoli druhu Sigil .
  • Existuje velké množství aritmetických a logických operátorů, jako jsou například +, +=, ++, &, ~, atd.
  • Více než jeden úkol může být provedena v jediném příkazu.
  • Návratové hodnoty Funkce může být ignorovány, pokud není potřeba.
  • Psaní je statický , ale slabě vynucený : všechna data typu, ale může být provedena implicitní převody.
  • Prohlášení syntax kontext napodobuje využití. C nemá „definovat“ klíčové slovo; Místo toho prohlášení počínaje jménem typu se považuje za prohlášení. Neexistuje žádný „funkci“ klíčové slovo; místo toho, funkce je indikována v závorkách seznamu argumentů.
  • Uživatelem definované ( typedef) a sloučeniny typu jsou možné.
    • Heterogenní agregační datové typy ( struct) umožňují související datové prvky, které mají být přístupné a přidělen jako jednotka.
    • Union je struktura s překrývajícími členy; Pouze poslední člen uložen platný.
    • Array indexování je sekundární notace, definovaný v podmínkách ukazatel aritmetiky. Na rozdíl od structs, pole nejsou objekty prvotřídní; nemohou být postoupena nebo ve srovnání s použitím jednoduchých vestavěných operátorů. Neexistuje žádná „array“ klíčové slovo v použití nebo definici; místo toho, hranaté závorky označují pole syntakticky, například month[11].
    • Vyjmenované typy jsou možné s enumklíčovým slovem. Jsou volně k vzájemné záměně s celými čísly.
    • Řetězce nejsou samostatný typ dat, ale jsou obvykle realizovány jako null ukončený pole znaků.
  • Přístup k low-level do paměti počítače je možné převedením strojů adresy zadali ukazatelů .
  • Postupy (podprogramy nevracejí hodnoty) jsou zvláštní případ funkce s netypovou návratový typ void.
  • Funkce nemusí být v rámci lexikální rozsahu dalších funkcí.
  • Funkční a datové ukazatele povolit ad hoc run-time polymorfismus .
  • Preprocessor provádí makro definici, zdrojový kód začlenění souboru a podmíněné kompilace .
  • K dispozici je základní podoba modularity : soubory mohou být sestaveny odděleně a spojeny spolu s kontrolou nad nímž funkce a datové objekty jsou viditelné do jiných souborů pomocí statica externatributy.
  • Komplexní funkce, jako je I / O , řetězec manipulace a matematické funkce jsou důsledně přenesena do knihovny rutiny .

Zatímco C neobsahuje některé funkce nalezené v některých jiných jazycích, jako je orientace objektu nebo odvoz odpadu , mohou být tyto funkce implementovány nebo emulované v jazyce C, často prostřednictvím externích knihoven (např Boehm garbage collector nebo Object System GLib ) ,

Vztahy k ostatním jazykům

Mnoho později jazyky půjčovaly si přímo či nepřímo z C včetně C ++ , C # , Unixu C shell , D , Go , Java , JavaScript , Limbo , LPC , Objective-C , Perl , PHP , Python , Rust , Swift , Verilog a SystemVerilog ( popis hardware jazyky). Tyto jazyky byly vypracovány mnohé ze svých řídících struktur a dalších základních funkcí, z C. Většina z nich (s Python je nejdramatičtější výjimka) jsou také velmi syntakticky podobný C obecně, a mají tendenci kombinovat rozpoznatelný výraz a prohlášení syntax C s podkladovými systémy typu, datové modely a sémantiku, které mohou být zcela odlišné.

Dějiny

časné vývoje

Rok C standard
1972 Narození
1978 K & R C
1989/1990 ANSI C a ISO C
1999 C99
2011 C11
2017/2018 C18

Původ C je úzce svázán s vývojem Unix operačního systému, který byl původně realizován v assembleru na PDP-7 Dennis Ritchie a Ken Thompson, zahrnující několik nápadů ze strany kolegů. Nakonec se rozhodli portovat operační systém na PDP-11 . Původní PDP-11 verze Unix byl vyvinut v jazyce symbolických instrukcí. Vývojáři zvažovali přepisování systému pomocí jazyka B , Thompsona zjednodušená verze BCPL . Nicméně B neschopnost využít některé funkce PDP-11 je, zejména byte adresovatelnost, vedl k C. Název C byl zvolen pouze jako další po B.

Vývoj C byla zahájena v roce 1972 v systému PDP-11 Unix a nejprve objevil se v verze 2 Unix . Jazyk nebyl původně navržen s přenositelností v mysli, ale brzy se běžel na různých platformách, stejně: kompilátor pro Honeywell 6000 byl vypracován v prvním roce historii c je, zatímco IBM System / 370 portu brzy následovaly.

Také v roce 1972, velká část Unix byl napsán v C 1973, s přidáním structtypů, jazyk C stal natolik silná, že většina Unix jádra byl nyní v C.

Unix byl jeden z prvních operačních systémů jader realizovaných v jiném jazyce než češtině sestavy . Dřívější případy zahrnují Multics systém (který byl psán v PL / I ) a Master Control Program (MCP) pro Burroughs B5000 (který byl napsán v ALGOL ) v roce 1961. Kolem roku 1977, Ritchie a Stephen C. Johnson dělal další změny jazyk s cílem usnadnit přenositelnost operačním systémem Unix. Johnsonův Portable C sloužila jako základ pro několik implementací C na nových platformách.

K & R C

Kryt knihy, programovacím jazyku C , první vydání ze strany Brian Kernighan a Dennis Ritchie

V roce 1978, Brian Kernighan a Dennis Ritchie publikoval první vydání The C Programming Language . Tato kniha, známý C programátoři jako „K & R“, sloužil dlouhá léta jako neformální specifikace jazyka. Verze C, která se popisuje se běžně označuje jako K & R C . Druhé vydání knihy se vztahuje na pozdější ANSI C standard, popsané níže.

K & R představila několik jazykových funkcí:

  • Standardní I / O knihovny
  • long int datový typ
  • unsigned int datový typ
  • Složené operátory přiřazení formuláře (například ) byly změněny na formu (tj ) pro odstranění sémantické nejednoznačnost vytvořený konstrukty, jako jsou , které byly interpretovány jako (snižování podle 10) namísto případně určena (nechat být - 10).=op=-op=-=i=-10i =- 10ii = -10i

I po zveřejnění normy 1989 ANSI, na mnoho let K & R C stále považováno za „ nejmenšího společného jmenovatele “, ke kterému C programátoři omezily při maximální mobilitu byl žádoucí, protože mnoho starších překladače byly ještě v použití, a proto pečlivě psaný K & R C kód může být legální standard C stejně.

V dřívějších verzích C, pouze funkce, které vracejí jiné než typy intmusí být prohlášena, pokud jsou použity před definici funkce; Funkce používané bez předchozího prohlášení se předpokládá, že návrat typ int.

Například:

long some_function();
/* int */ other_function();

/* int */ calling_function()
{
    long test1;
    register /* int */ test2;

    test1 = some_function();
    if (test1 > 0)
          test2 = 0;
    else
          test2 = other_function();
    return test2;
}

Na inttypu Specifikátory které jsou zakomentovány by mohl být vynechán v K & R C, ale jsou nutné v pozdější normou.

Vzhledem k tomu, K & R funkce prohlášení neobsahovala žádné informace o argumenty funkce, parametry funkce kontroly typu nebyly provedeny, i když některé kompilátory vydá varovnou zprávu, pokud se místní funkce volána se špatným počtem argumentů, nebo je-li více hovorů na externí funkce použity různé počty nebo typy argumentů. Samostatné nástroje, jako je Unix má měkkou nástroje byly vyvinuty, které (mimo jiné) by mohl kontrolovat konzistenci použití funkce napříč více zdrojových souborů.

V letech po zveřejnění K & R C, několik funkcí, byly přidány k jazyku, podporované překladače od AT & T (zejména PCC ) a některých jiných výrobců. Ty zahrnovaly:

Velký počet rozšíření a nebylo dosaženo dohody o standardní knihovny , spolu s jazykem popularita a skutečnost, že ani Unix kompilátory přesně realizován specifikaci K & R, vedlo k nutnosti normalizace.

ANSI C a ISO C

Během pozdní 1970 a 1980, verze C byly implementovány pro širokou škálu sálových počítačů , minipočítačů a mikropočítačů , včetně IBM PC , protože jeho popularita začala výrazně zvyšovat.

V roce 1983, American National Standards Institute (ANSI) vytvořený výbor, X3J11, stanovit standardní specifikaci C. X3J11 bázi standardní C o provádění Unix; Nicméně, non-přenosné část knihovny Unix C byl předán do IEEE pracovní skupiny 1003, aby se stal základem pro 1988 POSIX standardu. V roce 1989, standardní C bylo potvrzeno jako ANSI X3.159-1989 „Programovací jazyk C“. Tato verze jazyka je často označován jako ANSI C , Standard C, nebo někdy C89.

V roce 1990, standardní ANSI C (změny formátování) byl přijat Mezinárodní organizace pro standardizaci (ISO), jako je ISO / IEC 9899: 1990, která se někdy nazývá C90. Z tohoto důvodu výrazy „C89“ a „C90“ odkazují na stejný programovací jazyk.

ANSI, stejně jako ostatní národních normalizačních orgánů, již vyvíjí standard C samostatně, ale odkládá na mezinárodní C standardu, vedeném pracovní skupina ISO / IEC JTC1 / SC22 / WG14. Národní přijetí aktualizace na mezinárodní normy obvykle nastane do jednoho roku od zveřejnění ISO.

Jedním z cílů postupu normalizace C měl produkovat nadmnožinu K & R C, zahrnující mnoho z dodatečně zavedených neoficiální funkcí. Výbor standardů také několik dalších funkcí, jako je funkční prototypy (převzatých z C ++), voidukazatele, podpora mezinárodních znakových sad a lokalitách a vylepšení preprocesoru. Ačkoli syntaxe pro prohlášení parametrů byl rozšířen, aby zahrnoval styl použitý v jazyce C ++, K & R rozhraní nadále povoleny pro kompatibilitu se stávajícími zdrojového kódu.

C89 je podporováno současnými C kompilátory, a většina C kód je napsán dnes je založen na tom. Jakýkoliv program napsaný pouze ve standardním C a bez hardwaru závislé na předpokladech budou pracovat správně na libovolné platformě s vyhovující implementace C, jeho mezích zdrojů. Bez těchto opatření, programy mohou sestavit pouze na určité platformě nebo s konkrétní překladač, v důsledku, například, k použití nestandardních knihoven, jako je GUI knihovny, nebo spoléhání se na compiler- nebo platformě specifickými atributy takových jako přesné velikosti datových typů a bytového endianness .

V případech, kdy kód musí být kompilovatelný buď odpovídající standardu nebo K R C bázi překladačů je __STDC__makro lze použít k rozdělení kódu do standardních a K a R sekcí, aby se zabránilo použití na K a R C-založený kompilátor funkcí, k dispozici pouze v normě a C.

Po procesu standardizace ANSI / ISO, specifikace jazyk C zůstala relativně statický na několik let. V roce 1995 Normativní Změna 1 normy 1990 C (ISO / IEC 9899 / AMD1: 1995, známá neformálně jako C95) byla zveřejněna, opravit některé detaily a přidat další rozsáhlou podporu pro mezinárodní znakové sady.

C99

Standardní C byl dále revidován v pozdní 1990, což vede k vydání normy ISO / IEC 9899: 1999 v roce 1999, který se běžně označuje jako „ C99 “. Od té doby bylo změněno třikrát Technické opravy.

C99 představil několik nových funkcí, včetně vložené funkce , několik nových datových typů (včetně long long inta complextypu, představují komplexní čísla ), proměnné délky pole a pružné členy pole , vylepšenou podporu pro IEEE 754 plovoucí desetinnou čárkou, podpora variadic makra (makra proměnné arity ), a podporu pro jeden řádek poznámky počínaje //, jako v BCPL nebo C ++. Mnohé z nich již byla provedena jako rozšíření v několika kompilátorů C.

C99 je z větší části zpětně kompatibilní s C90, ale je přísnější v některých ohledech; zejména prohlášení, že postrádá specifikátor typu již byla intimplicitně předpokládá. Standardní makro __STDC_VERSION__je definována s hodnotou 199901Lcož znamená, že podpora C99 je k dispozici. GCC , Solaris Studio a další kompilátory C nyní podporuje mnoho nebo všechny nové funkce C99. C kompilátor v Microsoft Visual C ++ , ale implementuje standard C89 a C99 ty části, které jsou nezbytné pro kompatibilitu s C ++ 11 .

C11

V roce 2007 byly zahájeny práce na další revizi normy typu C, neformálně zvané „C1x“ až do jeho oficiálního zveřejnění na 2011-12-08. Tyto standardy výbor C přijala směrnice k omezení přijímání nových funkcí, které nebyly testovány existující implementace.

Standardní C11 přidává řadu nových funkcí a C a knihovny, včetně typu generických maker, anonymních struktur, vylepšenou podporu Unicode, atomické operace, multi-threading a mezích zkontrolovala funkce. To také činí některé části stávajícího C99 knihovny volitelné, a zlepšuje kompatibilitu s C ++. Standardní makro __STDC_VERSION__je definována jako 201112Lukázat, že podpora C11 je k dispozici.

C18

Zveřejněna v červnu 2018, C18 je současný standard pro programovací jazyk C. Zavádí žádné nové funkce jazyka, pouze technické korekce a vysvětlení vady C11. Standardní makro __STDC_VERSION__je definován jako 201710L.

Embedded C

Historicky, vložené programování C vyžaduje nestandardní rozšíření k jazyku C s cílem podpořit exotické vlastnosti, jako jsou pevné řádové čárce, několik odlišných paměťové banky a základní I / O operací.

V roce 2008 Výbor pro C Standards zveřejnil technickou zprávu , probíhající jazyk C řešit tyto problémy tím, že poskytuje společnou normu pro všechny implementace dodržovat. To zahrnuje celou řadu funkcí, které nejsou dostupné v běžné C, například na pevné řádové čárce , pojmenované adresových prostorů a základní I / O hardware adresování.

Syntax

C má formální gramatiku specifikované v normě C. Řádkové konce jsou obecně významné C; Nicméně, vedení hranice to mít význam v průběhu fáze předběžného zpracování. Se může objevit Komentář buď mezi oddělovače /*a */, nebo (od C99) po //až do konce řádku. Komentáře ohraničena /*a */ne hnízdo, a tyto sekvence znaků nejsou interpretovány jako oddělovače komentáře v případě, že se objeví v řetězcových nebo znakové literály.

C zdrojové soubory obsahují deklarace a definice funkcí. Definice funkce, na oplátku obsahovat prohlášení a prohlášení . Prohlášení buď definovat nové typy pomocí klíčových slov, jako je struct, uniona enumnebo přiřadit typy se a snad i skladování rezerv pro nové proměnné, obvykle tím, že píše typ následovaný názvem proměnné. Klíčová slova, jako je chara inturčují vestavěné typy. Části kódu jsou uzavřeny v závorkách ( {a }, někdy nazývané „složené závorky“) omezit rozsah prohlášení a působit jako jeden příkaz řídicích struktur.

Jako imperativním jazyku C používá příkazy lze specifikovat akce. Nejběžnější tvrzení je výrazem prohlášení , skládající se z výrazu je třeba vyhodnotit, následuje středník; jako vedlejší účinek zhodnocení může být jejich funkce jmenuje a proměnné mohou být přiřazeny nové hodnoty. Pro modifikuje normální postupný provádění příkazů, C poskytuje několik příkazy řízení toku označené vyhrazených klíčových slov. Strukturované programování je podporováno if(- else) podmíněného plnění a do- while, whilea foropakující se plnění (smyčkování). forVýrok má vlastní inicializaci, testování a reinitialization výrazy, z nichž některé nebo všechny mohou být vynechána. breaka continuemohou být použity k opuštění nejvnitřnější prohlášení obklopující smyčky nebo přeskočit na její reinitialization. K dispozici je také non-strukturované gotoprohlášení, které větve přímo na určené štítku v rámci funkce. switchvybere casemají být provedeny na základě hodnoty výrazu celé číslo.

Výrazy mohou využít celou řadu vestavěných operátorů a mohou obsahovat volání funkce. Pořadí, ve kterém jsou vyhodnocovány argumenty funkcí a operandů do většiny operátorů není specifikován. Tato hodnocení mohou být dokonce prokládány. Však může mít všechny vedlejší účinky (včetně ukládání do proměnných), před dalším „ sekvence bodu “; sekvenční body patří konec každého expresního příkazu, a vstup do a návratu z každé volání funkce. Sekvenční body dojít také při vyhodnocování výrazů obsahujících některé operátory ( &&, ||, ?:a operátor čárka ). To umožňuje vysokou míru optimalizace objektového kódu kompilátor, ale vyžaduje C programátory, aby se více péče pro získání spolehlivých výsledků, než je potřeba pro další programovací jazyky.

Kernighan a Ritchie řekl v úvodu o programovacím jazyku C : „C, stejně jako jakýkoli jiný jazyk, má své vady Některé z těchto subjektů mají špatnou přednost; některé části syntaxe by mohlo být lepší.“. Standardní C nepokusil opravit mnohé z těchto kazů, protože dopad těchto změn na již existující software.

Znaková sada

Základním zdrojem C znaková sada obsahuje následující znaky:

Nový řádek označuje konec textového řádku; nemusí odpovídat skutečné jeden znak, i když pro pohodlí C považuje ji za jeden.

Dodatečné multi-byte zakódované znaky mohou být použity v řetězcové konstantě, ale nejsou úplně přenosné . Nejnovější C standard ( C11 ) umožňuje multi-národní Unicode znaky, které mají být vloženy do portably C zdrojového textu pomocí \uXXXXnebo \UXXXXXXXXkódování (kde Xznačí hexadecimální znak), i když tato funkce dosud není široce provedena.

Základní provedení C znaková sada obsahuje stejné znaky, spolu s reprezentací na pohotovosti , backspace a návrat vozíku . Run-time podpora rozšířených znakových sad se zvýšil s každou revizí standardu C.

vyhrazená slova

C89 má 32 vyhrazená slova, známé také jako klíčová slova, což jsou slova, která nemohou být použity k jinému účelu, než pro které jsou předdefinované účelům:

C99 vyhrazeno pět dalších slov:

C11 vyhrazeno sedm dalších slov:

Většina nedávno vyhrazených slov začínat podtržítkem následované velkým písmenem, protože identifikátory této formě byly dříve vyhrazeny v normě C pro použití pouze implementací. Vzhledem k tomu, existující zdrojový kód programu by neměly být pomocí těchto identifikátorů, že by neměl být ovlivněn, pokud implementace C začal podporovat tyto rozšíření programovacího jazyka. Některé standardní hlavičky udělat definovat vhodnější synonyma pro podtrženého identifikátory. Jazyk dříve součástí vyhrazené slovo s názvem entry, ale toto bylo zřídka implementován, a byla nyní odstraněna jako vyhrazené slovo.

operátoři

C podporuje bohatou škálu subjektů , které jsou symboly použité v rámci výrazu k určení manipulace, které mají být provedeny při hodnocení, že exprese. C má operátory pro:

C používá operátor =(použitý v matematiky vyjádřit rovnosti) k určení přiřazení, v návaznosti na precedens Fortran a PL / I , ale na rozdíl od ALGOLu a jeho derivátů. C používá operátor ==pro testování rovnosti. Podobnost mezi těmito dvěma operátory (přiřazení a rovnost) může vést k náhodnému použití jednoho namísto druhého, a v mnoha případech je chyba nevytvářejí chybová zpráva (ačkoli některé kompilátory produkují varování). Například, podmíněný výraz if(a==b+1)může chybně zapsat jako if(a=b+1), který bude vyhodnocen jako pravdivý, pokud anení nula po zadání.

C přednost operátor není vždy intuitivní. Například operátor ==váže pevněji než (je vykonán před) Provozovatelé &(bitové A) a |(bitové OR) ve výrazech, například x & 1 == 0, které je třeba zapsat jako (x & 1) == 0v případě, že je kodéru záměr.

"Hello, world" Příkladem

Dále jen „ ahoj, svět “ příklad, který se objevil v prvním vydání K & R , se stala modelem pro úvodní programu ve většině programovacích učebnic, bez ohledu na programovací jazyk. Program vytiskne „Hello, world“ na standardní výstup , který je obvykle koncový nebo displej.

Původní verze byla:

main()
{
    printf("hello, world\n");
}

Standardní konformní „ahoj, svět“ program:

#include <stdio.h>

int main(void)
{
    printf("hello, world\n");
}

První řádek programu obsahuje směrnici předběžného zpracování , který je označen #include. To způsobí, že kompilátor nahradí tento řádek s celým textem stdio.hstandardní záhlaví, které obsahuje prohlášení pro standardní vstupní a výstupní funkce, jako je printf. Lomené závorky obklopující stdio.hnaznačují, že stdio.hleží s použitím vyhledávací strategie, která preferuje záhlaví dodávané s kompilátorem na jiné záhlaví, které mají stejný název, protože na rozdíl od uvozovek, které obvykle zahrnují místní nebo projektu specifického hlavičkové soubory.

Následující řádek ukazuje, že funkce s názvem mainje definován. mainFunkce slouží speciální účel v programech C; run-time prostředí volá mainfunkci k zahájení provádění programu. Typ specifikátor intznamená, že hodnota, která se vrací do volající (v tomto případě run-time) v důsledku vyhodnocení mainfunkce, je celé číslo. Klíčové slovo voidjako seznam parametrů znamená, že tato funkce trvá žádné argumenty.

Úvodní složená závorka označuje začátek definice mainfunkce.

Příští linka volá (přesměruje vykonávání na) funkce s názvem printf, který v tomto případě je dodávána ze systémové knihovny . V této výzvy je printffunkce je předán (opatřena) jediný argument, na adresu prvního znaku v řetězci doslovný "hello, world\n" . Řetězec doslovný je nejmenovaný pole s prvky typu char, která byla zřízena automaticky kompilátorem s konečnou 0-ceněný znak označit konec pole ( printfmusí vědět to). \nJe řídicí sekvence , které C se převádí na nový řádek znak, který na výstupu znamená konec aktuálního řádku. Návratová hodnota printffunkce je typu int, ale to je zahozen, protože se nepoužívá. (A opatrnější program mohl testovat návratovou hodnotu určit, zda je či není printffunkční uspěl.) Středník ;ukončí prohlášení.

Uzavírací složená závorka označuje konec kódu pro mainfunkci. Podle specifikace C99 a novější je mainfunkce, na rozdíl od jiných funkcí, bude implicitně vrátit hodnotu 0po dosažení }který ukončí funkci. (Dříve explicitní return 0;bylo požadováno sdělení.) To je interpretován run-time systém jako kód ukončení označující úspěšné provedení.

Typy dat

Typ systému v C je statická a slabě napsaný , což je podobná typu systému algol potomků, jako je Pascal . K dispozici jsou vestavěné typy na celá čísla v různých velikostech, a to jak podepsané a nepodepsané, čísel s plovoucí desetinnou čárkou , a vyjmenované druhy ( enum). Integer typ charse často používá pro jednobajtové znaky. C99 přidal boolean datový typ . K dispozici jsou také odvozené typy včetně polí , ukazatelů , záznamů ( struct) a svazy ( union).

C je často používán v systémové programování na nízké úrovni, kde unikají z typu systému může být nezbytné. Překladač se snaží zajistit typu správnosti většiny projevů, ale programátor může přepsat kontroly různými způsoby, a to buď pomocí typu obsazení explicitně převést hodnotu z jednoho typu do druhého, nebo pomocí ukazatele nebo odbory k reinterpretaci základních bitů z datového objektu nějakým jiným způsobem.

Někteří najdou syntax prohlášení C je unintuitive, zejména u ukazatelů funkcí . (Ritchie nápad měl deklarovat identifikátory v kontextech připomínajících jejich využití: „ deklarace odráží použití “.)

C je obvyklé aritmetické konverze umožňují efektivní být generován kód, ale někdy může vést k neočekávaným výsledkům. Například srovnání podepsaných a celých čísel bez znaménka stejné šířky vyžaduje konverzi podepsaného hodnoty do bez znaménka. To může vytvářet neočekávané výsledky, pokud je podepsán hodnota záporná.

ukazovátka

C podporuje použití ukazatelů , což je druh vztahu , který zaznamenává adresy nebo umístění objektu nebo funkce v paměti. Ukazatele mohou být dereferencovat přístup k datům uloženým na adrese ukázal, nebo vyvolat špičatého-fungovat. Ukazatele lze manipulovat pomocí zadání nebo ukazatel aritmetiku . Run-time reprezentace hodnoty ukazatele je obvykle raw adresa paměti (snad rozšířena pomocí ofsetového-v-slovo pole), ale vzhledem k tomu typu ukazatel zahrnuje typ věci poukázal na výrazy včetně ukazatele mohou být typu zkontrolovat při kompilaci. Ukazatel aritmetika je automaticky zmenšen podle velikosti špičaté, do datového typu. Ukazatele jsou používány k mnoha účelům v C. Textové řetězce se běžně manipulovat pomocí ukazatele na pole znaků. Dynamické přidělování paměti se provádí pomocí ukazatelů. Mnoho datových typů, jako jsou stromy , jsou obvykle implementovány jako dynamicky alokovaných structobjektů, které dohromady pomocí ukazatelů. Ukazatele na funkce jsou užitečné pro předávání funkcí jako argumenty vyššího řádu funkcí (jako je qsort nebo bsearch ) nebo jako zpětná volání být volány obslužné rutiny.

Null Ukazatel Hodnota výslovně odkazuje na žádném platné umístění. Získávání nulovou hodnotu ukazatele je definován, což často vede k poruše segmentace . Nulové hodnoty ukazatel jsou užitečné pro označení zvláštních případů, jako je ne „další“ ukazatel v posledním uzlu propojeného seznamu , nebo jako indikace chyby z funkce vrací ukazatele. Ve vhodných podmínkách in zdrojového kódu, jako je přiřazení na ukazatel proměnné, je ukazatel NULL konstanta může být psáno jako 0, s nebo bez explicitní lití na ukazatel typu, nebo jako NULLmakro definované několika standardních záhlaví. V podmíněných kontextech, nulové hodnoty ukazatel vyhodnotit na hodnotu false, zatímco všechny ostatní hodnoty ukazatel vyhodnotit na hodnotu true.

Void ukazatele ( void *) ukazují na objekty neurčeného typu, a proto může být použit jako „obecné“ datových ukazatelů. Vzhledem k velikosti a typu poukázal k objektu není známa, void ukazatele nelze dereferencovat, ani je ukazatel aritmetiku na nich povolen, ačkoli oni mohou být snadno (a v mnoha kontextech implicitně se) převedeny do az jakéhokoli jiného ukazatele objektu typ.

Neopatrné používání ukazatelů je potenciálně nebezpečný. Vzhledem k tomu, že jsou obvykle pod kontrolou, ukazatel proměnné mohou být provedeny, aby odkazoval na každém libovolném místě, což může způsobit nežádoucí účinky. Přestože řádně používané ukazatele poukazují na bezpečných místech, které mohou být provedeny, aby odkazovaly na nebezpečných místech pomocí neplatný ukazatel aritmetiku ; objekty, které odkazují na smějí být nadále používány po deallocation ( visících ukazatelů ); mohou být použity, aniž by byl inicializován ( wild ukazatele ); nebo mohou být přímo přiřazeny nebezpečné hodnotu pomocí odlitku, unie, nebo prostřednictvím jiné zkorumpovaným ukazatel. Obecně platí, že C je permisivní v umožňuje manipulaci a konverzi mezi typy ukazatel, i když překladače obvykle poskytují možnosti pro různé úrovně kontroly. Některé jiné programovací jazyky řešit tyto problémy pomocí přísnější referenční typy.

pole

Array typy v jazyce C jsou tradičně z pevné, statické formátu zadaného v době kompilace. (Novější standardní C99 také umožňuje formu proměnné délky pole). Nicméně, je také možné přidělit blok paměti (z libovolné velikosti) při spuštění, pomocí standardní knihovny mallocfunkci, a zacházet s ní jako array. Sjednocení C je z Pole a ukazatele znamená, že prohlásil, polí a tyto dynamicky přidělené simulované pole jsou v podstatě zaměnitelné.

Vzhledem k tomu, pole jsou vždy přístupné (ve skutečnosti) prostřednictvím ukazatelů, pole přístupy jsou obvykle nejsou kontrolovány proti podkladové velikost pole, i když některé kompilátory mohou stanovit hranice kontrolní jako jedna z možností. Array ohraničuje porušení je tedy možné a poměrně běžné v nedbale literou zákona a může vést k různým důsledkům, včetně ilegální paměť zpřístupňuje, poškození dat, přetečení vyrovnávací paměti , a run-time výjimky. Požaduje-li se kontrola hranice, je nutné provést ručně.

C nemá zvláštní ustanovení pro prohlašující multi-dimenzionální pole , ale spíše se spoléhá na rekurze v systému typu deklarovat matice polí, která účinně dosáhne totéž. Index hodnoty výsledné „multi-dimenzionální pole“ může být myšlenka je zvýšení v řadě dur pořadí .

Vícerozměrná pole jsou běžně používány v numerických algoritmů (především z aplikované lineární algebry ) pro uložení matice. Struktura matice C, se dobře hodí pro tento konkrétní úkol. Nicméně, protože pole jsou předány pouze jako ukazatele jsou hranice pole musí být známy fixní hodnoty jinak výslovně předány jakékoliv podprogramu, který jim ukládá, a dynamicky velké pole na pole nelze přistupovat pomocí dvojité indexování. (A řešení je to, přidělit pole s další „řádkového vektoru“ ukazatelů na sloupcích.)

C99 představil „proměnné délky pole“, které se zaměřují na některé, ale ne všechny, problémů s obyčejnými C polí.

Array-pointer zaměnitelnost

Index notace x[i](kde xoznačuje ukazatel) je syntaktický cukr pro *(x+i). Využívat znalostí kompilátoru typu ukazatele, adresu, která x + iodkazuje na není základní adresa (na kterou ukazuje x) zvýší o ibytech, nýbrž je definován jako základní adresa zvýší o ivynásobí velikostí prvek, který xbodů na. Tak x[i]označuje i+1tého prvku matice.

Dále ve většině expresních kontextech (výrazná výjimka je operand sizeof), název pole je automaticky převedeny na ukazatel na první prvek paprsku pole. To znamená, že pole se nikdy kopírovány jako celek, když jmenoval jako argument funkce, ale pouze adresy jejího prvního prvku je předán. Z tohoto důvodu, i když volání funkce v provozu C projíždějících-hodnota sémantiky, sady jsou v podstatě prochází od reference .

Velikost prvku může být stanovena na základě daného operátora sizeofkteréhokoliv dereferenced prvek x, jako v n = sizeof *x, nebo n = sizeof x[0], a počet prvků v deklarovaném pole Amůže být určena sizeof A / sizeof A[0]. Ta se vztahuje pouze na názvy polí: proměnné deklarované s indexy ( int A[20]). Vzhledem k sémantiky C, není možné určit celé velikosti polí pomocí ukazatelů na pole nebo ti vytvořený dynamickou alokaci ( malloc); kód, jako je sizeof arr / sizeof arr[0](kde arroznačuje ukazatel) nebude fungovat, protože kompilátor předpokládá velikost ukazatele sám je žádán. Vzhledem k tomu, název pole argumenty sizeofnejsou převedeny na ukazatele, které nevykazují takové nejasnosti. Nicméně, pole vytvořené dynamickou alokací jsou přístupné pomocí ukazatelů namísto skutečných proměnné pole, takže trpí stejnými sizeofotázkami jako ukazatelů pole.

Tak, i přes tuto zjevnou ekvivalence mezi pole a indikační proměnné, je stále rozlišovat mezi nimi. I přesto, že název pole je, že ve většině expresních kontextech, převede na ukazatel (jeho první prvek), tento ukazatel není sama o sobě na jakýchkoliv skladování; název pole není l-hodnota , a jeho adresa je konstantní, na rozdíl od ukazatel proměnné. V důsledku toho, co je pole „body“ nelze změnit, a to je možné přiřadit nové adresy na jméno pole. Obsah pole může být kopírován, avšak s použitím memcpyfunkce nebo použitím jednotlivých prvků.

správa paměti

Jedním z nejdůležitějších funkcí programovacího jazyka je poskytnout zázemí pro správu paměti a objekty, které jsou uloženy v paměti. C poskytuje tři různé způsoby, jak přidělit paměť pro objekty:

  • Statická alokace paměti : prostor pro objekt je k dispozici v binární při kompilaci; tyto objekty mají rozsah (nebo život) tak dlouho, jak binární, která obsahuje jim je načten do paměti.
  • Automatická alokace paměti : dočasné objekty mohou být uloženy na zásobníku , a tento prostor je automaticky uvolněno a opakovaně po bloku, v němž jsou deklarovány ukončen.
  • Dynamické přidělování paměti : bloků paměti libovolné velikosti může být požadováno při spuštění pomocí knihovny funkce, jako je mallocz oblasti paměti, nazývá haldy ; Tyto bloky přetrvávají dokud následně uvolněna pro opětovné použití voláním funkce knihovny reallocnebofree

Tyto tři přístupy jsou vhodné v různých situacích a mají různé kompromisy. Například statické přidělování paměti má malou přidělení režii, automatické přidělování může zahrnovat něco více režii a dynamické přidělování paměti může mít potenciálně velkou režii jak pro přidělování a deallocation. Přetrvávající povaha statických objektů je užitečné pro udržování informací o stavu přes volání funkce, automatické přidělování je snadno ovladatelný, ale stack prostor je obvykle mnohem omezenější a přechodné než jeden statické paměti nebo haldy prostoru a dynamického přidělování paměti umožňuje pohodlné rozdělení objektů, jejichž velikost je znám pouze při spuštění. Většina programů C ve velké míře využívají všech tří.

Tam, kde je to možné, automatická nebo statická alokace je obvykle nejjednodušší, protože úložiště spravuje kompilátor, uvolnění programátora potenciálně náchylné k chybám fuška ručně přidělování a uvolnění úložiště. Nicméně, mnoho datových struktur může měnit co do velikosti za běhu, a protože statické přidělení (a automatické přidělení před C99), musí mít pevnou velikost při kompilaci čase, existuje mnoho situací, ve kterých je nutná dynamická alokace. Před standardu C99, s proměnlivou velikostí pole byly obyčejný příkladem. (Viz článek o mallocpro příklad dynamicky alokovaných polí.) Na rozdíl od automatického přidělení, které mohou selhat při běhu s nekontrolovanými následky, dynamické funkce přidělování vrátí údaj (ve formě nulové hodnoty ukazatele), když je vyžadováno úložiště nemůže mají být přiděleny. (Statický alokace, že je příliš velká je obvykle detekována linkerem nebo nakladač , předtím, než program může dokonce začít provádění.)

Není-li uvedeno jinak, statické objekty obsahují nula nebo null hodnoty ukazatele při startu programu. Automaticky a dynamicky přidělené objekty jsou inicializovány pouze tehdy, pokud je výslovně uvedeno počáteční hodnota; jinak je zpočátku neurčité hodnoty (typicky, bez ohledu na vzorek bitů se stane, že je přítomen v paměti , který ani nemusí představovat platnou hodnotu tohoto typu). Pokud se program pokusí o přístup k neinicializované hodnoty, výsledky jsou nedefinované. Mnoho moderních překladače pokusí rozpoznat a upozornit na tento problém, ale obě falešných pozitiv a negativ může dojít.

Dalším problémem je to, že přidělení haldy paměti musí být synchronizovány s jeho skutečného využití v jakémkoli programu, aby pro to, aby znovu použít co nejvíce. Například, v případě, že pouze ukazatel na přidělení haldy paměti dostane mimo rozsah nebo je jeho hodnota přepsána dříve free(), se nazývá, pak tato paměť nemůže být získán pro pozdější použití a je v podstatě ztratil do programu, což je jev známý jako únik paměti . Naopak, je možné, že paměť bude uvolněna, ale i nadále se bude odkazovat, což vede k nepředvídatelným výsledkům. Obvykle se tyto příznaky objeví v části programu daleko od skutečné chyby, takže je obtížné vystopovat problém. (Tyto problémy jsou zlepšeny v jazycích s automatickou garbage collector ).

knihovny

Programovací jazyk C používá knihovny jako primární způsob prodloužení. V jazyce C, knihovna je sada funkcí, obsažených v rámci jednoho souboru „archivní“. Každá knihovna má obvykle soubor záhlaví , který obsahuje prototypy funkce obsažené v knihovně, které mohou být použity programem, a prohlášení speciálních datových typů a maker použitých symbolů s těmito funkcemi. K tomu, aby program používat knihovnu, musí zahrnout hlavičkový soubor knihovny a knihovny musí být spojena s programem, který v mnoha případech vyžaduje kompilátor příznaky (např -lm, zkratka pro „odkaz matematický knihovna“).

Nejběžnější C knihovna je C standardní knihovna , který je stanoven v ISO a ANSI C standardy a přichází s každé provedení C (implementace, které se zaměřují na omezené prostředí, jako vestavěných systémů může poskytnout pouze podmnožinu standardní knihovny). Tato knihovna podporuje vstupního proudu a výstup, přidělování paměti, matematiku, řetězce znaků a časové hodnoty. Několik samostatných standardní hlavičky (například stdio.h) specifikovat rozhraní pro tyto a ostatní standardní knihovny zařízení.

Dalším společným sada funkcí knihovny C, jsou ty, které používají aplikace specificky cílených pro Unix a unixových systémů, zejména funkce, které poskytují rozhraní do jádra . Tyto funkce jsou podrobně popsány v různých standardů, jako je POSIX a UNIX Specification jednotné .

Vzhledem k tomu, mnoho programů, které byly napsány v jazyce C, existuje celá řada dalších knihoven k dispozici. Knihovny jsou často napsaný v C, protože C kompilátory generovat efektivní objektový kód ; programátoři vytvořit rozhraní pro knihovnu tak, že rutiny mohou být použity z jazyků na vyšší úrovni, jako je Java , Perl a Python .

manipulace souborů a potoky

Soubor vstupu a výstupu (I / O) není součástí jazyka C sám, ale místo toho je řešen v knihovnách (například C standardní knihovna) a jejich přidružené hlavičkové soubory (např stdio.h). Manipulace s soubor je obvykle realizován prostřednictvím vysoké úrovni I / O, která pracuje přes potoky . Proud je z tohoto hlediska datového toku, který je nezávislý na zařízení, zatímco soubor je konkrétní zařízení. Vysoká úroveň I / O se provádí prostřednictvím sdružení proudu do souboru. Ve standardní knihovny C, je vyrovnávací paměť (paměťovou oblast nebo fronta) je dočasně používá k ukládání dat před tím, než je odeslán do cílového místa určení. To snižuje čas strávený čekání na pomalejších zařízení, například pevný disk nebo SSD . Nízkoúrovňové I / O funkce nejsou součástí standardní knihovny jazyka C, ale jsou obvykle součástí „bare metal“ programování (programování, které je nezávislé na jakémkoli operačním systému, jako je většina, ale ne všem vloženým programování ). Až na několik výjimek, implementace jsou nízkoúrovňové I / O.

Jazykové nástroje

Řada nástrojů, které byly vyvinuty na pomoc C programátoři najít a opravit prohlášení s nedefinovanou chování nebo případně chybné výrazy, s větší přísností než poskytované kompilátorem. Nástroj lint byl prvním svého druhu, což vede k mnoha dalších.

Automatizovaná kontrola zdrojový kód a audity jsou přínosné v jakémkoli jazyce, a C, existuje mnoho takových nástrojů, jako je Lint . Běžnou praxí je použít Lint na detekci sporný kód, když je program První písemná. Jakmile program odesílá cupanina, se sestavují pomocí kompilátor C. Také, mnohé kompilátory mohou případně varovat syntakticky platných konstrukty, které by mohly být ve skutečnosti chyby. MISRA C je proprietární soubor pokynů, aby se zabránilo takové pochybné kódu, vyvinutý pro vestavěné systémy.

K dispozici jsou také překladače, knihovny, a mechanismy úrovni operačního systému pro provádění akcí, které nejsou standardní součástí C, jako je například kontrolou hranic pro pole, detekci přetečení vyrovnávací paměti , serializace , dynamické paměti sledování a automatický sběr odpadků .

Nástroje jako Purify nebo Valgrind a propojení s knihovnami, které obsahují speciální verze funkcí přidělení paměti může pomoci odhalit chyby při běhu v využití paměti.

použití

Index TIOBE graf, který ukazuje srovnání popularity různých programovacích jazyků

C je široce používán pro programování systému při zavádění operačních systémů a vestavěný systém aplikací, protože kód v C, když psaný pro přenositelnost, může být použit pro většinu účelů, ale v případě potřeby kód specifické pro daný systém může být použit pro přístup k určitým hardwarové adresy a provádět typ pěchování tak, aby odpovídala externě uložené požadavky na rozhraní s nízkou run-time nároky na systémové prostředky.

C lze použít také pro programování webových stránek pomocí CGI jako „brána“ pro informaci mezi webovou aplikací, serverem a prohlížečem. C je často dána přednost před interpretovaný jazyk , protože jeho rychlost, stabilitu a téměř univerzální dostupnosti.

Jedním z důsledků široké dostupnosti a výkonnosti c je, že kompilátory , knihovny a tlumočníci z jiných programovacích jazyků jsou často prováděny v C. referenční implementace s Python , Perl a PHP , například, jsou napsané v C.

Vzhledem k tomu, že vrstva abstrakce je tenká a režie je nízká, C umožňuje programátorům vytvářet efektivní implementace algoritmů a datových struktur, vhodné pro výpočetně intenzivní programy. Například GNU Multiple Precision Arithmetic Knihovna je GNU vědecká knihovna , Mathematica a MATLAB jsou zcela nebo částečně napsaný v jazyce C.

C je někdy používán jako meziprodukt jazyk implementacemi jiných jazyků. Tento přístup může být použit pro přenášení nebo pohodlí; pomocí C jako přechodném jazyku, další stroj specifické pro generátory kódu nejsou nutné. C má některé funkce, jako je například směrnice řádek číslo předprocesoru a volitelných nadbytečné čárky na konci seznamů Inicializátor, že podpora sestavování generovaného kódu. Nicméně, některé z nedostatků, C je vedly vývoj jiných jazyků C založené na specificky určených pro použití jako meziprodukty jazyků, jako je C- .

C byl také široce používán k implementaci pro koncové uživatele aplikace. Avšak takové aplikace mohou být psány v novějších, nadřazených jazyků.

příbuzné jazyky

C má přímo i nepřímo ovlivnila mnoho vyšší jazyky, jako je C # , D , Go , Javy , JavaScriptu , Limbo , LPC , Perl , PHP , Python a UNIX C shell . Nejvíce všudypřítomný vliv byl syntaktická, všechny z jazyků uvedených kombinovat prohlášení a (více či méně zřetelně) výraz syntax C s typovými systémů, datových modelů a / nebo rozsáhlých programových struktur, které se liší od těch, C, někdy radikálně ,

Několik C nebo blízko-C tlumočníci existují, včetně Ch a CINT , který může být také použit pro skriptování.

Když objektově orientované jazyky se staly populární, C ++ a Objective-C byly dva různé rozšíření jazyka C, který poskytl objektově orientované možnosti. Oba jazyky byly původně zaveden jako zdroj-k-zdroje překladačů ; zdrojový kód byl přeložen do C, a pak se sestavují s kompilátor C.

C ++ programovací jazyk byl navržený Bjarne Stroustrup jako přístup k poskytování objektově orientované funkčnost s syntaxe C-podobně. C ++ dodává větší pevnost, psaní působnosti, a další nástroje užitečné v objektově orientovaného programování, a umožňuje generické programování pomocí šablon. Téměř nadstavbou C, C ++ nyní podporuje většinu C, s několika výjimkami .

Objective-C byl původně velmi „tenký“ vrstva v horní části C, a zůstává přísné nadmnožinu C, který umožňuje objektově orientovaného programování pomocí hybridní dynamického / statického psaní paradigma. Objective-C odvodí jeho syntaxe z obou C a Smalltalk : syntaxi, která zahrnuje předzpracování, výrazy, deklarace funkce a funkce volání se dědí z C, zatímco syntaxe pro objektově orientované rysy byla původně převzata z Smalltalk.

Kromě C ++ a Objective-C , Ch , Cilk a Unified Parallel C jsou téměř nadmnožiny C.

viz též

Poznámky

Reference

Prameny

Další čtení

externí odkazy