Movatterモバイル変換


[0]ホーム

URL:


Pojdi na vsebino
Wikipedijaprosta enciklopedija
Iskanje

Programski jezik C

Iz Wikipedije, proste enciklopedije
Splošni programski jezik.Predloga:SHORTDESC:Splošni programski jezik.
C
Text in light blue serif capital letters on white background and very large light blue sans-serif letter C.
Paradigmamultiparadigmatična:imperativna (proceduralna),strukturalna
Začetna izdaja1972 (1972)[a]
OblikovalDennis Ritchie
RazvijalecBellovi laboratoriji[d],Dennis Ritchie[1],Ameriški nacionalni inštitut za standardizacijo,Mednarodna organizacija za standardizacijo inKenneth Thompso
Stabilna izdajaC23 (31. oktober 2024 (2024-10-31)[2])
Pregledna izdajaC2Y (N3096]) (21. februar 2024 (2024-02-21)[3])
Tipizacijastatična,šibka,manifestna,imenska
Večje implementacijeC++Builder,Clang,GCC,Intel C,K&R,LCC,MSVC,pcc,Watcom C/C++
DialektiCyclone,Unified Parallel C,Split-C,Cilk,C*
VpliviALGOL 68[d][4],B,zbirni jezik,Fortran,PL/I[d],CPL[d],BCPL[d],ALGOL 60[d] inALGOL
Vplival namnoge:AMPL,AWK,csh,C++,C--,C#,Objective-C,BitC,D,Go,java,JavaScript,JS++,Julia,Limbo,LPC,nim,Perl,PHP,Pike,Processing,Python,Rust,Seed7,Swift,V (Vlang),Vala,Verilog (HDL),[5]zig
OSMicrosoft Windows,podoben Unixu[d] invečplatformsko[d]
Običajnakončnica datoteke.c, .h
Spletna stran
Wikibooks logoC Programming naWikibooks
Koda zaprogramPozdravljen, svet vurejevalnikuGedit

Prográmski jêzik C ali karC (izgovorjava [cé] ali po izvirniku [sí]) jenizkonivojskiimperativnistandardiziraniračunalniškiprogramski jeziktretje generacije (3GL)za splošno rabo. Podpirastrukturalno programiranje,leksično območje spremenljivk inrekurzijo,statični sistem tipov pa preprečuje mnogo nenameravanih operacij. Zasnova jezika C omogoča konstrukte, ki se učinkovito preslikujejo v tipičnestrojne ukaze. Po zasnovi gradniki C jasno odražajo zmogljivosti ciljnihprocesorjev. Zaradi tega se je C začel rabiti v aplikacijah, ki so bile prej razvite vzbirnem jeziku, še posebej vsistemski programski opremi, kot je npr. računalniškioperacijski sistemUnix.[6] Našel je trajno uporabo v kodi operacijskih sistemov (zlasti vjedrih[7]),gonilnikih naprav inprotokolskih skladih, vendar se njegova uporaba vaplikacijski programski opremi zmanjšuje.[8] C se pogosto uporablja vračunalniških arhitekturah v različnihuporabniških programskih opremah od največjihsuperračunalnikov do najmanjšihmikrokrmilnikov invgradnih sistemov.

Programski jezik C je prvotno razvilDennis Ritchie med letoma 1969 in 1973 vAT&T Bellovih laboratorijih.[9][10][11] Ritchie inKen Thompson sta najprej razvilaprevajalnik za operacijski sistem Unix, ki je bil v osnovi napisan v zbirnem jeziku. Unixovo jedro je bilo tako prvo napisano v drugem jeziku in ne v zbirnem. Kasneje se je C hitro pojavil tudi na drugih operacijskih sistemih. V 1980-ih je C postopoma pridobival na priljubljenosti. Postal je eden najbolj razširjenih programskih jezikov[12][13] s prevajalniki C, ki so na voljo za praktično vse sodobne računalniške arhitekture in operacijske sisteme.

Pred uradnim standardom za C se je mnogo uporabnikov in izvršiteljev opiralo na neuradno specifikacijo, opisano v knjigiProgramski jezik CBriana Wilsona Kernighana in Ritchieja.[14][15] Ta različica je v splošnem znana kot »K&R« C. Leta 1989 jeAmeriški državni inštitut za standarde (ANSI) objavil standard za C (v splošnem imenovan »ANSI C« ali »C89«). Naslednje leto sta to specifikacijo potrdiliMednarodna organizacija za standardizacijo (ISO) inMednarodna komisija za elektrotehniko (IEC) kot mednarodni standard (v splošnem imenovan »C90«). ISO in IEC sta kasneje izdali razširitev standarda za podporointernacionalizacije leta 1995 in popravljeni standard (znan kot »C99«) leta 1999. Ta standard je do sedaj najbolj razširjen. Trenutna različica standarda (sedaj imenovana »C23«) je ISO kot ISO/IEC 9899:2014 potrdila 31. oktobra 2024.[16]

Zasnova

[uredi |uredi kodo]

C jeimperativniproceduralni jezik. Izdelan je bil za prevajanje na relativno preprostemprevajalniku in da bi zagotavljal nizkonivojski dostop dopomnilnika, jezikovne konstrukte, ki bi se učinkovito preslikali v tipične strojne ukaze in, da bi potreboval najmanjšopodporo izvajanja. Zaradi tega se je C začel rabiti v mnogih aplikacijah, ki so bile prej razvite z zbirnem jeziku, še posebej vsistemskem programiranju.

Navkljub svojim nizkonivojskim zmožnostim se je jezik C razvil v smislu boljšega programiranja namnogih platformah. Program zapisan v C, ki je v skladu s standardom in napisanprenosljivo, se lahko prevede za zelo širok nabor računalniških platform in operacijskih sistemov z zelo malo spremembami v izvorni kodi. Tako je C postal razpoložljiv na mnogih platformah od vgrajenihmikrokrmilnikov do superračunalnikov.

C velja za učinkovit jezik in je primeren za sistemska opravila, ni pa najprimernejši za učenjeprogramiranja, čeprav se pogosto pojavlja vizobraževanju. Je tudieden od najbolj razširjenih programskih jezikov, skupaj zjavo,C++ aliPHP, od leta 2008 pa mu priljubljenost celo rahlo narašča.[12][13] Od leta 2000 se C stalno uvršča med prve štiri jezike vindeksu TIOBE, ki meri priljubljenost programskih jezikov.[17] Obstaja zelo maloarhitektur in operacijskih sistemov za katere ni na voljo prevajalnika za C. C se veliko rabi tudi za razvoj prenosljive uporabniške programske opreme.[6]

Pregled in osnovne značilnosti jezika

[uredi |uredi kodo]

Kot večina imperativnih jezikov v tradicijiALGOLa je C zmoženstrukturalnega programiranja in omogočaleksično območje spremenljivk terrekurzijo,statični sistem tipov pa preprečuje mnogo nenameravanih operacij.

C je dokaj skop programski jezik, ki deluje blizustrojne opreme, in je za razliko od večine programskih jezikov bolj podobenzbirniku. Včasih ga imenujejo »prenosljivi zbirnik«, kar tudi označuje njegovo pomembno razliko od zbirniškega jezika.Izvorno kodo, napisano v C, se da prevesti in pognati na skoraj vsakemstroju. Tega ne zmore skoraj noben obstoječ programski jezik in tudi kodo, zapisano v zbirniku, se lahko požene le na določenih vrstah strojev. C po navadi imenujejonizkonivojski alisrednjenivojski jezik, kar označuje kako blizu strojne opreme lahko deluje.

V C-ju je vsaizvršna koda vsebovana znotrajpodprogramov, imenovanih »funkcije«, čeprav ne v strogem pomenufunkcionalnega programiranja.Parametri funkcij seprenašajo po vrednosti.Polja se prenašajo kotkazalci, to je kot naslov prvega elementa v polju.Prenos po sklicu se v C simulira z eksplicitnim prenašanjem vrednosti kazalcev na objekt, na katerega se sklicuje.

Izvorno besedilo programa v C je vprostem formatu in za končnikstavkov rabipodpičje (;), terzavita oklepaja ({ }) za združevanjeblokov stavkov.

C so naredili zaradi enega samega pomembnega namena, kar ni slučajnost, da bi bilo moč pisati velike programe z manj napakami v proceduralnem programiranju in, da pisec programov ne bi nosil bremena tvorjenja prevajalnika za C, ki ga otežujejo zapleteni gradniki jezika. V tem smislu ima C naslednje pomembne značilnosti:

  • majhno fiksno številorezerviranih besed, ki vključuje polno množico primitivovnadzornega pretoka:if/else,for,while,switch indo/while. Obstaja enimenski prostor, imena, ki jih opredeli uporabnik, se ne morejo razlikovati od rezerviranih besed z nobeno vrstosigle,
  • veliko število aritmetičnih,bitnih, logičnih (enočlenih,dvočlenih,tročlenih) in pozapisnih operatorjev, kot so npr.:+,-,!,*,&,~,+=,++,||,<<,? :,.,-> ipd.,
  • v enem stavku se lahko izvede več kot enaprireditev,
  • funkcije:
    • vrnjene vrednosti funkcij se lahko prezrejo, kadar se ne rabijo
    • funkcijski in podatkovni kazalci omogočajo osnovno oblikozaprtja (closure) inad hoc izvajalnegapolimorfizma,
    • funkcije se ne morejo opredeliti znotraj slovarskega področja drugih funkcij,
    • spremenljivke so lahko definirane znotraj funkcije zdosegom (scope),
    • funkcija lahko kliče samo sebe, zato jerekurzija podprta,
  • podatkovnatipizacija jestatična, vendar prisiljenošibka: vsi podatki imajo tip, lahko pa se izvedeimplicitno pretvorbo. Znaki se lahko na primer rabijo kot cela števila,
  • uporabniško definirani tipi (typedef) in sestavljeni tipi,
    • zapisi (records) ali skupki raznovrstnih podatkovnih tipov (struct), ki jih določi uporabnik, in omogočajo združevanje in upravljanje podobnihpodatkovnih elementov v celoti. Vsebine celih struktur ni mogoče primerjati z enim samim vgrajenim operatorjem (elemente je treba primerjati posamezno),
    • unija je struktura s prekrivajočimi se člani; omogoča, da več tipov podatkov deli isto pomnilniško lokacijo.
    • indeksiranjepolj je sekundarni zapis, opredeljen s pomočjo kazalčne aritmetike. Z razliko od unij polja niso prvorazredni objekti ni jih moč prirediti ali primerjati s pomočjo posameznih vgrajenih operatorjev. Pri rabi ali opredelitvi ne obstaja rezervirana beseda »array«. Namesto tegaoglata oklepaja ([ ]) nakazujeta polja skladenjsko, na primermesec[11],
    • naštevni tipi (enumerated types) z rezervirano besedoenum. Niso opremljeni z označbami in so prosto medsebojno spremenljivi s celimi števili,
    • znakovni nizi niso posebni podatkovni tip, ampak so po navadiizvedeni kotničelno omejena polja znakov znadzornimničelnim znakom'\0',[b]
  • nizkonivojski nepreverjeni dostop do pomnilnika s pomočjo pretvorbe strojnih naslovov v tipske kazalce,[c][18]
  • podprogrami, ki ne vračajo vrednosti, so posebni primer funkcij z netipskim vrnitvenim tipomvoid,
  • pomnilnik je mogočedodeliti programu s kliciknjižniških podprogramov,
  • uporabapredprocesorskega jezika,predprocesorja C, za naloge kot so določevanjemakrojev, vključevanje večkratnih datotek z izvorno kodo inpogojno prevajanje,
  • osnovna oblikamodularnosti: datoteke se lahko prevedejo samostojno inpovežejo skupaj, z nadzorom katere funkcije in podatkovni objekti so vidni v drugih datotekah prek atributovstatic aliextern,
  • preprostjedrski jezik s pomembno kompleksno funkcionalnostjo, kot na primer upravljanjevhodnoizhodnih (V/I) nalog in delo zznakovnimi nizi,matematične funkcije ali delo z datotekami omogočajo knjižniški podprogrami,
  • preprost sistempodatkovnih tipov, ki obvaruje pred brezpredmetnimi operacijami,
  • slovarsko področje spremenljivk,
  • usmeritev naproceduralno programiranje z zmožnostjo programiranja v slogustrukturalnega programiranja,
  • označitvenaskladnja posnema kontekst rabe. C nima rezervirane besede »define« in se namesto tega stavek, ki se začne z imenom tipa, vzame kot označitev. Ne obstaja rezervirana beseda »function«, namesto tega je funkcija naznačena z oklepajema, ki objemata seznam njenihparametrov,
  • parametri, ki prehajajo vfunkcije po vrednosti in ne po sklicu (referenci),
  • zelo omejena raba ukazaelse (načelo KISS),
  • ustvarjena koda ima po prevajanju razmeroma enostavne potrebe na osnovni platformi, zaradi česar je primerna za ustvarjanje operacijskih sistemov in za uporabo vvgrajenih sistemih.

C ne vsebuje nekaterih gradnikov, ki so sestavni deli novejših, sodobnejših visokonivojskih jezikov, kot na primerobjektne usmerjenosti ali samodejnegačiščenja pomnilnika, tako da imaročno upravljanje pomnilnika. Ti gradniki se lahko velikokrat izvedejo ali emulirajo s pomočjo zunanjih knjižnic (na primer s knjižnicoGLib Object System ali zBoemovim čiščenjem pomnilnika).

Razvoj

[uredi |uredi kodo]

Zgodnji razvoj

