C (programmeringsspråk)

**C** er et imperativt programmeringsspråk som støtter strukturert programmering. Med dette språket er det mulig å uttrykke seg svært maskinnært til høynivåspråk å være. Til forskjell fra lavnivåspråkene kan C-kode kompileres for de fleste maskiner. Siden en både kan uttrykke seg maskinnært og samtidig enkelt flytte programmer mellom ulike maskiner, kan en si at C inntar et mellomnivå mellom høynivåspråk og lavnivåspråk, som er årsaken til at C av og til kalles et «portabelt assemblerspråk».

Språket ble utviklet fra 1969 til 1973 av Dennis Ritchie (1941–2011), en amerikansk ingeniør ved AT&T Bell Laboratories. Språket ble utviklet i forbindelse med implementasjonen av operativsystemet UNIX, og er så anvendelig at det brukes til de fleste oppgaver. Mange andre språk har en syntaks som ligner på C, slik som Perl og Java, men oppbyggingen av disse språkene er annerledes. Direkte etterfølgere av C er det objektorienterte C++ og senere også Objective-C.

## Historie

### Bakgrunn
Programmeringsspråket C ble opprinnelig utviklet av Dennis Ritchie ved AT&T Bell Laboratories fra 1969 til 1973. Den mest kreative perioden var i 1972. Språket ble kalt «C», fordi det var avledet av det tidligere programmeringsspråket B, som ble utviklet av Ken Thompson (f. 1943) i 1969. Språket «B» var igjen en forenklet versjon av programmeringsspråket BCPL, som ble utviklet av Martin Richards (f. 1946) i 1966.

Opprinnelsen til C henger nøye sammen med utviklingen av operativsystemet UNIX. UNIX ble utviklet på minidatamaskinen PDP-7 av Ritchie og Thompson i 1969. UNIX var skrevet i assemblerspråk, og da Ritchie og Thomson i 1970 besluttet seg for å portere operativsystemet til minidatamaskinen PDP-11, oppdaget de raskt behovet for et portabelt språk. Programmeringsspråket B ble tatt i bruk på PDP-7 og PDP-11, men utnyttet ikke alle egenskapene til PDP-11, deriblant adressering av *[[byte]]s*.

De tre første versjonene av forsknings-Unix for PDP-11 var også skrevet i assemblerspråk; den første C-kompilatoren ble lansert sammen med versjon 2 den 12. juni 1972. I november 1973 var det meste av operativsystemkjernen til versjon 4 av forsknings-Unix omskrevet i C. Dette var det tredje operativsystemet som ble implementert i et annet språk enn assemblerspråk. Operativsystemet Multics ble skrevet i PL/I fra 1964 til 1969. Operativsystemet *[[Master Control Program]]* for stormaskinen Burroughs B5000 ble skrevet i Algol 60 i 1961.

### K&R C

I 1978 publiserte Brian Kernighan og Dennis Ritchie boken *The C Programming Language*. Kernighan var den første som laget et opplæringskurs i C. Han hadde også jobbet ved AT&T Bell Laboratories, og var den som oppfant navnet UNIX. Boken tjente i mange år som språkets informative spesifikasjon. Den beskriver den opprinnelige syntaksen til C, som vanligvis er blitt referert til som *K&R C* og *Kernighan & Ritchie C*. Andre utgave av boken fra 1988 dekker standarden ANSI C. Boken er oversatt til 27 språk og utkom på norsk i 1989 med tittelen *[[Programmeringsspråket C (bok)|Programmeringsspråket C]]*.

Etter at ANSI C standarden ble godkjent av ANSI i 1989, fortsatte K&R C å være «minste fellesnevner» i mange år. C-programmerere fortsatte i mange tilfeller å benytte K&R C for å oppnå maksimal portabilitet. Mange eldre C-kompilatorer var fortsatt i bruk, og K&R C-koden var også lovlig i den standardiserte utgaven.

K&R C introduserte fire nye elementer:
* standard I/O bibliotek
* `long int` datatype
* `unsigned int` datatype
* sammensatte tildelingsoperatorer av formen `=`*op* (liksom `=-`) ble forandret til formen *op*`=` for å unngå semantiske tvetydigheter. Konstruksjoner som `i=-10` kunne nemlig feiltolkes som `i&nbsp;=-&nbsp;10` i stedet for den korrekte `i&nbsp;=&nbsp;-10`

Funksjoner som ikke var deklarerte returnerte en variabel av typen `int`. Eksempel:

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

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

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


Mangelen på informasjon om funksjoners argumenter, gjorde at det ikke ble foretatt typesjekking, selv om enkelte kompilatorer ga en advarsel hvis lokale funksjoner ble kalt med feil antall argumenter, eller hvis flere kall til en ekstern funksjon benyttet et annet antall argumenter eller typer av argumenter. Separate verktøy som lint i UNIX kunne sjekke hvorvidt det var konsistens eller ikke i bruken av funksjoner i mange kildekiler.

I årene som fulgte, ble flere uoffisielle egenskaper tilføyd språket, støttet av kompilatorer fra AT&T og andre. Av disse kan nevnes:

* typen void for funksjoner som ikke returnerte noen verdi
* funksjoner som returnerte datatypene `[[struct (programmeringsspråket C)|struct]]` eller `[[union (informatikk)|union]]` i stedet for pekere
* tildelinger for `struct` datatyper
* oppsummerende typer

Det store antallet med utvidelser, mangelen på et C standardbibliotek, språkets popularitet og det faktum at ikke en gang UNIX-kompilatorer implementerte K&R-spesifikasjonen 100 %, førte til nødvendighetene av en standardisering.

### ANSI C og ISO C

På slutten av 1970-årene og i 1980-årene økte programmeringsspråkets popularitet betraktelig. Det ble laget C-kompilatorer for stormaskiner, minidatamaskiner og mikrodatamaskiner, deriblant IBM Personal Computer og dens etterfølgere som var basert på x86-arkitekturen.

I 1983 opprettet American National Standards Institute (ANSI) komitéen X3J11 for å utforme en standard-spesifikasjon for C. Standarden ble godkjent i 1989, og publisert i 1990 som ANSI X3.159-1989 *Programming Language C*. Den blir omtalt som ANSI C, Standard C og C89. I 1990 ble ANSI C adoptert av International Organization for Standardization (ISO) som ISO/IEC 9899:1990, og blir derfor noen ganger også omtalt som C90. Liksom tilfellet er med andre nasjonale standardorganisasjoner, videreutvikler ikke ANSI lenger noen C-standard. Standardiseringen skjer idag i regi av ISO.

Et av formålene med standardiseringen av C var å skape en overmengde (*superset*) av K&R C, hvor det ble inkorporert mange uoffisielle egenskaper som etterhvert ble introdusert. Standardkomitéen inkluderte også flere tilleggsegenskaper som funksjonprototyper (hentet fra C++), `void` pekere, støtte for internasjonale tegnsett og lokale parametre og forbedringer av preprosessoren. Syntaksen for parameter-deklarasjoner ble endret til den samme stilen som i C++, men av kompatibilitetshensyn var den gamle K&R syntaksen fortsatt lovlig.

C89/C90 støttes av nåværende C-kompilatorer, og det meste av C-kode som skrives idag er basert på denne standarden. Ethvert program som er skrevet i Standard C uten noen maskinavhengige og operativsystemspesifikke referanser, vil kunne kjøre på ulike plattformer. Når det benyttes ikke-standardiserte biblioteker som f.eks. biblioteker for Grafiske brukergrensesnitt eller biblioteker med plattformspesifikke attributter, er rekompileringer nødvendige for å tilpasse programvaren den rette endian byterekkefølgen.

I tilfeller hvor koden må være kompatibel med både K&R C og standard C, kan makroen __STDC__ bli benyttet for å lage seksjoner i koden som bare består av standard C.

### C99

### C11