[uredi |uredi kodo]
Ken Thompson inDennis Ritchie, glavna tvorca programskega jezika C
Časovnica razvoja jezika C[19]
letoneuradno
ime
uradni
standard
1972prva izdaja
1978K&R C,C78
1989,
1990
ANSI C, C89,
ISO C, C90
ANSI X3.159-1989
ISO/IEC 9899:1990
1999C99, C9XISO/IEC 9899:1999
2011C11, C1XISO/IEC 9899:2011
2018C17, C18ISO/IEC 9899:2018
2024C23, C2XISO/IEC 9899:2024
prihodnostC2Y
18-bitniminiračunalnikDECPDP-7A (S#115) pred restavriranjem v Oslu leta 2005. Na takšnem stroju so leta 1969 Thompson, Ritchie,Ossana, Canaday inMcIlroy vzbirnem jeziku razvilioperacijski sistemUnix

Izvor jezika C je tesno povezan z razvojem operacijskega sistemaUnix, ki so ga izvirno razvili vzbirnem jeziku naminiračunalnikuDECPDP-7 Ritchie, Thompson,Joe Ossana, Rudd Canaday inDoug McIlroy v AT&T Bellovih laboratorijih, in vključili več zamisli svojih kolegov.[20] V začetku Thompson niti ni programiral na samem PDP-7, ampak je rabil množico makrojev za zbirni jezik GEMAP na32-bitnemosrednjem strojuGeneral ElectricGE-635. Nato je poprocesor tvoril papirni trak, ki ga je PDP-7 lahko prebiral.[10] Kmalu je Unix s preprostim jedrom, zbirnim jezikom, preprostolupino (tolmačem ukazov) in z nekaterimi pripomočki (kot npr. Unixovi ukazirm,cat,cp) leta 1969 postal samozadosten, in razvoj se je lahko nadaljeval neodvisno na samem PDP-7. McIlroy je kmalu zatem tvoril prvi visokonivojski jezik sistema Unix, izvedboprevajalnika prevajalnikovTMG Roberta M. McClurea. McIlroy inBob Morris sta uporabila TMG za zgodnji prevajalnik jezikaPL/I v operacijskem sistemuMultics. Thompson se je zaradi McIlroyjevega uspeha reproduciranja TMG odločil, da je Unix, ki verjetno tedaj še ni bil imenovan tako, potreboval lastensistemski programski jezik.

Glavni članek:programski jezik B.

Pisanje v zbirnem jeziku novonastalega Unixa je bilo nerodno. Za pisanje programskih struktur se je porabilo več časa, kodo je bilo težje razhroščevati in jo razumeti.[21] Thomson je želel imeti prednosti visokonivojskega jezika vendar ne v smislu operacijskega sistema Multics, napisanega v PL/I in zbirnem jeziku. Bil je vodja neformalne skupine v AT&T, ki je začela pregledovati možnosti drugih operacijskih sistemov in višjenivojskih jezikov. Najprej je s pomočjo TMG leta 1970 neuspešno hotel uporabitiFortran,[22] nato pa je ustvariljezik B s poenostavitvijo raziskovalnega sistemskega jezikaBCPL, ki ga je leta 1967 razvil Martin Richards, tako da je lahko njegovtolmač šel v 8kB18-bitnibesedni pomnilnik računalnika PDP-7. Uradni opis jezika BCPL tedaj ni bil na voljo.[23] Thompson je spremenil njegovo skladnjo z manjbesedami in podobno poenostavljenemuAlgolu, znanemu kot SMALGOL.[24] Jezik je imenovalB in ga opisal kot »semantika BCPL z veliko skladnje SMALGOL.«[10][24] Tako kot BCPL je imel Bzagonski prevajalnik za lažji prenos na nove stroje.[24] Vendar je bilo le nekaj pripomočkov na koncu napisanih v B, ker je bil prepočasen in ni mogel izkoristiti funkcij PDP-11, kot je na primerbajtno naslovljivost.

B se je izkazal za zelo počasnega in nezmožnega za sistemsko programiranje v samem Unixu. Tako kot BCPL je bil brez tipov. Pri novem zmogljivejšem računalniku DECPDP-11 je bil jezik brez tipov neizvršljiv. Njegov procesor je podpiral podatkovne tipe različnih velikosti in z jezikom B tega ni bilo moč izraziti. Problem je bilo tudi izvajanje. Thompson in Ritchie sta se odločila prenesti operacijski sistem na PDP-11. Prva različica PDP-11 je imela 16 kB pomnilnika za operacijski sistem in 8 kB za uporabniške programe.[20] Tudi njegov operacijski sistem je bil napisan v zbirnem jeziku.[10] Želela sta napisati operacijski sistem v jeziku B.

Novi B in prva izdaja C

[uredi |uredi kodo]

Najprej je zaradi nezmožnosti rabe nekaterih prednosti računalnika PDP-11, še posebej bajtno naslovljivost, v letu 1971 nastal »novi B« (NB), ki je rešil te probleme.[19][24] Pomemben dodatek je bil znakovni podatkovni tip. Thompson je začel uporabljati NB za pisanjeUnixovega jedra in njegove zahteve so oblikovale smer razvoja jezika.[24][25] Do leta 1972 so bili jeziku NB dodani bogatejši tipi: NB je imelpolja tipovint inchar. Dodani so bili tudikazalci, zmožnost ustvarjanja kazalcev na druge tipe, polja vseh tipov in tipe, ki jih vračajo funkcije. Polja znotraj izrazov so postala kazalci. Napisan je bil nov prevajalnik in jezik se je leta 1972 preimenoval v C.[10] Postal je prevajalni in ne tolmačitveni jezik.

Prevajalnik C in nekateri pripomočki, izdelani z njim, so bili vključeni v različicoVersion 2 Unix, ki je znana tudi kotResearch Unix.[26]

Strukture in ponovni zapis Unixovega jedra

[uredi |uredi kodo]

Začetni razvoj jezika C je po Ritchiejevih besedah potekal v AT&T Bellovih laboratorijih med letoma 1969 in 1973.[10] Najbolj kreativno obdobje je bilo leta 1972. Tedaj je bila večina Unixa ponovno napisana v C-ju.[27] Do leta 1973 z dodatkom podatkovnega tipazapisovstruct je C postal dovolj močan za prevod Unixovegajedra. Novi jezik je dobil ime »C«, ker so bili njegovi gradniki izvedeni iz jezika »B«, ta pa je bil po Thompsonovih besedah okleščena različica jezika BCPL.[28] Novo jedro z reimplementacijo jezika C je imela različicaVersion 4 Unix, izdana novembra 1973.[10]

Predprocesor je bil predstavljen okoli leta 1973 na pozivAlana Snyderja in tudi kot priznanje uporabnosti mehanizmov za vključitev datotek, ki so na voljo v BCPL in PL/I. Njegova izvirna različica je vsebovala samo vključene datoteke in preproste zamenjave znakovnih nizov (stringov): makrov#include in#define brez parametrov. Kmalu za tem ga je razširil predvsemMike Lesk in nato John Reiser, da je vključeval makre z argumenti inpogojno prevajanje.[10]

Tako je bilo Unixovo jedro prvo jedro kakšnega operacijskega sistema napisano v drugem jeziku od zbirnega. Pred tem sta bila na primer še operacijska sistema Multics (napisan v PL/I) in MCP (Master Control Program) za sistemBurroughs B5000 (napisan vALGOLu) leta 1961. Leta 1977 sta Ritchie inStephen Curtis Johnson dodatno spremenila jezik C za pospešitevprenosljivosti operacijskega sistema Unix. JohnsonovPortable C Compiler (PCC) je služil kot osnova za več izvedb C-ja na novih platformah.[25]

Naslovnica izvirne prve izdaje knjigeProgramski jezik C (The C Programming Language) iz leta 1978

Leta 1978 sta Kernighan in Ritchie objavila prvo izdajo knjigeProgramski jezik C (The C Programming Language).[29] Ta knjiga, pri programerjih v C-ju znana kot »bela knjiga« (white book), oziroma »K&R«,[10] je bila mnogo let neformalnaspecifikacija jezika. Različica jezika C, ki ga knjiga opisuje, se navadno imenuje »K&R C«. Ker je bila izdana leta 1978, se včasih imenuje tudiC78.[30] Druga izdaja knjige[31] pokriva kasnejši standardANSI C, opisan spodaj.

K&R je uvedla nekaj jezikovnih gradnikov:

  • standardna vhodnoizhodna knjižnica
  • podatkovni tiplong int
  • podatkovni tipunsigned int
  • sestavljeni prireditveni operatorji v obliki=op (kot npr.=-) so bili spremenjeni v oblikoop= (to je-=) zaradi semantične dvoumnosti pri tvorjenju takšnih konstruktov kot npr.i=-10, kar je bilo tolmačeno koti =- 10 (zmanjšaji za vrednost 10) namesto možno predvidenegai = -10 (priredii vrednost -10).

Tudi po objavi standarda ANSI leta 1989, je K&R C še vedno mnogo let veljala za »najmanjši skupni imenovalec« na katerega so se programerji v C-ju omejili, kadar je bila zaželena največja možna prenosljivost, saj je bilo v rabi še vedno več starejših prevajalnikov, skrbno napisana koda v K&R C pa je bila lahko tudi veljavni standard za C.

V zgodnejših različicah C-ja je bilo treba pred opredelitvijo (definicijo) uvesti le funkcije, ki so vračale vrednosti razen tipovint. Funkcije, ki so se rabile brez predhodnih označitev (deklaracij), so privzeto vračale vrednostiint, če so uporabile njihove vrednosti. Na primer:

longneka_funkcija();/* To je označitev funkcije, tako da   *//* prevajalnik lahko pozna ime in tip  *//* vrednosti, ki jo funkcija vrača     *//* int */druga_funkcija();/* Druga označitev funkcije. Ker je    *//* to zgodnja različica C, je tukaj    *//* implicitni tip 'int'. Komentar kaže,*//* kje bi bil v kasnejših različicah   *//* potreben izrecni določilnik tipa    *//* 'int'.                              *//* int */klicna_funkcija()/* To je opredelitev funkcije, ki      *//* vključuje njeno telo s kodo med     *//* { zavitima oklepajema }. Ker ni     *//* določen tip vračane vrednosti,      *//* funkcija implicitno vrača tip 'int' *//* v tej zgodnji različici C.          */{longtest1;register/* int */test2;/* Tukaj navedba tipa 'int' ni         *//* potrebna. Določilnik tipa 'int' v   *//* komentarju bi bil potreben v        *//* kasnejših različicah C. Ključna     *//* beseda 'register' nakazuje          *//* prevajalniku, da se naj ta          *//* spremenljivka idealno shrani v      *//* register v nasprotju znotraj okvirja*//* sklada.                             */test1=neka_funkcija();if(test1>0){test2=0;}else{test2=druga_funkcija();}returntest2;}

Določilnike (specifikatorje) tipaint, ki so izpuščeni, v K&R C ni bilo treba navajati, kasnejši standardi pa so jih zahtevali.

Ker označitev funkcij v K&R C ni vsebovala nobenega podatka o parametrih funkcije, senjihovo preverjanje ni izvedlo, čeprav je nekaj prevajalnikov javljalo opozorilno sporočilo, če je bila lokalna funkcija klicana z napačnim številom parametrov, ali, če je več klicev zunanje funkcije rabilo različno število tipov parametrov. Razvili so več ločenihorodij, kot na primer Unixov pripomočeklint, ki so poleg drugih stvari lahko preverjala doslednost rabe funkcij križem v več datotekah izvorne kode.

Po objavi K&R C so k jeziku dodali več gradnikov, ki so jih podpirali prevajalniki, na primer od AT&T (še posebejPCC[32]) in od nekaterih drugih ponudnikov. Med njimi so:

  • funkcije tipavoid (funkcije, ki ne vračajo vrednosti)
  • funkcije, ki vračajo podatkovne tipestruct aliunion (namestokazalcev. Pred tem so funkcije lahko vračale le en kazalec, celo številoint ali število s plavajočo vejicofloat)
  • prireditev za podatkovne tipestruct
  • naštevni tipi (enumerated types, pred tem so se rabile predporocesorske opredelitve za cele fiksne vrednosti, na primer#define dZELENA 3)

Veliko število razširitev, pomanjkanje dogovora ostandardni knjižnici, priljubljenost jezika in dejstvo, da tudi na operacijskem sistemu Unix prevajalniki niso dosledno izvrševali specifikacije K&R, je vodilo do potrebe za standardizacijo.[33]

ANSI C in ISO C

[uredi |uredi kodo]
Glavni članek:ANSI C.

V poznih 1970-ih in 1980-ih so izvedli različice C-ja za širok razponosrednjih računalnikov,miniračunalnikov inmikroračunalnikov, vključno zosebnim računalnikomIBM PC, saj se je tedaj njegova priljubljenost zelo povečala.

Leta 1983 jeAmeriški državni inštitut za standarde (ANSI) ustanovil odbor X3J11 za ustanovitev standardne specifikacije jezika C. X3J11 je osnoval standard za C na Unixovi izvedbi; vendar so neprenosljivi del Unixove knjižnice C predalidelovni skupini 1003IEEE, ki je postala osnova za standardPOSIX leta 1988. Leta 1989 so standard C potrdili kot ANSI X3.159-1989 »Programming Language C«. Ta različica jezika se po navadi imenujeANSI C, Standard C ali včasih C89.

Leta 1990 je standard ANSI C (z oblikovnimi spremembami) sprejelaMednarodna organizacija za standardizacijo (ISO) kot ISO/IEC 9899:1990, kar se včasih imenuje C90. Tako se izraza »C89« in »C90« nanašata na isto različico programskega jezika.

Kakor druge nacionalne ustanove za standarde ANSI ni več razvijal standarda C neodvisno, ampak ga je odložil k mednarodnemu standardu C, ki ga vzdržuje delovna skupinaISO/IEC JTC1/SC22/WG14. Nacionalna usvojitev posodobitve mednarodnega standarda se po navadi izvede še v letu publikacije ISO.

Eden od ciljev procesa standardizacije jezika C je bilo tvorjenjesupermnožice K&R C, ki bi vključevala več predhodno uvedenih neuradnih gradnikov. Standardizacijski odbor je vključil tudi več dodatnih gradnikov, kot so npr.prototipi funkcij (izposojeno od C++), kazalcivoid, podpora za mednarodninabor znakov inlokalnih parametrov, ter predprocesorske izboljšave. Čeprav je bilaskladnja za označitev parametrov povečana, da bi vključevala slog rabljen v C++, je bil vmesnik K&R zaradi združljivosti z obstoječo izvorno kodo še naprej dovoljen.

C89 podpirajo trenutni prevajalniki za C, večina kode v C-ju, ki je zapisana sedaj, temelji na njem. Vsak program, zapisan le v ANSI C in brez privzetkov odvisnestrojne opreme, se bo izvajal pravilno na katerikoliplatformi v skladu z izvedbo C-ja v mejah svojih virov. Brez takšnih previdnosti se lahko programi prevedejo le na določenih platformah ali z določenim prevajalnikom zaradi na primer rabe nestandardnih knjižnic, kot so knjižnicegrafičnih uporabniških vmesnikov (GUI), ali oslonitev na računalniške ali specifične platformske atribute, kot je točna velikost podatkovnih tipov inureditev bajtov (endianost,endianness).

V primerih, ko mora biti koda prevedljiva tako v skladu s standardom ali s prevalniki na osnovi K&R C, se lahko rabi makro__STDC__, ki razdeli kodo na dele z ANSI C in K&R, ter tako prepreči prevajalnikom na osnovi K&R C uporabo gradnikov, razpoložljivih le v ANSI C.

Po standardizacijskem procesu ANSI/ISO je specifikacija jezika C več let ostala statična. Leta 1995 so k standardu C iz leta 1990 dodali Normative Amendment 1 (ISO/IEC 9899/AMD1:1995, neformalno znan kot C95). Z njim so popravili nekaj podrobnosti in dodali obsežnejšo podporo mednarodnega nabora znakov.[34]

Glavni članek:C99.

Standard C so v poznih 1990-ih na novo popravili, kar je leta 1999 vodilo do objave standarda ISO/IEC 9899:1999, ki je v splošnem znan kot »C99«. Od tedaj so ga s tehniškimi popravki dopolnili trikrat.[35]

C99 je uvedel več novih gradnikov. Na primervrinjene funkcije (inline functions), novepodatkovne tipe (na primerlong long int incomplex za delo skompleksnimi števili),polja s spremenljivo dolžino (variable-length arrays (VLA)),[36]prilagodljive člane polj (flexible array members),[36] izboljšano podporo aritmetike splavajočo vejicoIEEE 754, podporovariadičnih makrojev (variadic macros, makrojev s spremenljivomestnostjo (arnostjo)) in podporo enovrstičnih komentarjev, ki se začnejo z dvemapoševnicama//, kot vBCPL ali C++. Več teh gradnikov je kot razširitve tedaj že podpiralo nekaj prevajalnikov za C.

C 99 je večinoma nazaj združljiv s C90, vendar je na nekaterih mestih strožji. Še posebej, označitev, ki je brez določilnika tipa, implicitno privzeto ni več tipaint. Standardni makro__STDC_VERSION__ je določen z vrednostjo199901L in nakazuje, da je na voljo podpora C99.GCC,Solaris Studio in drugi prevajalniki za C sedaj podpirajo mnogo ali pa vse nove gradnike C-ja v standardu C99. Prevajalnik za C vMicrosoft Visual C++ izpolnjuje standard C89 in tiste dele C99, ki so zahtevani za združljivost z različico standardaC++11.[37]

Poleg tega standard C99 zahteva podporo zaoznačevalnike (identifikatorje)Unicode v oblikiubežnih znakov (escape characters) (na primer\u0040 ali\U0001f431) in predlaga podporo za surova imena Unicode.

Leta 2007 so se začela dela na novi različici standarda C, ANSI C11 ali ISO/IEC 9899:2011, do objave 8. decembra 2011 neformalno imenovane »C1X«. Standardizacijski odbor C je sprejel smernice za omejitev usvojitve novih gradnikov, ki jih niso preskusili z obstoječimi izvedbami.

V standardu C11 se je pojavilo več novih gradnikov jezika C in knjižnic, na primer: makroji rodovnih tipov, anonimne strukture, izboljšana podporakodirnega standardaUnicode, atomske operacije,mnogonitnost in funkcije s preverjanjem mej. Neketeri deli obstoječe knjižnice C99 so postali izbirni, izboljšana je bila tudi združljivost s C++. Standardnimakro__STDC_VERSION__ je opredeljen kot201112L in tako označuje, da je na voljo podpora standardu C11.

C17 je neuradno ime za standard programskega jezika C, objavljen junija 2018 kot ISO/IEC 9899:2018. Ne uvaja novih jezikovnih gradnikov, le tehnične popravke in pojasnila za napake v C11. Standardni makro__STDC_VERSION__ je opredeljen kot201710L in tako označuje podporo standardu C17.

C23 je neformalno ime za trenutno večjo standardno različico jezika C. Med celotnim razvojem je bila neuradno znana kot »C2X«. C23 je bila objavljena 31. oktobra 2024 kot ISO/IEC 9899:2024.[16] Standardni makro__STDC_VERSION__ je opredeljen kot202311L in tako označuje podporo standardu C23.

C2Y je neuradno ime za naslednjo večjo standardno različico jezika C po C23 (C2X), ki bo verjetno objavljena v kasnejših 2020-ih. Zato nosi ime '2' in »C2Y«. Delovna skupinaISO/IEC JTC1/SC22/WG14 je 21. februarja 2024 objavila zgodnji delovni osnutek kot N3220.[38]

Vgradni C

[uredi |uredi kodo]
Glavni članek:vgradni C.

Programiranje zvgradnim C-jem (embedded C) zgodovinsko zahteva nestandardne razširitve k jeziku C, da se lahko podpirajo C-ju tuji gradniki, kot so npr.:aritmetika sfiksno vejico, mnogokratne različnepomnilniške vrstice in osnovnevhodnoizhodne operacije.

Leta 2008 jestandardizacijski pododbor SC 22 objaviltehniško poročilo z razširitvijo jezika C,[39] ki se je nanašala na probleme med razširitvami jezika C za različnevgradne sisteme, in tako zagotovila splošni standard za vse ustrezne izvedbe. Vključuje več gradnikov, ki v normalnem C niso na voljo: aritmetika s fiksno vejico, prostori z imenovanimi naslovi in osnovno vhodnoizhodno naslavljanje strojne opreme.

Vgradni C rabi večino skladnje in semantike standardnega C-ja: funkcijamain, opredelitev spremenljivk, označitev podatkovnih tipov, pogojni stavki (if,switch,case),zanke (while,for), funkcije, polja in znakovni nizi, strukture in unije, bitne operacije, makroji ipd.

Skladnja

[uredi |uredi kodo]
Glavni članek:skladnja jezika C.

C imaformalno slovnico, ki jo določa standard C.[40] Z razliko od nekaterih drugih jezikov, kot je npr.FORTRAN 77, je izvorna koda C-ja proste oblike, kjer seznaki za prazni prostor lahko rabijo poljubno, koda pa ni odvisna od stolpčnih ali besedilno-vrstičnih omejitev. Konci vrstic v C na splošno niso pomembni, meje vrstic pa so drugače med predprocesorsko fazo pomembne.

Komentarji

[uredi |uredi kodo]

Komentarji so lahko med razmejilnima znakoma/* in*/ enovrstično ali mnogovrstično, od standarda C99 naprej pa tudi za razmejilnima znakoma// enovrstično do konca vrstice. Komentarji, ki jih razmejujeta/* in*/, ne smejo biti vgnezdeni. Če se zaporedje teh dveh znakov pojavi znotrajznakovnega niza ali znakovnegačrkovnega simbola, se ne obravnavata kot razmejilna znaka komentarja.[31]:192 Komentarji oblike:

/* ... *//*...*//* ... // ... */// .../*... // ...*/

so v redu, vgnezdeni enovrstično pa npr. ne:

/* /* ... */...*/

ali vgnezdeni mnogovrstično:

/*/* ...*/...*/

saj drugo zaporedje/* ne velja za razmejilni znak komentarja, kot tudi ne drugo zaporedje*/, ki je sedaj zunaj komentarja, in prevajalnik bi v obeh primerih javil napako.

Izrazi

[uredi |uredi kodo]

Datoteke s C-jevsko izvorno kodo vsebujejo označitev (deklaracijo) in opredelitev (definicijo) funkcij. Opredelitve funkcij po vrsti vsebujejo označitve instavke. Označitve opredeljujejo nove podatkovne tipe z rezerviranimi besedami, kot so:struct,union inenum, ali prirejajo tipe in morda rezervirajo pomnilniška mesta novim spremenljivkam, po navadi z zapisom tipa, ki mu sledi ime spremenljivke. Rezervirane besede, kot stachar inint, označujejo vgrajene tipe. Deli kode so obdani zzavitima oklepajema{ in}, ki omejujeta označitvenidoseg ali pa delujeta kot samostojni stavek zanadzorne strukture.

C kot imperativni jezik za označitev dejanj rabistavke. Najbolj razširjeni stavek jeizrazni stavek, ki vsebuje izraz, kateremu je treba določiti vrednost, izrazu pa sledipodpičje. Zaradi še večje preglednosti se podpičje velikokrat razmakne od označitvenih/ukaznih besed z dodatnim presledkom. Na primer:

inta;|inta;for(i=0;i<max;i++)|for(i=0;i<max;i++)

Kotstranski pojav določitve vrednosti se funkcije lahkokličejo in spremenljivkam se lahkopriredijo nove vrednosti. Za spreminjanje normalne zaporedne izvršitve stavkov ima C več stavkov za nadzor pretoka, ki jih označujejo rezervirane besede.Strukturalno programiranje je podprto s pogojno izvršitvijoif ... [else], z iterativnimi izvršitvami (zankami)do ...while,while infor. Stavekfor ima ločene dodelitvene izraze, izraze za preverjanje in izraze za ponovno dodelitev vsak od njih pa se lahko opusti. Izrazabreak incontinue se lahko rabita v zankah.break se rabi za zapustitev najbolj notranjega zančnega stavka,continue pa za preskočitev na njeno ponovno dodelitev (alokacijo). Obstaja tudi nestrukturalni stavekgoto, ki preusmerja neposredno na imenovanooznako (label) znotraj funkcije. Oznake so tvorijo z imeni, ki jim sledidvopičje na primeroznaka:.switch izbere primercase, ki se izvede na podlagi vrednosti celoštevilskega izraza. Za razliko od mnogih drugih jezikov bo nadzorni pretok padel v naslednji primercase, razen če ga prekine prekinitevbreak.

Izrazi lahko rabijo različne vgrajene operatorje in lahko vsebujejo klice funkcij. Vrstni red po katerem se določijo vrednosti parametrom funkcij in operandom večine operatorjev ni določen. Določevanje vrednost je lahko tudi vloženo vmes. Vendar se bodo vsi stranski pojavi (vključno s pomnilnikom do spremenljivk) pojavili pred naslednjo »zaporedno točko«. Zaporedne točke vsebujejo zaključek vsakega izraznega stavka ter vstop in vračanje iz vsakega klica funkcije. Zaporedne točke se pojavijo tudi med določevanjem vrednosti izrazov, ki vsebujejo določene operatorje (&&,||,?: inoperator vejica). To dovoljuje visoko stopnjo optimizacije kode prevajalnika, vendar od programerjev v C zahteva večjo skrb za dosego zanesljivih rezultatov kot je potrebna pri drugih programskih jezikih.

Kernighan in Ritchie v uvodu knjigeProgramski jezik C pravita: »Kakor drugi jeziki ima C svoje hibe. Nekateri od operatorjev imajo napačno prednost; nekateri deli skladnje bi lahko bili boljši.«[29]:3 Standard C ni poskušal popraviti veliko od teh hib zaradi vpliva takšnih sprememb na že obstoječo programsko opremo.

Nabor znakov

[uredi |uredi kodo]

Osnovni nabor znakov izvorne kode jezika C vsebuje:

Nova vrstica označuje konec besedilne vrstice. Ni treba da odgovarja dejanskemu posameznemu znaku, čeprav je v C zaradi prikladnosti to posamezen znak.

Lahko se rabijo tudi dodatni mnogobitno zakodirani znaki v prikazuliteralov znakovnih nizov, vendar niso povsemprenosljivi. Od standarda C99 se lahko prenosljivo vgradijo mnogonacionalni znaki kodirnega standardaUnicode v besedilo izvorne kode C s pomočjo kodiranj\uXXXX ali\UXXXXXXXX, kjerX označuješestnajstiško zapisan znak.

Osnovni izvršni nabor znakov C obsega enake znake, skupaj s prikazomopozorila (alert),povratnega znaka (backspace) inpomika na začetek vrstice (carriage return). Podporaizvajalnemu času (runtime) za razširjene nabore znakov se je z vsako različico standarda za C povečevala.

Rezervirane besede

[uredi |uredi kodo]

Naslednje besede (keywords;reserved words) so v jeziku Crezervirane in imajo strog pomen kot posamezni znaki (tokens).[41][42]

C89 ima 32 rezerviranih besed. Ne smejo se na novo opredeliti ali se rabiti kotoznačevalniki v drugih kontekstih:

Besede soobčutljive na male ali velike črke.INT,INt,InT,Int,iNT,iNt aliinT na primer ni enako kotint. V različnih izvedbah prevajalnikov za C se lahko pojavijo tudi druge rezervirane besede, npr.ada,asm,fortran,pascal, čeprav se tam običajno nestandardne besede začnejo z enim ali dvemapodčrtajema, npr.__asm,_Cdecl ipd.[43] V primerjavi z drugimi velikimi jeziki je imel C majhno število rezerviranih besed.Ada jih ima na primer 62. Ena od značilnosti jezika C je, da lahko naredi veliko z relativno malo posebnimisimboli in rezerviranimi besedami.[41]

C99 je dodal pet rezerviranih besed (‡ označuje drugačen črkovalni vzdevek za rezervirano besedo C23):

inline
restrict
_Bool
_Complex
_Imaginary

C11 je dodal še sedem razerviranih besed (‡ označuje drugačen črkovalni vzdevek za rezervirano besedo C23):

_Alignas
_Alignof
_Atomic
_Generic
_Noreturn
_Static_assert
_Thread_local

C23 je dodal še 15 rezerviranih besed:

  • alignas
  • alignof
  • bool
  • constexpr
  • false
  • nullptr
  • static_assert
  • thread_local
  • true
  • typeof
  • typeof_unqual
  • _BitInt
  • _Decimal32
  • _Decimal64
  • _Decimal128

Večina nedavno rezerviranih besed se začne s podčrtajem, ki mu sledi velika začetnica, ker so bili označevalniki te oblike predhodno rezervirani s standardom C za uporabo samo v izvedbah. Ker obstoječa izvorna koda programa ne bi smela uporabljati teh označevalnikov, na to ne bi vplivalo, ko bi izvedbe C začele podpirati te razširitve programskega jezika. Nekatere standardne zaglavne datoteke opredeljujejo bolj priročne sinonime za podčrtane označevalnike. Nekatere od teh besed so bile dodane kot rezervirane besede z običajnim črkovanjem v C23, ustrezni makri pa so bili odstranjeni.

Na začetku je imel C manj rezerviranih besed, na primer 29, sedaj pa jih pozna 63. Besedaentry se je redko ali pa nikoli rabila in sedaj ni več rezervirana. V drugi izdaji knjigeProgramski jezik C sta Kernighan in Richie zapisala: »... [rezervirana beseda]entry, prej rezervirana, a nikoli uporabljena, ni več rezervirana.« in: »Mrtvorojena rezervirana besedaentry je umaknjena.« [31]:192, 259

Operatorji

[uredi |uredi kodo]
Glavni članek:operatorji v C in C++.

C podpira bogat naboroperatorjev, ki so simboli znotrajizraza za določevanje potrebnih opravil med njegovim izvajanjem. Njegovi operatorji so razdeljeni na osemnajst kategorij. C ima operatorje za:

C rabi operator=, ki je v matematiki rezerviran za izražanjeenakosti, za naznanitev prireditve po zgledu predhodnih jezikovFortrana inPL/I, vendar z razliko odALGOLa in njegovih izpeljank. Podobnost med cejevskima operatorjema za prireditev in za primerjanje enakosti (==) so kritizirali, saj se ju lahko preprosto zamenja. V mnogih primerih mora biti vsak rabljen v kontekstu drugega brez napak prevajalnika, čeprav nekateri prevajalniki tvorijo opozorila. Pogojni izrazif (a == b + 1) se na primer lahko napačno zapiše kotif (a = b + 1) in bo njegova vrednost po izvršitvi pravilna (true), če jea enak0 po prireditvi.[44]

Operatorska prednost v C ni vedno intuitivna, saj se na primer operator== zvezuje tesneje (se izvrši pred) kot operatorja& (bitni IN (AND) in| (bitni ALI (OR) v izrazih, kot jex & 1 == 0, ki bi moral biti zapisan kot(x & 1) == 0, če je bil to namen programerja.[45]

Zgradba, oblika programa in slog v C

[uredi |uredi kodo]

Osnovni gradnik programa v C je funkcija.[46] Vsak program v C je zbirka ene ali več funkcij. Funkcije sestavljajo označitve spremenljivk in stavki, ali zapleteni ukazi, obkrožata pa jih zavita oklepaja ({ in}).

Zgleda programov

[uredi |uredi kodo]

Program Pozdravljen, svet

[uredi |uredi kodo]
Program »Hello, World!«Briana Wilsona Kernighana (1978)

Izvirni programPozdravljen, svetHello, World!«) se je pojavil v prvi izdaji knjigeProgramski jezik C in je postal model za uvodni program v večini učbenikov programskih jezikov:[29]:6

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

Spodnji zgled izpiše znakovni niz »Pozdravljen, svet!« nastandardni izhod s funkcijoprintf. Navadno je standardni izhod povezan s terminalom ali z zaslonom monitorja, lahko pa je tudi datoteka ali kakšna druga strojna naprava. Program je napisan v skladu s standardomANSI C.[d]

#include<stdio.h>intmain(void){printf("Pozdravljen, svet!\r\n");return0;}

Sledi analiza programa po vrsticah:

#include<stdio.h>

Prva vrstica v programu jepredprocesorski ukaz (navodilo, direktiva)#include. Pred samim prevajanjem programa predprocesor pregleda izvorno kodo in izvrši vse predprocesorske ukaze. Ti ukazi se vedno začnejo zznakom#. Ukaz#include povzroči, da se na njegovo mesto v izvorno kodo vključi datotekastdio.h, ki vsebuje standardne vhodnoizhodne funkcije.

intmain(void)

V naslednji vrstici se opredeli funkcija z imenommain. Ta funkcija ima poseben pomen v C programih. Pri začetkuizvajanja programa se najprej kliče ta funkcija. Rezervirana besedaint na začetku vrstice pove, da funkcijamain izvajalnemu sistemu vrne celo število, rezervirana besedavoid pa, da funkcija ne sprejme nobenih parametrov. Funkcijamain po standarduANSI C vedno vrača vrednost, čeprav nekateri prevajalniki prevedejo kodo uspešno, četudi temu ni tako. Tudi v jeziku C++ je ta funkcija še vedno C-jevska. Funkcijamain je lahko opredeljena s pomočjo naslednjih štirih oblik ob označitvi:[47][e][f][g][h]

intmain(){/* ... */}intmain(void){/* ... */}intmain(intargc,char*argv[]){/* ... */}intmain(intargc,char**argv){/* ... */}

oziromaprototipno:

intmain();intmain(void);intmain(int,char*[]);intmain(int,char**);

Prvi dve opredelitvi sta enakovredni (in združljivi s C++).

{

Odprti zaviti oklepaj pomeni začetek opredelitve funkcijemain.

printf("Pozdravljen, svet!\r\n");

V tej vrstici se kliče funkcijaprintf, ki je označena v datotekistdio.h. Pri tem klicu se funkcijiprintf poda en parameter v obliki znakovnega niza, ki jepomnilniški naslov prvega znaka vliteralu znakovnega niza"Pozdravljen, svet\r\n". Literal znakovnega niza je neimenovanopolje, ki jo samodejno nastavi prevajalnik, z elementi tipachar in končnimznakom NULL (vrednost ASCII 0), ki označuje konec polja, kar omogoča funkcijiprintf, da določi dolžino niza). Znak NULL se lahko zapiše tudi kotubežno zaporedje\0. Dvoznakovni niz\n je standardno ubežno zaporedje, ki se v C prevede v znaknove vrstice (EOL,end of line). Znak je namenjen kot ukaz izhodni napravi, da postavi trenutno lego na začetek naslednje vrstice. Vrnjena vrednost funkcijeprintf je tipaint, vendar je tiho zavržena, ker se ne uporablja. Previdnejši program lahko preizkusi vrnjeno vrednost, da preveri, ali je funkcijaprintf uspela.Podpičje; prekine stavek.

return0;

Vrstica zaključi izvajanje funkcijemain in vrne celo število0.

}

Zaprti zaviti oklepaj pomeni zaključek opredelitve funkcijemain. Po specifikaciji standarda C99 in novejših bo funkcijamain (za razliko od vseh drugih funkcij) implicitno vrnila vrednost0 preden doseže}, ki prekine funkcijo.[i] Vrnjeno vrednost0 izvajalni sistem tolmači kot izhodno kodo, ki označuje uspešno izvedbo funkcijemain.[48]

Najmanjši program

[uredi |uredi kodo]

Katera opredelitev funkcijemain se uporabi v programu, je verjetno odvisno od posamezne izbire. Trenutni standard C vsebuje dva zgleda rabemain() in dvamain(void), standard C++ pa rabimain(). Vrednost, ki jomain vrača (in mora biti tipaint), služi kotstatus prekinitve. Tega program vrne gostiteljevemu okolju.

Standard C opredeljuje vrnitveni vrednosti0 (»nič napak« (zero errors)) inEXIT_SUCCESS, ki označujeta uspeh, terEXIT_FAILURE za označevanje neuspešnega izvajanja programa. (EXIT_SUCCESS inEXIT_FAILURE sta opredeljeni v standardni zaglavni datotekistdlib.h). Druge vrnitvene vrednosti služijo kot izvedbeni opredelitveni pomeni. VLinuxu na primer program, ki ga je prekinil ukazsignal, vrne kodo številske vrednosti signala plus 128.

Najmanjši pravilen program v C vsebuje prazno funkcijomain brez parametrov:

intmain(void){}

Lahko se zapiše tudi v več vrsticah:

intmain(void){/* začetek telesa funkcije v prvem     */}/* stolpcu vrstice                     */

ali redkeje sicer v skladu z dobrim slogom:

int/* podatkovni tip vrnjene vrednosti    */main(void)/* funkcije. Ime funkcije v prvem      */{/* stolpcu vrstice. Začetek telesa     */}/* funkcije v prvem stolpcu vrstice    */

Sploh pa je slaba praksa pisati neporavnano, kot npr:

intmain/*            *** *   * **/(void){}

ali:

intmain/* ** * *  ***/(void){}

oziroma poravnano brez reda:

intmain/***     *       ****/(void){}

Preveden program bo sicer deloval, izvorna koda pa je že v preprostem zgledu nepregledna. Seveda je treba rezervirane besede, imena spremenljivk in funkcij pisati brez presledkov.

Okroglaoklepaja (), ki sledita imenu funkcije, morata biti vključena, saj na ta način C razlikuje funkcije od navadnih spremenljivk. Načeloma pri funkcijah za imenom funkcije in odprtim oklepajem ni presledka, npr.main(void) in nemain (void), z razliko odsizeof (), ki dejansko strogo ni funkcija, in je skladenjska rezervirana beseda zaenočlenioperator.[49]sizeof je lahko podobno kotreturn brez okroglih oklepajev. Prireturn je to celo zaželeno, razen če je dvoumno.

Ker nista navedenareturn aliexit, funkcijamain ob izhodu vrne0.[48] To je poseben primer predstavljen v standarduC99, ki velja le za funkcijomain. Če se zahteva še ta navedba, ima najmanjši program obliko:

intmain(void){return0;}

Funkcijamain bo za uspešno delovanje programa po navadi klicala druge funkcije. Ni treba, da je na vrhu programa, tako da se program v C ne začne v prvi vrstici, ampak tam kjer je navedena funkcijamain.[46] Funkcijemain ni možno klicati ali jo zagnati s kakšno drugo funkcijo v programu. Kliče jo lahko leoperacijski sistem in na ta način se zažene program v C. Funkcijamain ni nikoli statična, in, če je navedena kotstatic int main(), bo prevajalnik običajno javil napako.

Nekatere izvedbe niso izvedljive, po navadi zaradi tega, ker niso mišljene za rabo z operacijskim sistemom. Takšne izvedbe se v standardu C imenujejoprostostoječe (free-standing). V prostostoječi izvedbi ni podrobnega opisa kako naj obravnava izvajanje programa. V programu še posebej ni treba opredeliti funkcijemain.

Druge funkcije se lahko imenujejo poljubno v skladu s skladnjo jezika. Lahko jih napiše programer sam ali pa se rabijo obstoječe iz knjižnic. Vmesniki za knjižniške funkcije so običajno navedeni z vključitvijozaglavnih datotek spredprocesorskim ukazom#include, objekti knjižnice pa se povežejo v končno izvršno sliko. Določene knjižniške funkcije, kot sta na primerprintf aliscanf, so opredeljene s standardom C, in se imenujejostandardne knjižniške funkcije.

Funkcija lahko vrne vrednost klicatelju po navadi drugi funkciji C-ja, ali gostiteljevemu okolju za funkcijomain. Zgoraj omenjena funkcijaprintf vrne koliko znakov je bilo izpisano, vendar se ta vrednost običajno prezre.

Podatkovni tipi

[uredi |uredi kodo]
Glavni članek:podatkovni tipi v C.
Koncepti jezika C po standarduC99

C imastatičnišibkisistem tipov, ki je deloma podoben sistemom tipov potomcevALGOLa, kot je npr.paskal, vendar C sam ni potomec Algola.[50] V C obstajajo vgrajeni tipi zacela števila različnih velikosti, tako predznačena in nepredznačena, števila splavajočo vejico (npr.racionalna števila),znake (char) innaštevne tipe (enum). Celoštevilski tipchar je pogosto rabi za enobajtne znake. C99 je z rezervirano besedo_Bool dodalBoolov podatkovni tip (Boolova spremenljivka). Obstajajo tudi izpeljani tipi, kot so:polja (tabele,arrays),kazalci (pointers),zapisi (records,struct) in nenaznačeneunije (unions,union).

C se velikokrat rabi v programiranju nizkonivojskih sistemov, kjer morda ni potrebe za sistemom tipov. Prevajalnik poskuša zagotoviti pravilnost tipov večine izrazov, vendar lahko programer zaobide preverbe na več načinov, ali s pomočjotipske opustitve (type cast), kjer ekscplicitno pretvori vrednost iz enega tipa v drugega, ali s pomočjo kazalcev ali unij, kjer se osnovni biti podatkovnega objekta na novo tolmačijo na kakšen drug način.

Za nekatere je označitvena skladnja v C neintuitivna, še posebejkazalci na funkcije. (Ritchiejeva zamisel je bila, da se določilniki označijo v kontekstu njihove rabe: »označitev zrcali rabo.«)[31]:122

C-jevskeobičajne aritmetične pretvorbe dovoljujejo tvorjenje učinkovite kode, vendar lahko včasih pride do nepričakovanih rezultatov. Primerjava predznačenih in nepredznačenih celih števil enake širine na primer zahteva pretvorbo predznačene vrednosti v nepredznačeno. To lahko povzroči nepričakovane rezultate, če je predznačena vrednost negativna.

Osnovni podatkovni tipi

[uredi |uredi kodo]

V jeziku C je večosnovnih podatkovnih tipov. Večina od njih se tvori iz enega od štirih osnovnih aritmetičnih določilnikov tipov v C (char,int,float indouble), ter štirih izbirnih določilnikov (signed,unsigned,short inlong). Vsi razpoložljivi osnovni aritmetični tipi so navedeni v razpredelnici:

podatkovni tip
insopomenke
pojasnilonajmanjša velikost
[biti]
mejne vrednosti
vlimits.h
formatno določilopripona za desetiške konstante
charnajmanjša naslovljiva enota stroja, ki lahko vsebuje osnovni nabor znakov. Njen tip jeceloštevilski. Dejanski tip je lahko predznačen ali nepredznačen, kar je odvisno od izvedbe. VsebujeCHAR_BIT bitov in njegov obseg je [−128, +127].[51]8CHAR_MIN /
CHAR_MAX
%c
signedcharenaka velikost kotchar, vendar je zagotovo predznačena in njegov obseg je [−128, +127].[51][j]8SCHAR_MIN /
SCHAR_MAX
%c(ali%hhi za numerični vnos)
unsignedcharenaka velikost kotchar, vendar je zagotovo nepredznačena. V dvojiškem zapisu je predstavljen brez zapolnjevalnih bitov, tako je njegov obseg točno [0, 2CHAR_BIT−1],[52] običajno [0, +255][53]80 /
UCHAR_MAX
%c(ali%hhu za numerični vnos)
short
shortint
signedshort
signedshortint
predznačeni celoštevilski tipshort. Njegov obseg je vsaj [−32.768, +32.767].[54][51][j]16SHRT_MIN /
SHRT_MAX
  • %hi %hd
unsignedshort
unsignedshortint
podobno kotshort, vendar nepredznačeno, in njegov obseg je vsaj [0, +65.535].[51]160 /
USHRT_MAX
%hu
int
signed
signedint
osnovni predznačeni celoštevilski tip. Njegov obseg je vsaj [−32.768, +32.767].[54][51][j]16INT_MIN /
INT_MAX
  • %i %d
brez[55]
unsigned
unsignedint
podobno kotint, vendar nepredznačeno, in njegov obseg je vsaj [0, +65.535].[51]160 /
UINT_MAX
%uu aliU[55]
long
longint
signedlong
signedlongint
predznačeni celoštevilski tiplong. Njegov obseg je vsaj [−2.147.483.648, +2.147.483.647].[54][51][j]32LONG_MIN /
LONG_MAX
  • %li %ld
l aliL[55]
unsignedlong
unsignedlongint
podobno kotlong, vendar nepredznačeno, in njegov obseg je vsaj [0, +4.294.967.295].[51]320 /
ULONG_MAX
%luobeu aliU inl aliL[55]
longlong
longlongint
signedlonglong
signedlonglongint
predznačeni celoštevilski tiplong long. Njegov obseg je vsaj [−9.223.372.036.854.775.808, +9.223.372.036.854.775.807].[54][51][j] Uveden s standardomC99.64LLONG_MIN /
LLONG_MAX
  • %lli %lld
ll aliLL[55]
unsignedlonglong
unsignedlonglongint
podobno kotlong long, vendar nepredznačeno in njegov obseg je vsaj [0, +18.446.744.073.709.551.615].[51] Uveden s standardomC99.640 /
ULLONG_MAX
%lluobeu aliU inll aliLL[55]
floattip za realna števila splavajočo vejico in enojno točnostjo. Dejanske značilnosti niso navedene (razen spodnjih mej), vendar je na večini sistemov todvojiški format števila s plavajočo vejico in enojno točnostjo IEEE 754 (32 bitov). Ta format zahteva izbirni Annex F »IEC 60559 floating-point arithmetic.«  FLT_MIN /
FLT_MAX
  • %f[k] %F
  • %g %G
  • %e %E
  • %a %A
f aliF
doubletip za realna števila s plavajočo vejico in dvojno točnostjo. Dejanske značinosti niso navedene (razen spodnjih mej), vendar je na večini sistemov todvojiški format števila s plavajočo vejico in dvojno točnostjo IEEE 754 (64 bitov). Ta format zahteva izbirni Annex F »IEC 60559 floating-point arithmetic.«  DBL_MIN /
DBL_MAX
  • %f[l]
  • %lf %lF
  • %lg %lG
  • %le %lE
  • %la %lA[m]
 
longdoubletip za realna števila s plavajočo vejico inrazširjeno točnostjo. Dejanske značilnosti niso navedene. Z razliko od tipovfloat indouble je lahkoformat števila s plavajočo vejico in razširjeno točnostjo x86 (80 bitov, tipično pa 96 ali 128 bitov v pomnilniku zzapolnjevanimi bajti), »double-double«, ki ni v skladu z IEEE (128 bitov),dvojiški format števila s plavajočo vejico in štirikratno točnostjo IEEE 754 (128 bitov), če je format s povišano točnostjo zagotovljen, ali drugače enako kotdouble. Za podrobnosti glej članek olong double. LDBL_MIN /
LDBL_MAX
  • %Lf %LF
  • %Lg %LG
  • %Le %LE
  • %La %LA[m]
l aliL

Dejanska velikost celoštevilskih tipov se v izvedbah razlikuje. Standar zahteva le velikostne povezave med podatkovnimi tipi in najmanšimi vrednostmi za vsak podatkovni tip:

Zahteve za povezave so, dalong long ni manjši odlong, ki ni manjši odint, ta pa ne manjši odshort. Ker je velikostchar vedno najmanjši podprti podatkovni tip, vsi drugi podatkovni tipi ne morejo biti manjši.

Najmanjša velikost zachar je8 bitov, najmanjši velikosti zashort inint sta 16 bitov, zalong 32 bitov in zalong long mora vsebovati vsaj 64 bitov.

Tipint mora biti celoštevilski tip, za katerega je ciljni procesor najbolj učinkovit. To omogoča veliko prilagodljivost, saj so lahko na primer vsi tipi 64-bitni. Vendar je priljubljeno več različnih shem celoštevilskih širin (podatkovnih modelov). To je zato ker podatkovni model opredeljuje kako različni programi med seboj komunicirajo, enotni podatkovni model se rabi znotraj uporabniškega vmesnika danega operacijskega sistema.[56]

Treba je omeniti, da je v praksi velikost tipachar po navadi 8 bitov, tipashort pa 16 bitov (kakor tudi njihova nepredznačena dvojnika). To velja za platforme pogoste v 1990-ih, kot so:SunOS 4 Unix, MicrosoftMS-DOS, sodobniLinux in Microchip MCC18 za vgradne 8-bitne mikrokontrolerje PIC.POSIX zahteva, da je velikostchar točno 8 bitov.

Tudi dejanska velikost in obnašanje tipov s plavajočo vejico se razlikuje v izvedbah. Edino zagotovilo je, dalong double ni manjši oddouble, ki ni manjši odfloat. Če ju strojna oprema podpira, se po navadi rabita 32-bitna in 64-bitna dvojiška formata s plavajočo vejicoIEEE 754.

Kazalci

[uredi |uredi kodo]

C podpira rabokazalcev, vrstosklica, ki zapisuje naslov ali mesto objekta ali funkcije v pomnilniku. Naslov objekta je odvisen od sistema. Kazalci v C so izpeljani podatkovni tipi in se lahkodereferencirajo za dostop podatkov, ki so shranjeni na naslovu na katere kažejo, ali kličejo funkcije na katere kažejo. S kazalci se lahko upravlja s pomočjo prirejanja alikazalčne aritmetike. Predstavitev vrednosti kazalca pri izvajanju je običajno surov pomnilniški naslov (mogoče povečan z izravnavo znotraj besedilnega polja), vendar ker kazalčni tip vsebuje tip objekta na katerega kaže, se lahko izrazi, ki vključujejo kazalce, preverijo glede na tip že med prevajanjem. Kazalčna aritmetika se samodejno skalira z velikostjo podatkovnega tipa na katero se kaže.

Osnovna skladnja za opredelitev kazalca v C je:[57][n]

podatkovni_tip*ime_kazalca;

Na primer:

int*ptr;

To označiptr kot označevalnik objekta naslednjega tipa:

  • kazalec, ki kaže na objekt tipaint

To se običajno navede bolj zgoščeno kot 'ptr je kazalec naint'. Pri tem znak »*« (zvezdica) pomeni unarni ali nomadski operator posrednosti (indirektnosti,indirection operator) ali dereferenčni operator (dereference operator).

Slogov zapisa kazalcev je lahko več. Na primer:[n]

int*ptr;int*ptr;int*ptr;

Običajno se rabi zapis operatorja posrednosti brez presledka (desnostično) pred imenom kazalcaint *ptr;, predvsem zaradi nedvomljivosti pri hkratnih večkratnih opredelitvah:

int*ptr1,*ptr2,a,b;
int*ptr1,ptr2,a,b;

V zadnjem zapisu je kazalec samo spremenljivkaptr1.

Ker C ne opredeljuje implicitne dodelitve za objekte s samodejnim pomnilniškim trajanjem,[58] je treba biti velikokrat previden pri zagotavljanju, da je naslov, na katerega kažeptr, veljaven. Zaradi tega včasih predlagajo, da se kazalcu eksplicitno dodeli vrednostničelnega kazalca (null pointer value), ki je v C tradicionalno določena s standardiziranim makrojemNULL:[59]

int*ptr=NULL;

Sicer v tem primeru kazalec še ne 'kaže nikamor', razen da ima vrednost ničelnega kazalca. Pri tem je npr. izpis 'neobstoječe' vrednosti (ničelnega kazalca), kamor naj bi kazal kazalec v funkcijiprintf s formatom izpisa podatkovnega tipa int%d in formatom izpisa kazalcev%p v redu, izpis 'praznega' naslova, pa ne:

printf("\n%d %p",ptr,ptr);/* program izpiše 0 in npr. (nil)      */printf("\n%p",*ptr);/* program javi napako sklica na       *//* naslov pomnilniškega mesta          */

Vrednost ničelnega kazalca tako eksplicitno ne kaže na nobeno veljavno mesto v pomnilniku. Dereferenciranje njegove vrednosti je nedoločeno, kar velikokrat povzročasegmentacijsko odpoved (segmentation fault) ali popolnosesutje programa:[60]:33

int*ptr=NULL;*ptr=42;/* dereferenciranje vrednosti ničelnega *//* kazalca je nedoločeno                */

Vrednosti ničelnih kazalcev so uporabne pri nakazovanju posebnih primerov, kot so brez »naslednjega« kazalca v končnem vozliščupovezanega seznama, ali kot naznanitev napake iz funkcij, ki vračajo kazalce. V ustreznih kontekstih izvorne kode, kot je prirejanje kazalčne spremenljivke, se lahkokonstanta ničelnega kazalca zapiše kot0, z ali brez eksplicitne opustitve na tip kazalca, ali kot makroNULL, ki je opredeljen v več standardnih zaglavnih datotekah, ali od standarda C23 naprej kot konstantanullptr. V pogojnih zvezah imajo vrednosti ničelnih kazalcev napačno vrednost (false), vse druge vrednosti kazalcev pa pravilno (true).

Kazalci se v C rabijo za več namenov. Z besedilnimiznakovnimi nizi se običajno upravlja s pomočjo kazalcev v polja znakov.Dinamična dodelitev pomnilnika se izvaja s kazalci. Rezultat funkcijemalloc je običajno pretvorjen v podatkovni tip podatkov, ki jih je treba shraniti. Mnogo podatkovnih tipov, kot so na primer povezani seznami alidrevesa, je velikokrat izvedeno kot dinamično dodeljeni objektistruct, ki so med seboj povezani s kazalci. Kazalci na druge kazalce se pogosto uporabljajo v večrazsežnostnih poljih in poljih strukturnih objektov.

Kazalci na funkcije (funkcijski kazalci) so uporabni za prenašanje funkcij kot parametrovfunkcij višjega reda, kot na primerqsort alibsearch, vtabelah prekinitev (dispatch tables), ali kotpovratni klici (callbacks), ki ga izvedejo obdelovalnikidogodkov (event handlers).[48]

Prazni kazalci (void *) kažejo na objekte nedoločenega tipa, in se lahko zaradi tega uporabijo kot »generični« podatkovni kazalci. Ker velikost in tip nakazanih objektov nista znana, se prazni kazalci ne morejo dereferencirati, in tudi kazalčna aritmetika nad njimi ni dovoljena. Enostavno jih je tudi pretvoriti v in iz poljubnega tipa objektnega kazalca. V mnogih zvezah se jih dejansko implicitno pretvori.[48]

Neprevidna raba kazalcev je potencialno nevarna. Ker se njihov tip ne preverja, lahko kazalčna spremenljivka kaže na poljubno mesto v pomnilniku, kar lahko povzroči nezaželene učinke. Čeprav pravilno rabljeni kazalci kažejo na varna mesta, lahko kažejo na nevarna mesta, če se zanje rabi nepravilna kazalčna aritmetika. Objekti na katera kažejo se lahko ponovno dodelijo in uporabijo (obviseli kazalci) (dangling pointers) lahko se uporabijo brez, da bi se jim dodelila vrednost (divji kazalci (wild pointers)), ali pa se jim lahko neposredno dodeli nevarno vrednost s pomočjo opustitve, unije ali prek drugega pokvarjenega kazalca. V splošnem C dopušča upravljanje in pretvarjanje med tipi kazalcev, čeprav običajno prevajalniki preskrbijo možnosti za različne nivoje preverjanja. Nekateri drugi programski jeziki te probleme rešujejo z bolj omejevalnimi tipi sklicev.

Podatkovni tipipolj imajo v C tradicionalno fiksno, statično velikost med prevajanjem. Standard C99 dovoljuje tudi oblikopolj s spremenljivo dolžino. Možno je tudi dodeliti blok pomnilnika (poljubne velikosti) pri izvajanju s pomočjo standardne knjižniške funkcijemalloc (calloc) in ga obravnavati kot polje. Cejevska združitev polj in kazalcev pomeni, da so označena polja in ta dinamično dodeljena simulirana polja dejansko zamenljiva med seboj.

Ker se do polj (v bistvu) vedno dostopa prek kazalcev, se dostopi polj tipičnone preverjajo za vezano velikost polja, čeprav nekateri prevajalniki lahko preskrbijopreverjanje mej kot možnost.[61][62] Zaradi tega so možne prekršitve mej polj in te so kar vsakdanje v neprevidno napisani kodi. Lahko vodijo do različnih neugodnih stranskih pojavov, kot so: nepravilni dostopi do pomnilnika, popačenje podatkov,prekoračitve medpomnilnika in izjeme med izvajanjem. Če je zahtevano preverjanje mej, mora biti izvedeno ročno.

C nima posebnega predpisa za označitev mnogorazsežnih polj, in se raje zanaša na rekurzijo znotraj sistema tipov tako da označuje polja polj, ki učinkovito opravljajo enako stvar. Vrednosti indeksov nastalega »mnogorazsežnega polja« se lahko obravnava kot (linearno) povečevanjeureditve po vrsticah. Mnogorazsežna polja se velikokrat rabijo v numeričnih algoritmih, večinoma iz uporabnelinearne algebra za hranjenje podatkovmatrik. Zgradba cejevskega polja je za to posebno nalogo zelo primerna. Ker se polja večinoma prenašajo kot kazalci, morajo biti, sploh v zgodnjih različicah jezika C, njihove meje fiksne vrednosti ali pa jih je treba izrecno prenesti v poljubni podprogram, ki jih zahteva. Dinamično oblikovana polja polj se ne morejo dostopati s pomočjo dvojnega indeksiranja. To se lahko naredi z dodelitvijo polja z dodatnim »vrstičnim vektorjem« kazalcev k stolpcem.

Poljepolje se na primer lahko označi in uporabi na naslednje načine:

intpolje[5];/* označi 5 sosednjih celih števil     */int*vptr=polje;/* polja se lahko rabijo kot kazalci   */vptr[0]=1;/* kazalci se lahko indeksirajo s      *//* skladnjo polj                       */*(polje+1)=2;/* polja se lahko dereferencirajo s    *//* skladnjo kazalcev                   */*(1+polje)=2;/* kazalčno seštevanje je komutativno  */2[polje]=4;/* operator indeksa je komutativen     */

Standard C99 je uvedel »polja s spremenljivo dolžino« (variable-length array, VLA), ki rešujejo nekatere, vendar ne vse, probleme običajnih cejevskih polj. Naslednji zgled z uporabo sodobnega jezika C (C99 ali novejši) prikazuje dodelitev dvorazsežnega polja nakopico s pomočjo funkcijemalloc in uporabo večrazsežnega indeksiranja polja za dostope (ki lahko uporablja preverjanje meja na mnogih prevajalnikih C):

intfunc(intN,intM){float(*p)[N][M]=malloc(sizeof*p);if(p==0){return-1;}for(inti=0;i<N;i++){for(intj=0;j<M;j++){(*p)[i][j]=i+j;}}print_array(N,M,p);free(p);return1;}

In tukaj je podobna izvedba z uporabo gradnika samodejnega VLA standarda C99:[o]

intfunc(intN,intM){/* Pozor: preveriti je treba, da       *//* N * M * sizeof(float) NE presega    *//* omejitev za samodejne VLA in je     *//* znotraj razpoložljive velikosti     *//* sklada.                             */floatp[N][M];/* Samodejni VLA se hrani na skladu in *//* se spremeni v velikost, ko je       */for(inti=0;i<N;i++){/* funkcija priklicana                 */for(intj=0;j<M;j++){p[i][j]=i+j;}}print_array(N,M,p);/* ni potrebe za funkcijo free(p), saj *//* bo objekt pri izhodu iz funkcije    *//* func() izginil, vključno s          */return1;/* preostankom okvirja sklada          */}

Izmenljivost polj in kazalcev

[uredi |uredi kodo]

Zapis s spuščenimi indeksix[i] (kjerx označuje kazalec) jeskladenjski sladkor za*(x+i).[63] S prednostjo pomnilnikovega znanja o kazalčnem tipu naslov, na katerega kažex + i, ni osnovni naslov (na katerega kažex), povečan zai bitov, ampak je določen kot osnovni naslov, povečan zi pomnoženim z velikostjo elementa, na katerega kažex. Takox[i] označujei+1-ti element polja.

V večini izraznih kontekstov, kjer je večja izjema operandsizeof, se naprej izraz tipa polja samodejno pretvori v kazalec na prvi element polja. To pomeni, da se polje nikoli v celoti ne skopira, ko je imenovan kot parameter funkciji, ampak se prenese le naslov njegovega prvega elementa. Čeprav klici funkcij v C uporabljajo semantikoklicev po vrednosti, so tako polja učinkovito prenesena po sklicu.

Skupna velikost poljax se lahko določi s pomočjo operatorjasizeof na izraz tipa polja. Velikost elementa se lahko določi z operatorjemsizeof na poljubni dereferenciran elementx, kot v izrazun = sizeof *x alin = sizeof x[0], tako, da se število elementov v označenem poljux lahko določi kotsizeof x / sizeof x[0]. Zadnji izraz velja le za imena polj: spremenljivke označene s spuščenimi indeksi (int x[20]). Zaradi semantike C-ja ni mogoče določiti celotne velikosti polj prek kazalcev na polja ali polj tvorjenih z dinamično dodelitvijo (malloc). Tako izrazi, kot jesizeof vptr / sizeof vptr[0] (kjervptr označuje kazalec), ne bodo delovali, saj prevajalnik privzame, da se zahteva velikost kazalca samega.[64][65] Ker parametri imena polja nasizeof niso pretvorjeni v kazalce, ne kažejo takšne nejasnosti. V polja tvorjena z dinamično dodelitvijo pa se dostopa s kazalci in ne kot prave spremenljivke polja, zato imajo enake težave z operatorjemsizeof kot kazalci na polja. Če se v kakšni funkciji potrebuje vrednost velikosti (enorazsežnega) poljavptr, jo je treba vključiti kot njen parameter (npr.velikost). Na primer:

/* ... */{int*vptr=NULL;staticconstintvelikost=10;vptr=(int*)malloc(velikost*sizeof(vptr));funkcija(vptr,velikost);free(vptr);/* ... */}funkcija(int*v,intn)/* funkcija ima (vsaj) dva parametra – */{/* kazalec na polje in njegovo velikost*//* (n)                                 *//* ... */}

Podobno velja za mnogorazsežna polja.

Navkljub tej navidezni enakosti med polji in kazalčnimi spremenljivkami je tako med njimi še vedno razlika. Čeprav se v večini izraznih kontekstih ime polja pretvori v kazalec (na njegov prvi element), kazalec sam ne zajema nobega dela pomnilnika ime polja nil-vrednost in njegov naslov je konstanta, z razliko od kazalčne spremenljivke. Zaradi tega se področje »na katerega kaže polje, ne more spremeniti, in na ime polja je nemogoče prirediti nov naslov. Vsebina polj pa se lahko kopira, na primer s pomočjo funkcijememcpy ali z dostopanjem do posameznih elementov.

Strukture in unije

[uredi |uredi kodo]

Strukturastruct je označitevsestavljenega podatkovnega tipa (alizapisa), ki opredeljuje fizično združen seznam spremenljivk pod enim imenom v bloku pomnilnika, kar omogoča dostop do različnih spremenljivk prek enega samega kazalca ali z označenim imenomstrukture, ki vrne isti naslov. Podatkovni tipstruct lahko vsebuje druge podatkovne tipe, zato se uporablja za zapise mešanega tipa podatkov, kot je vnos imenika trdega diska (dolžina datoteke, ime, pripona, fizični naslov itd.) ali druge zapise mešanega tipa (ime , naslov, telefon, stanje itd.).

Struktura se neposredno sklicuje na sosednji blok fizičnega pomnilnika, ki je običajno razmejen (po velikosti) z mejami dolžine besede. Ustreza funkciji s podobnim imenom, ki je na voljo v nekaterihzbirnikih za procesorje Intel. Ker je vsako polje v strukturi blok neprekinjenega pomnilnika, se od začetka nahaja na določenem fiksnem odmiku.

Ker je vsebina strukture shranjena v neprekinjenem pomnilniku, je treba za pridobitev števila bajtov, potrebnih za shranjevanje določene vrste strukture, uporabiti operatorsizeof, tako kot se lahko uporablja zaprimitive. Poravnava določenih polj v strukturi (glede na mejebesed) je specifična za izvedbo in lahko vključuje oblazinjenje, čeprav sodobni prevajalniki običajno podpirajo ukaz#pragma pack, ki spremeni velikost v bajtih, uporabljenih za poravnavo.[66]

V jezikuC++ je struktura enakarazredu C++, vendar ima drugačno privzeto vidnost: člani razreda so privzeto zasebni, medtem ko so člani strukture privzeto javni.

V C in C++ so neoznačeneunijeunion izražene skoraj tako kot strukture (struct), le da se vsak podatkovni član začne na isti lokaciji v pomnilniku. Podatkovni člani, tako kot v strukturah, niso nujno primitivne vrednosti in so dejansko lahko strukture ali celo druge unije.

Glavna uporaba unije je omogočanje dostopa do skupne lokacije z različnimi podatkovnimi tipi, na primer dostop do vhodnoizhodne strojne opreme, skupna raba bitnih polj in besed, alitipsko sprevračanje (type punning). Unije lahko zagotovijo tudi nizko stopnjopolimorfizma. Vendar ni tipskega preverjanja, zato mora programer zagotoviti, da se v različnih kontekstih dostopa do ustreznih polj. Ustrezno polje spremenljivke unije je običajno določeno s stanjem drugih spremenljivk, po možnosti v obdajajoči strukturi.

En pogost programski idiom, ki ga C uporablja z unijami za izvajanje tega, kar C++ imenujereinterpret_cast, z dodelitvijo enemu polju unije in branjem iz drugega, kot je storjeno v kodi, ki je odvisna od neobdelane predstavitve vrednosti. Praktični primer jemetoda računanja kvadratnih korenov z uporabo reprezentacije IEEE. Vendar to ni varna uporaba unij na splošno.

Strukture in unije imajo enako skladnjo. V C++ so unije načeloma bolj zaradi združljivosti za nazaj s C.[66]

Upravljanje pomnilnika

[uredi |uredi kodo]

Ena od najpomembnejših funkcij programskega jezika je zagotovitev pripomočkov zaupravljanje pomnilnika in objektov, ki so shranjeni v njem. C zagotavlja tri glavne načine dodelitve pomnilnika objektom:[48]

  • statični: prostor za objekt je zagotovljen v dvojiški obliki med prevajanjem.Življenjska doba teh objektov je enaka času, ko je dvojiška datoteka, ki jih vsebuje, naložena v pomnilnik.
  • samodejni: začasni objekti se lahko shranijo nasklad, ta prostor pa se samodejno sprosti in je ponovno uporaben po tem ko se izstopi iz bloka v katerem so objekti označeni.
  • dinamični: bloki pomnilnika poljubne velikosti se lahko zahtevajo med izvajanjem s pomočjo funkcij, kot stamalloc alicalloc, iz dela pomnilnika, ki se imenuje kopica. Ti bloki obstajajo dokler se jih s klicanjem knjižničnih funkcijrealloc alifree ne sprosti za ponovno rabo.

Ti trije pristopi so primerni v različnih razmerah in imajo različne izkupnine. Statična dodelitev pomnilnika ima majhno dodelitveno povprečnino, samodejna dodelitev jo lahko vsebuje nekaj več, dinamična dodelitev pomnilnika pa ima lahko precej večjo povprečnino tako za dodelitev kot za sprostitev. Trajna narava statičnih objektov je uporabna za ohranjanje stanja informacij med klici funkcij. Samodejna dodelitev je preprosta za uporabo, vendar je običajno prostor sklada tipično bolj omejen in prehoden tako od statičnega pomnilnika ali od prostora kopice. Dinamična dodelitev pomnilnika omogoča priročno dodelitev objektov, katerih velikost je znana le med izvajanjem. Večina programov v C s pridom uporablja vse tri načine.

Kjer je možno, sta samodejna in statična dodelitev najpreprostjši, ker pomnilnik upravlja prevajalnik, in programerju ni treba paziti na opravila, ki so potencialno dovzetna za napake ročnega dodeljevanja in sproščanja pomnilnika. Vendar se lahko veliko podatkovnih struktur med izvajanjem spreminja po velikosti, in, ker morajo imeti statične dodelitve (in samodejne dodelitve pred standardom C99) fiksno velikost med prevajanjem, je velikokrat potrebna dinamična dodelitev.[48] Pred standardom C99 so bila polja s spreminjajočo velikostjo običajen primer tega. (Glej članek o funkcijimalloc za primer dinamično dodeljenih polj.) Z razliko od samodejne dodelitve, ki lahko med izvajanjem odpove z nepredvidljivimi posledicami, funkcije dinamične dodelitve vračajo pokazatelj (v obliki vrednosti ničelnega kazalca) kadar zahtevan pomnilnik ne more biti dodeljen. (Statično dodelitev, ki je prevelika, po navadi zaznapovezovalnik alinalagalnik (loader), preden program sploh začne izvajanje.)

Dokler ni posebej označeno, statični objekti vsebujejo vrednosti nič ali ničelnih kazalcev pri izvajanju programa. Samodejnim in dinamičnim dodeljenim objektom se dodeli vrednost le, če je začetna vrednost eksplicitno označena, drugače imajo na začetku nedoločene vrednosti (tipično, katerikolibitni vzorec, ki se nahaja vpomnilniku, in lahko predstavlja tudi nepravilno vrednost za določeni tip). Če program poskuša dostopati do nedodeljene vrednosti, so rezultati nedoločeni. Veliko sodobnih prevajalnikov poskuša zaznati in opozoriti na ta problem, vendar se lahko pojavijo takonapačno pozitivni kot napačno negativni.

Drug problem je, da mora biti dodelitev pomnilnika s kopico sinhronizirana s svojo dejansko rabo v kateremkoli programu da se lahko ponovno uporabi kolikokrat je mogoče. Če na primer vrednost edinega kazalca na pomnilniško dodelitev s kopico uide iz svojega dosega ali se prepiše preko preden je klicana funkcijafree, oziroma se izrecno ponovno dodeli, potem se tisti del pomnilnika ne more obnoviti za kasnejšo ponovno rabo in je dejansko za program izgubljen. Ta pojav je znan kotpuščanje pomnilnika (memory leak). Možno je tudi obratno, da se pomnilnik sprosti, vendar se nanj še vedno sklicuje, kar lahko spet povzroči neprevidljive rezultate. Tipično se bodo simptomi pokazali v delu programa, ki je zelo oddaljen od dejanske napake, kar bo oteževalo sledenje problemu. Takšni problemi so izboljšani v jezikih s samodejnimčiščenjem pomnilnika.

Knjižnice

[uredi |uredi kodo]

Osnovno razširitev jezika C predstavljajoknjižnice. Knjižnica je v C množica funkcij zbrana v eni »arhivski« datoteki. Vsaka knjižnica ima po navadizaglavno datoteko s prototipi funkcij, ki jih vsebuje knjižnica in se lahko rabijo v programu, in označitvami posebnih podatkovnih tipov in makro simbolov znotraj teh funkcij. Da lahko program rabi knjižnico, mora vsebovati njeno zaglavno datoteko, knjižnica pa mora biti povezana s programom, kar v mnogih primerih zahtevaprevajalnikove zastavice (na primer-lm, okrajšano za »poveži z matematično knjižnico« (link the math library)).[48]

Najobičajnejša knjižnica C jestandardna knjižnica jezika C, ki jo navajata standardaISO inANSI C. Standardna knjižnica je del vsake izvedbe C. Izvedbe, ki ciljajo na omejena okolja, kot so na primervgradni sistemi, lahko zagotavljajo le podmnožico standardne knjižnice. Standardna knjižnica C podpira vhodnoizhodni tok, dodelitev pomnilnika, matematične funkcije in količine, znakovne nize in časovne vrednosti. Več ločenih standardnih zaglavnih datotek (na primerstdio.h) določa vmesnike zanje in druge pripomočke standardne knjižnice.

Druge običajne množice funkcij knjižnice C so tiste, ki se rabijo v aplikacijah, posebej prirejenih zaUnix insisteme podobne Unix, še posebej funkcije, ki zagotavljajo vmesnik zajedro. Te funkcije v podrobnosti navajajo standardi, kot staPOSIX inSingle UNIX Specification.

Ker je veliko programov napisanih v C, so na voljo raznolike druge knjižnice. Knjižnice so običajno napisane v C, ker C-jevski prevajalniki tvorijo učinkovitoobjektno kodo. Programerji nato naredijo vmesnike h knjižnici, tako da se lahko njeni podprogrami rabijo v visokonivojskih jezikih, kot sojava,Perl inPython.[48]

Obravnavanje datotek in tokov

[uredi |uredi kodo]

Datotečni vhod in izhod nista del samega jezika C, temveč ju upravljajo knjižnice (kot je standardna knjižnica C) in z njimi povezane zaglavne datoteke (na primerstdio.h). Obravnavanje datotek se na splošno izvaja prek V/I na visoki ravni, ki deluje prektokov (streams). Tok je s tega vidika tok podatkov, ki je neodvisen od naprav, medtem ko je datoteka konkretna naprava. V/I na visoki ravni poteka prek povezave toka z datoteko. V standardni knjižnici C semedpomnilnik (pomnilniško območje ali čakalna vrsta) začasno uporablja za shranjevanje podatkov, preden se pošljejo na končni cilj. To skrajša čas čakanja na počasnejše naprave, na primertrdi disk alinegibljivi disk (SSD). Vhodnoizhodne funkcije nizke ravni niso del standardne knjižnice C, ampak so na splošno del »golega« programiranja (programiranja, ki je neodvisno od katerega koli operacijskega sistema, kot je večinavdelanega programiranja). Z nekaj izjemami izvedbe vključujejo nizkonivojski V/I.

Jezikovna orodja

[uredi |uredi kodo]

Za pomoč programerjem v C pri iskanju in popravljanju stavkov z neopredeljenim obnašanjem ali z možnimi napačnimi izrazi so razvili večorodij z večjo strogostjo, ki jo zagotavljajo prevajalniki. Med prvimi takšnimi orodji je bilo orodjelint. Njegov razvoj je vodil do nastanka mnogih drugih.

Avtomatizirano preverjanje izvorne kode in pregledovanje je koristno v vsakem jeziku. Za C obstaja več takšnih orodij, kot na primer lint. Običajna praksa je, da se z orodjem lint odkrije vprašljiva koda, ko je program prvič napisan. Ko program preveri lint, se ga s prevajalnikom za C prevede. Poleg tega lahko mnogi prevejalniki opcijsko opozorijo o skladenjsko pravilnih konstruktih, ki bodo verjetno dejansko napake.MISRA C je lastniška množica navodil v izogib takšni vprašljivi kodi, razvita za vgradne sisteme.[67]

Obstajajo tudi prevajalniki, knjižnice in mehanizmi na nivoju operacijskih sistemov za izvajanje procesov, ki niso standardni deli jezika C, kot na primer:preverjanje mej polj, odkrivanjeprekoračitev medpomnilnika,serializacija, sledenjedinamičnemu pomnilniku in samodejnočiščenje pomnilnika.

Orodja, kot sopomnilniški razhroščevalniki:Purify,Valgrind,Insure++,dmalloc,Electric Fence,Inspector,libcwd,Memwatch,MTuner,Oracle Developer Studio,Splint,TotalView aliWinDbg skupaj s povezovanjem knjižnic, ki vsebujejo posebne različice funkcijdinamičnih dodelitev pomnilnika, lahko pomagajo odkrivati napake v rabi pomnilnika pri izvajanju.

Uporabe

[uredi |uredi kodo]

Sistemsko programiranje

[uredi |uredi kodo]
Nekatere aplikacije, jeziki, pogoni, knjižnice, vmesniki, kompleti orodij, spletni strežniki razviti iz ali v programskem jeziku C:Linuxovo jedro,AVR Libc,GCC,Python,PostgreSQL,SQLite,OpenGL,GTK,Apache,nginx

C se pogosto uporablja zasistemsko programiranje pri izvajanju operacijskih sistemov in vgrajenih sistemskih aplikacij.[68] To je iz več razlogov:

  • C omogoča dostop do platformske strojne opreme in pomnilnika s kazalci intipsko sprevračanje, tako da je mogoče sistemsko specifične funkcije (npr.nadzornostatusne registre,vhodnoizhodne registre) konfigurirati in uporabljati s kodo, napisano v C to popoln nadzor nad platformo, na kateri se izvaja.
  • koda, ustvarjena po prevajanju, ne zahteva velikosistemskih gradnikov in jo je mogoče priklicati iz neke zagonske kode na enostaven način preprosto jo je izvesti.
  • stavki in izrazi v C se običajno dobro preslikajo v zaporedja navodil za ciljni procesor in zato je sistemska poraba v časuizvajanja nizka izvajanje je hitro.
  • s svojim bogatim naborom operatorjev lahko C uporablja mnoge funkcije ciljnih procesorjev. Kjer ima določena CPE bolj ezoterična navodila, je mogoče sestaviti jezikovno različico z mordaintrinzičnimi funkcijami za izkoriščanje teh navodil uporablja lahko praktično vse funkcije ciljne CPE.
  • C omogoča preprosto prekrivanje struktur na bloke dvojiških podatkov, kar omogoča razumevanje podatkov, navigacijo in spreminjanje lahko zapiše podatkovne strukture, celo datotečne sisteme.
  • C podpira bogat nabor operatorjev, vključno z bitno manipulacijo, za celoštevilsko aritmetiko in logiko ter morda različne velikosti števil s plavajočo vejico lahko učinkovito obdela ustrezno strukturirane podatke.
  • C je dokaj majhen jezik z le peščico stavkov in brez preveč gradnikov, ki ustvarjajo obsežno ciljno kodo je razumljiv.
  • C ima neposreden nadzor nad dodelitvijo in ponovno dodelitvijo (sprostitvijo) pomnilnika, kar zagotavlja razumno učinkovitost in predvidljiv časovni razpored za operacije obravnavanja pomnilnika, brez kakršnih koli skrbi za občasne dogodke zbiranja smeti obzaustavitvi sveta ima predvidljivo delovanje.
  • C dovoljuje uporabo in izvajanje različnih shemdodelitve pomnilnika, vključno s tipičnima funkcijamamalloc infree, bolj izpopolnjen mehanizem zarenami ali različico za jedro operacijskega sistema, ki lahko ustrezaneposrednemu dostopu do pomnilnika (DMA), uporabi znotrajobdelovalnikov prekinitev ali integrirano s sistemomnavideznega pomnilnika.
  • odvisno od povezovalnika in okolja lahko koda C kliče tudi knjižnice, napisane vzbirnem jeziku, in se lahko kliče iz zbirnega jezika dobro deluje z drugo nizkopnivojsko kodo.
  • C in njegovidogovori o klicanju ter povezovalnikove strukture se običajno uporabljajo v povezavi z drugimi visokonivojskimi jeziki, pri čemer so podprti klici v C in iz C dobro deluje z drugo visokonivojsko kodo.
  • C ima zelo zrel in širok ekosistem, vključno s knjižnicami, ogrodji, odprtokodnimi prevajalniki, razhroščevalniki in pripomočki, in je de facto standard. Verjetno gonilniki že obstajajo v C ali pa obstaja podobna arhitektura CPE kot zaledje prevajalnika C, zato je manj spodbude za izbiro drugega jezika.

Računsko zahtevne knjižnice

[uredi |uredi kodo]

C programerjem omogoča ustvarjanje učinkovitih izvedb algoritmov in podatkovnih struktur, ker je plast abstrakcije iz strojne opreme tanka, njeni stroški pa nizki, kar je pomembno merilo za računalniško intenzivne programe. Na primer,GNU Multiple Precision Arithmetic Library (GMP),GNU Scientific Library (GSL),Mathematica inMATLAB so v celoti ali delno napisani v C. Mnogi jeziki podpirajo klicanje knjižniških funkcij v C. OgrodjeNumPy, ki temelji naPythonu, na primer uporablja C za vidike visoke zmogljivosti in interakcije s strojno opremo.

Računalniške igre so pogosto zgrajene iz kombinacije jezikov. C se je zelo izkazal, zlasti za tiste igre, ki poskušajo doseči najboljšo zmogljivost računalniških platform. Med te igre spada igraDoom iz leta 1993.[69]

C kot vmesni jezik

[uredi |uredi kodo]

C se včasih uporablja kotvmesni jezik pri izvedbah drugih jezikov. Ta pristop se lahko uporablja zaradi prenosljivosti ali udobja. Z uporabo C kot vmesnega jezika dodatni strojnospecifični generatorji kode niso potrebni. C ima nekaj gradnikov, kot so predprocesorski ukazi številk vrstic in neobvezne odvečne vejice na koncu seznamov dodeljevalnikov, ki podpirajo prevajanje ustvarjene kode. Vendar pa so nekatere pomanjkljivosti C-ja spodbudile razvoj drugih jezikov, kitemeljijo na C-ju in so posebej zasnovani za uporabo kot vmesni jeziki, kot jeC--. Poleg tega imata sodobna glavna prevajalnikaGCC inLLVMvmesno reprezentacijo, ki ni C, in ti prevajalniki podpirajo čelne dele za mnoge jezike, vključno s C.

Razvijanje drugih jezikov

[uredi |uredi kodo]

Posledica široke razpoložljivosti in učinkovitosti jezika C je, da so prevajalniki, knjižnice intolmači drugih programskih jezikov pogosto izvedeni v C.[70] Na primer,referenčne izvedbe Pythona,[71]Perla,[72]Rubyja[73] inPHP[74] so napisane v C.

Spletni razvoj

[uredi |uredi kodo]

V preteklosti se je C včasih uporabljal zaspletni razvoj z uporaboskupnega prehodnega vmesnika (CGI) kot »prehoda« za informacije med spletno aplikacijo,spletnim strežnikom inspletnim brskalnikom.[75] C je bil morda izbran namesto tolmačenih jezikov zaradi njegove hitrosti, stabilnosti in skoraj univerzalne dostopnosti.[76] Ni več običajna praksa, da se spletni razvoj izvaja v C,[77] zanj so priljubljeni mnogi drugi jeziki. Aplikacije, kjer se spletni razvoj na osnovi C nadaljuje, vključujejo konfiguracijske straniHTTP nausmerjevalnikih, napravahinterneta stvari (IoT) in podobno, čeprav imajo tudi tukaj nekateri projekti dele v višjenivojskih jezikih, npr. uporaba jezikaLua znotraj odkprtokodnega projektaOpenWRT.

Razvoj spletnih strežnikov

[uredi |uredi kodo]

Dva najbolj priljubljenaspletna strežnika,strežnik HTTP Apache innginx, sta oba napisana v C. Ti spletni strežniki komunicirajo z operacijskim sistemom, poslušajo vrata TCP za zahteve HTTP in nato strežejo statično spletno vsebino ali povzročijo izvajanje obdelave drugih jezikov za 'upodabljanje' vsebine, kot je PHP, ki je sam primarno napisan v C. C-jev surovi pristop omogoča konstrukcijo teh visoko zmogljivih programskih sistemov.

Aplikacije za končne uporabnike

[uredi |uredi kodo]

C se pogosto uporablja tudi za izvajanje aplikacij zakončne uporabnike.[7] Vendar pa je takšne aplikacije mogoče napisati tudi v novejših višjenivojskih jezikih.

Omejitve

[uredi |uredi kodo]

moč zbirnega jezika in priročnost ...
zbirnega jezika

Dennis Ritchie[78]

Čeprav je bil C priljubljen, vpliven in izjemno uspešen, ima naslednje slabosti:

Za nekatere namene so bili sprejeti omejeni slogi C-ja, na primerMISRA C aliCERT C, da bi zmanjšali možnosthroščev.Podatkovne zbirke, kot jeCWE, poskušajo prešteti načine, na katere ima C itd. ranljivosti, skupaj s priporočili za ublažitev.

Obstajajoorodja, ki lahko ublažijo nekatere pomanjkljivosti. Sodobni prevajalniki C vključujejo preverjanja, ki lahko ustvarijo opozorila za pomoč pri prepoznavanju mnogih morebitnih hroščev.

Nekatere od teh pomanjkljivosti so spodbudile izdelavo drugih jezikov.

Sorodni jeziki

[uredi |uredi kodo]
Primerjava jezikov C inC++ s kodo programaPozdravljen, svet
Grafindeksa TIOBE kaže primerjavo med priljubljenostjo različnih programskih jezikov[85]

Razvoj jezika C je zelo vplival nadruge programske jezike, še posebej na C++, ki se je razvil kot razširitev C-ja.[86] Mnogo kasnejših jezikov si je neposredno ali posredno sposodilo določene gradnike C-ja, na primer:C#, UnixovaC shell,D,Go,java,JavaScript (vključno sprevajalniki od vira do vira),JS++,julia,Limbo,LPC,nim,Objective-C,Perl,PHP,pike,processing,Python,Ruby,Rust,seed7,Swift,Vala,Verilog,SystemVerilog (strojni opisni (HDL) instrojni preverljivostni jezik (HVL))[5] inzig. Najprodornejši vpliv je bilskladenjski. Ti jeziki so dobili mnogo svojihnadzornih struktur in drugih osnovnih gradnikov od C-ja. Večina od njih, kjer je Python največja izjema, je tudi skladenjsko zelo podobnih C-ju v splošnem in so usmerjeni na združevanje prepoznavnih izrazov in stavkovskladnje jezika C z osnovo sistemov tipa,podatkovnih modelov in semantiko, ki je lahko popolnoma drugačna. Skladnja pri teh jezikih včasih vključuje tudi enakovredne preproste nadzorne strukture.[87][p][88][89][q]

Java še zdaleč ni prvi poskus prenosljivosti. Ne pozabimo, da je bila prvotna motivacija za jezik C v zgodnjih 1970-ih ustvariti prenosni računalniški jezik. Teorija je bila, da bi lahko programer vzel program, napisan v C, in ga lahko pognal na različnih računalnikih preprosto s ponovnim prevajanjem izvorne kode. In v ta namen je bil C izjemno uspešen. Imam veliko programov, ki jih je mogoče prevesti in izvajati v sistemu Windows, na delovnih postajah Unix, ki temeljijo na Intelu, in celo na strežnikih Sun Ultra-SPARC. Ena od prednosti jave pred C-jem naj bi bila ta, da bi se programi lahko selili iz računalnika v računalnik, ne da bi jih bilo treba znova prevesti. Čeprav prenosljivost deluje večino časa, java ni in nikoli ne bo zamenjava za C ali njegovega naslednika C++.

Obstaja več tolmačev C ali skoraj C, vključno sCh inCINT, ki jih je mogoče uporabiti tudi za skriptiranje.

Ko soobjektno usmerjeni programski jeziki postali priljubljeni, sta bila C++ in Objective-C dve različni razširitvi jezika C, ki sta zagotavljali objektno usmerjene zmogljivosti. Oba jezika sta bila prvotno izvedena kotprevajalnika od vira do vira izvorna koda je bila prevedena v C in nato prevedena s prevajalnikom C.[91]

Programski jezikC++ (prvotno imenovan »C zrazredi«) je zasnovalBjarne Stroustrup kot pristop k zagotavljanju objektno usmerjene funkcionalnosti s skladnjo, podobno C-ju.[92] C++ dodaja večjo moč tipizacije, doseg in druga orodja, uporabna pri objektno usmerjenem programiranju, ter omogočagenerično programiranje prek predlog (templates). C++ je trenutno skoraj supermnožica C in podpira večino C, z nekajizjemami.[92]

Objective-C je bil prvotno zelo »tanek« sloj na vrhu C-ja in ostaja strogasupermnožica C-ja, ki dovoljuje objektno usmerjeno programiranje z uporabo hibridne paradigme dinamične/statične tipizacije.[93][94][95] Objective-C izpeljuje svojo skladnjo iz C-ja inSmalltalka: skladnja, ki vključuje predprocesiranje, izraze, označitve funkcij in klice funkcij, je podedovana iz C-ja, skladnja za objektno usmerjene funkcije pa je bila prvotno vzeta iz Smalltalka.

Poleg C++ in Objective-C soCh,Cilk inUnified Parallel C (UPC) skoraj supermnožice C-ja.

C se rabi tudi kotposredni jezik za druge jezike[96] ter za ustvarjanjestandardnih knjižnic inizvajalnih sistemov zavišjenivojske jezike, kot je npr.CPython.[97]

Glej tudi

[uredi |uredi kodo]

Opombe

[uredi |uredi kodo]
  1. Thompson je leta 1972 na kratko poskušal izdelati sistem, kodiran v zgodnji različici C (pred strukturami), vendar je zamisel opustil ( Ritchie (1993)).
  2. Izvedli so več poskusov, da bi bilo v C postopanje zznakovnimi nizi manj nagnjeno k napakam. Ena strategija je dodajanje varnejših in uporabnejših funkcij, kot stastrdup instrlcpy, in izogibanje nevarnim funkcijam, kot je npr.gets. Druga je dodajanje objektno usmerjene ovojnice okrog C-jevskih nizov, tako da so možna le varna klicanja.
  3. Z razliko od C-ja imata npr.Fortran inBASIC omejeni model, ki ne vsebuje kazalcev. Vpaskalu so kazalci dinamični objekti, sam jezik pa ne dovoljuje kazalčne aritmetike.
  4. Izvirna vzorčna koda se bo prevedla v večini sodobnih prevajalnikov, ki niso v načinu stroge standardne skladnosti, vendar ni v celoti v skladu z zahtevami C89 ali C99. C99 pravzaprav zahteva, da se ustvari diagnostično sporočilo.
  5. Funkcijamain ima pravzaprav dva argumenta,int argc inchar *argv[], ki ju je mogoče uporabiti za obdelavoargumentov ukazne vrstice. Standard ISO C (§ 5.1.2.2.1) zahteva veljavnost obeh oblik funkcijemain, brez parametrov:int main() oziroma:int main(void), ali z dvema parametroma:int main(int argc, char *argv[]), kar je izjema le za to funkcijo.
  6. Če se navede funkcijamain samo s prvim parametrom:
    intmain(intargc){/* ... */}
    bo prevajalnik javil opozorilo, če pa se navede samo z drugim parametrom:
    intmain(char*argv[]){/* ... */}
    bo javil napako, ker mora sicer funkcijamain biti brez parametrov ali imeti strogo dva parametra, prvi parameter pa mora biti tipaint.
  7. V nekaterih operacijskih sistemih, še posebej v starejših različicahUnixa, ima lahko funkcijamain tri parametre v obliki:
    intmain(intargc,char*argv[],char*envp[]){/* ... */}
    kjer je tretji parameter kazalec na vektor predvsem imen spremenljivk okolja. Tretji parameterenvp v funkcijimain pa ni v skladu s standardomPOSIX in se podatki o obstoječih spremenljivkah okolja pridobivajo z drugimi funkcijami, na primergetenv. Prevajalnikgcc zaLinux na primer to možnost podpira.
  8. Argumentoma funkcijemain se lahko dodatno določi konstantnost:
    intmain(constintargc,constchar**argv){/* ... */}intmain(constintargc,constchar*const*argv){/* ... */}
    To je priporočljivo, saj je možno zapisat na primer:
    strcpy(argv[0],"brezveze");
    kar želi spremeniti vrednost prvega znakovnega niza drugega argumenta, označenega kot konstantnega (./ime_programa).
  9. Pred standardom C99 je bil na koncu funkcijemain zahtevan eksplicitni ukazreturn 0;.
  10. 12345Najmanjši obsegi(2n11){\displaystyle -\left(2^{n-1}-1\right)\!\,} do+2n11{\displaystyle +2^{n-1}-1\!\,} (na primer [−127, +127]) izhajajo iz različnih predstavitev celih števil, ki jih je dovolil standard (eniški komplement,predznačna velikost,dvojiški komplement).(GlejISO/IEC 9899:1999 specification, TC3(PDF) (v angleščini), str. 22, § 5.2.4.2.1Sizes of integer types <limits.h>) Vendar pa večina platform uporablja dvojiški komplement, kar za te implementacije implicira obseg v obliki2m1{\displaystyle -2^{m-1}\!\,} do+2m11{\displaystyle +2^{m-1}-1\!\,} zamn{\displaystyle m\geq n}, na primer [−128, +127] (SCHAR_MIN = −128 inSCHAR_MAX = +127) za 8-bitnisigned char. Od standarda C23 naprej je edina dovoljena predstavitev dvojiški komplement, zato se vrednosti gibljejo od2n1{\displaystyle -2^{n-1}\!\,} do+2n11{\displaystyle +2^{n-1}-1\!\,}.(GlejISO/IEC 9899:2023 specification draft(PDF) (v angleščini), str. 41, § 6.2.6Representations of types)
  11. Samodejno razglašen nadouble v funkcijiprintf().
  12. %lf za funkcijoscanf().
  13. 12Velike črke se v izpisu razlikujejo od malih. Določilniki za velike črke ustvarijo vrednosti v velikih črkah, za male črke pa v malih (%A, %E, %F, %G ustvarijo vrednosti, kot so INF, NAN in E (eksponent) v velikih črkah).
  14. 12Mnogi dereferenčni operator* pišejo levostično s podatkovnim tipom in ne z imenom kazalca, pa redkeje tudi nestično od obeh:
    podatkovni_tip*ime_kazalca;podatkovni_tip*ime_kazalca;
  15. Koda za funkcijoprint_array (ni prikazana) se tudi rahlo razlikuje.
  16. Če se pozna programski jezik C, se pozna ukazfor. Ukaz for v jezikuPerl je skladenjsko enakovreden ukazu for v C-ju.
  17. Brezkazalcev bi C izgledal skoraj enako kotPHP

Sklici

[uredi |uredi kodo]
  1. The Development of the C Language
  2. ISO/IEC JTC1/SC22/WG14 (5. april 2023),C - Project status and milestones (v angleščini), pridobljeno 9. avgusta 2023
  3. »N3221 – Editor's Report, Post January 2024 Strasbourg France Meeting«,ISO/IEC JTC1/SC22/WG14 (v angleščini), Open Standards, 21. februar 2024, pridobljeno 24. maja 2024
  4. http://cm.bell-labs.com/cm/cs/who/dmr/chist.html
  5. 12Verilog HDL (and C)(PDF) (v angleščini), The Research School of Computer Science at the Australian National University, 3. junij 2010, arhivirano izprvotnega spletišča(PDF) dne 6. novembra 2013, pridobljeno 19. avgusta 2013,1980s: ; Verilog prvič predstavljen ; na Verilog je vplival programski jezik C
  6. 12Lawlis (1997).
  7. 12Munoz (2025).
  8. »C Language Drops to Lowest Popularity Rating«,developer.com (v ameriški angleščini), 9. avgust 2016, arhivirano izprvotnega spletišča dne 22. avgusta 2022, pridobljeno 1. avgusta 2022
  9. Stewart (2000a).
  10. 123456789Ritchie (1993).
  11. Giannini; Code Fighter, Inc.; Univerza Columbia (2004), str. 164.
  12. 12Programming Language Popularity (v angleščini), 2009, arhivirano izprvotnega spletišča dne 16. januarja 2009, pridobljeno 16. januarja 2009
  13. 12TIOBE Programming Community Index (v angleščini), 2009, arhivirano izprvotnega spletišča dne 2. julija 2013, pridobljeno 6. maja 2009
  14. Ward (1983).
  15. Prinz; Crawford (2005), str. 3.
  16. 12»WG14-N3132 : Revised C23 Schedule«(PDF),open-std.org (v angleščini), 4. junij 2023,arhivirano(PDF) iz spletišča dne 9. junija 2023
  17. TIOBE Index for September 2024 (v angleščini),arhivirano iz spletišča dne 18. septembra 2024, pridobljeno 20. septembra 2024
  18. Johnson; Kernighan (1983), str. 52.
  19. 12»History of C«,en.cppreference.com (v angleščini), 19. avgust 2014,arhivirano iz spletišča dne 29. maja 2018, pridobljeno 10. novembra 2014
  20. 12Stewart (2000b).
  21. Van der Linden (1994).
  22. Ritchie (1979).
  23. Ritchie, Dennis,BCPL to B to C (v angleščini),arhivirano iz spletišča dne 12. decembra 2019, pridobljeno 10. septembra 2019
  24. 12345Jensen (2020).
  25. 12Johnson; Ritchie (1978).
  26. McIlroy (1987).
  27. Stallings (2012), str. 91.
  28. A Brief History of C (v angleščini)
  29. 123Kernighan; Ritchie (1978).
  30. »C manual pages«,FreeBSD Miscellaneous Information Manual (v angleščini) (FreeBSD 13.0 izd.), 30. maj 2011,arhivirano iz spletišča dne 21. januarja 2021, pridobljeno 15. januarja 2021Arhivirano 2021-01-21 naWayback Machine.
  31. 1234Kernighan; Ritchie (1988).
  32. Stroustrup (2002).
  33. Rationale for American National Standard for Information Systems – Programming Language – C (v angleščini), arhivirano izprvotnega spletišča dne 17. julija 2024, pridobljeno 17. julija 2024
  34. C Integrity (v angleščini),Mednarodna organizacija za standardizacijo, 30. marec 1995,arhivirano iz spletišča dne 25. julija 2018, pridobljeno 24. julija 2018
  35. »JTC1/SC22/WG14 – C«,Domača stran (v angleščini), ISO/IEC,arhivirano iz spletišča dne 12. februarja 2018, pridobljeno 2. junija 2011
  36. 12Lesser known C features (v angleščini), pridobljeno 30. decembra 2014
  37. Binstock (2011).
  38. »WG14-N3220 : Working Draft, C2y«(PDF),open-std.org (v angleščini), 21. februar 2024,arhivirano(PDF) iz spletišča dne 26. februarja 2024
  39. »TR 18037: Embedded C«(PDF),open-std.org (v angleščini), ISO / IEC, 4. maj 2006,arhivirano(PDF) iz spletišča dne 25. februarja 2021, pridobljeno 26. julija 2011
  40. Harbison; Steele (2002).
  41. 12Kelley; Pohl (1984), str. 61.
  42. WG14 N1570 Committee Draft — April 12, 2011(PDF) (v angleščini), pridobljeno 13. oktobra 2014
  43. 12»C Language Reference«(PDF),www.openwatcom.org (v angleščini), arhivirano izprvotnega spletišča(PDF) dne 13. maja 2011, pridobljeno 31. decembra 2010
  44. 10 Common Programming Mistakes in C++ (v angleščini), Cs.ucr.edu, pridobljeno 26. junija 2009
  45. Schultz (2004), str. 20.
  46. 12»The form of a C program«,The GNU C Programming Tutorial (v angleščini), pridobljeno 10. oktobra 2014
  47. WG14 N1256 Committee Draft — September 7, 2007 (ISO/IEC 9899:TC3(PDF) (v angleščini), pridobljeno 13. oktobra 2014 Str. 12, klavzula 1, § 5.1.2.2.1Program startup.
  48. 12345678Klemens (2014).
  49. Larson (1996b).
  50. Feuer; Gehani (1982).
  51. 12345678910ISO/IEC 9899:1999 specification, TC3(PDF) (v angleščini), str. 22, § 5.2.4.2.1Sizes of integer types <limits.h>
  52. WG14 N1256.... Str. 37, klavzula 3, § 6.2.6Representations of types — §6.2.6.1 General.
  53. ISO/IEC 9899:1999 specification, TC3(PDF) (v angleščini), str. 37, § 6.2.6.1Representations of types – General
  54. 1234WG14 N1256.... Str. 22, klavzula 1, § 5.2.4.2.1Sizes of integer types<limits.h>.
  55. 123456ISO/IEC 9899:1999 specification, TC3(PDF) (v angleščini), str. 56, § 6.4.4.1Integer constants
  56. 64-Bit Programming Models: Why LP64? (v angleščini), The Open Group, 1997, pridobljeno 9. novembra 2011
  57. WG14 N1256.... Str. 114, klavzula 1, § 6.7.5Declarators.
  58. WG14 N1256.... Str. 126, klavzula 10, § 6.7.8Initialization.
  59. WG14 N1256.... Str. 254, klavzula 3, § 7.17Common definitions<stddef.h>: »NULL..., ki se razširi na izvedbeno določeno kazalčno konstanto...«.
  60. Hall (2025).
  61. gcc ima za ta namen na primer makro _FORTIFY_SOURCE.Security Features: Compile Time Buffer Checks (FORTIFY_SOURCE) (v angleščini), fedoraproject.org,arhivirano iz spletišča dne 7. januarja 2007, pridobljeno 5. avgusta 2012
  62. Aimsiriwong (2016).
  63. Raymond (1996), str. 432.
  64. Summit (1995b),Question 6.23.
  65. Summit (1995b),Question 7.28.
  66. 12»Struct memory layout in C«,Stack Overflow (v angleščini), 1. maj 2010
  67. »Man Page for lint (freebsd Section 1)«,unix.com (v angleščini), 24. maj 2001, pridobljeno 15. julija 2014[mrtva povezava]
  68. Dale; Weems (2014).
  69. »Development of Doom«,DoomWiki.org (v angleščini), 2. marec 2025, pridobljeno 2. marca 2025
  70. »C - the mother of all languages«,ICT Academy at IITK (v ameriški angleščini), 13. november 2018,arhivirano iz spletišča dne 31. maja 2021, pridobljeno 11. oktobra 2022
  71. »1. Extending Python with C or C++ — Python 3.10.7 documentation«,docs.python.org (v angleščini),arhivirano iz spletišča dne 5. novembra 2012, pridobljeno 11. oktobra 2022
  72. »An overview of the Perl 5 engine | Opensource.com«,opensource.com (v angleščini),arhivirano iz spletišča dne 26. maja 2022, pridobljeno 11. oktobra 2022
  73. »To Ruby From C and C++«,www.ruby-lang.org (v angleščini),arhivirano iz spletišča dne 12. avgusta 2013, pridobljeno 11. oktobra 2022
  74. »What is PHP? How to Write Your First PHP Program«,freeCodeCamp.org (v angleščini), 3. avgust 2022,arhivirano iz spletišča dne 4. avgusta 2022, pridobljeno 11. oktobra 2022
  75. Kim (1995).
  76. Dowling (2005).
  77. Perkins (2013).
  78. Metz (2011).
  79. Internet Security Research Group,»What is memory safety and why does it matter?«,Prossimo (v angleščini), pridobljeno 3. marca 2025
  80. corob-msft (2022).
  81. »Pragmas (The C Preprocessor)«,gcc.gnu.org (v angleščini),arhivirano iz spletišča dne 17. junija 2002, pridobljeno 24. septembra 2022
  82. »Pragmas«,Intel (v angleščini),arhivirano iz spletišča dne 10. aprila 2022, pridobljeno 10. aprila 2022
  83. »In praise of the C preprocessor«,apenwarr.ca (v angleščini), pridobljeno 9. julija 2023
  84. Roberts (1989).
  85. McMillan (2013).
  86. O'Regan (2015).
  87. More Control Structures (v angleščini)
  88. Simpson (2013).
  89. Learn C (v angleščini), arhivirano izprvotnega spletišča dne 13. septembra 2015
  90. Garfinkel (2001).
  91. Rauchwerger (2004).
  92. 12Stroustrup (1993).
  93. Write Objective-C Code (v angleščini), apple.com, 23. april 2013, pridobljeno 22. decembra 2013
  94. Dawkins (2006).
  95. Lee (2013).
  96. »How EiffelStudio Compiles«,docs.eiffel.com (v angleščini), pridobljeno 2. februarja 2015
  97. »Extending Python with C or C++«,docs.python.org (v angleščini), pridobljeno 2. februarja 2015

Viri

[uredi |uredi kodo]

Nadaljnje branje

[uredi |uredi kodo]

Zunanje povezave

[uredi |uredi kodo]
Wikimedijina zbirka ponuja več predstavnostnega gradiva o temi:Programski jezik C.

Spletni prevajalniki

[uredi |uredi kodo]
url
 
barvanje
skladnje
različni
urejevalniki
preverjanje
prevoda
izvajanje
kode
podprti
jeziki
izhod vzbirnem
jeziku
prevajalnik(i)
 
opombe
 
codepad.orgDaDaNeDaC,C++, ...Ne(angleško)
godbolt.orgDaNeDaNeC, C++Dagcc, clang(angleško)
ideone.comDaNeDaDaC, C++Negcc, clang(angleško)
repl.itDaNeDaDaC, C++,C#, ...Negcc(angleško)
rextester.comDaDaDaC, C++, C#, ...Negcc, clang, vs C(angleško)
stacked-crooked.comDaNeDaDaC, C++Negcc, g++(angleško)
comeaucomputing.comArhivirano 2016-04-16 naWayback Machine.C, C++[mrtva povezava]
compilr.comArhivirano 2016-03-16 naWayback Machine.[mrtva povezava]
delorie.com[mrtva povezava]
melpon.orgArhivirano 2016-04-11 naWayback Machine.DaDaDaC, C++,C#, ...Negcc, clang[mrtva povezava]
Pridobljeno iz »https://sl.wikipedia.org/w/index.php?title=Programski_jezik_C&oldid=6553807«
Kategorije:
Skrite kategorije:

[8]ページ先頭

©2009-2026 Movatter.jp