### C17

### C23

### Innbakt C

## Egenskaper

### Oversikt

C er et relativt minimalistisk programmeringsspråk, som noen ganger refereres til som «portable assembly». Kode i dette programmeringsspråket kan kompileres og kjøres på omtrent alle plattformer, mens programmer skrevet i assembler bare kan flyttes imellom maskiner med kompatibel instruksjonssettarkitektur.

C har bl.a. disse egenskapene:
* Et enkelt grunnspråk med viktig funksjonalitet for matematikk og filbehandling i biblioteker.
* Fokus på funksjoner og moduler som legger til rette for en strukturert programmeringsstil.
* Datatyper som forhindrer mange operasjoner som ikke er meningsfulle.
* Bruk av pre-prosessor for oppgaver som å kunne definere makroer og inkludere flere kodemoduler.
* Lavnivå direkte tilgang til RAM ved hjelp av pekere.
* Parametere overføres alltid til funksjoner som verdier, aldri som referanse.
* Funksjonspekere, som muliggjør en grunnleggende form for polymorfi.
* Ordbok over variabler.
* Brukerdefinerte datatyper.

Selv om listen over nyttige egenskaper som mangler i C er lang, har dette ikke vært viktig for språkets anerkjennelse fordi C gjør det mulig å lage nye kompilatorer raskt på nye plattformer. I tillegg har programmereren tilnærmet full kontroll over hva programmet gjør, som igjen resulterer i at C-kode ofte kjører mer effektivt enn kode kompilert ifra mange andre programmeringsspråk. Typisk er det bare manuelt optimalisert assembler som kjører raskere, siden programmereren da har full kontroll over maskinen, men fremskritt i kompilatorer sammen med ny kompleksitet i moderne datamaskiner har gjort denne forskjellen mindre.

### «[[Hello, world]]»-eksempel
Et enkelt og vanlig eksempel på kodesnutter i programmeringsspråk er å skrive ut beskjeden «Hei, verden!» til skjermen.


```c
#include <stdio.h>

int main(void)
{
    printf("Hei, verden!\n");

    return 0;
}
```


### Løkkeeksempler
Et eksempel på en «while»-løkke som går uendelig mange ganger rundt og skriver ut «Hallo verden!» like mange ganger.

```c
#include <stdio.h>

int main(void)
{
    while (1)
    {
        printf("Hallo, verden!\n");
    }
    return 0;
}
```


Et eksempel på en «while»-løkke som går 10 ganger rundt og skriver ut rundenummeret like mange ganger.

```c
#include <stdio.h>

int main(void)
{
    int i = 0; // rundeteller
    while (i < 10)
    {
        printf("while %d\n", i);
        i++;
    }
    return 0;
}
```


Et eksempel på en «for»-løkke som går 10 ganger rundt og skriver ut verdien av rundetelleren like mange ganger.

```c
#include <stdio.h>

int main(void)
{
    int i;  // rundeteller
    for (i = 0; i < 10; i++)
    {
        printf("runde: %d\n", i);
    }
    return 0;
}
```


### «Hvis/dersom»-eksempel
Et eksempel på en «if/else» betingelse som sammenligner verdiene av x og y.

```c
#include <stdio.h>

int main(void)
{
    int x=1;
    int y=3;

    if (x < y)
    {
        printf("x er mindre enn y\n");
    }
    else if (x > y)
    {
        printf("x er større enn y\n");
    }
    else
    {
        printf("x og y er like store\n");
    }

    return 0;
}
```


## Referanser


## Litteratur
* 
** 
* 

*Herbert Schildt: *C, the Complete Reference*, 1. utgave, 1988; 2. utgave, Osborne McGraw-Hill, august 1989, 3. utgave Osborne McGraw-Hill 1998; 4. utgave, Osborne McGraw-Hill, 26. april 2000, ISBN 0-07-212124-6, ISBN 978-0-07-212124-7

## Eksterne lenker
* 
*  ''The Development of the C Language'' av Dennis Ritchie