Programmering (fra oldgræsk πρόγραμμα prógramma)Wilhelm, Pape. & Max, Sengebusch. (1914). Handwörterbuch der griechischen Sprache (6. udg., Bd. 3). Vieweg & Sohn. er en proces, som går ud på at udvikle computerprogrammer (software) til elektronisk databehandling på en computer, ofte ved hjælp af et programmeringssprog. Programmering er en underafdeling af softwareudvikling. Formålet med et program er overordnet at modtage nogle input-data, udføre en opgave på disse (f.eks. beregninger, udskrivning, kommunikation med database) og som resultat tilbagelevere nogle output-data. thumb|550px|Lidt JavaScript-kode i en HTML-fil. Javascript er fortolket kode.

Programmeringsprocessen Udviklingen af et program er en proces bestående af det at skrive kildekode, testning, fejlretning (også kaldet aflusning, eng. debugging) og vedligeholdelse af kildekoden. Programmet skrives som regel som ren tekst i et programmeringssprog, som har en defineret syntaks for koden. Hvis der er tale om et compileret sprog, oversættes (compileres) kildekoden først til maskinkode eller et anden mere maskinnær kode. I denne compilering opdages også eventuelle syntaksfejl. Den oversatte maskinkode kan derefter køres af computeren. Hvis der er tale om et fortolket sprog, kører fortolkeren programmet direkte fra kildekoden, og først undervejs i kørselen opdages eventuelle syntaksfejl.

Programmeringen er en del af hele systemudviklingsprocessen, og forudsætningen for at programmere er, at der først er gennemført en analyse af, hvilke krav systemet skal opfylde over for brugerne. Dette er beskrevet i en kravspecifikation. Herefter designes systemet, og programmeringen gennemføres.

Der er en løbende debat om hvorvidt kodning af programmer er en kunst, et håndværk eller en ingeniør disciplin. Generelt anses god programmering for en afmålt anvendelse af alle tre, hvor målet er at producere en effektiv software-løsning som kan videreudvikles. Disciplinen afviger fra mange andre tekniske professioner, da programmører, generelt set, ikke behøver licens eller bevis på en standardiseret (eller offentligt reguleret) certifikation for at kalde sig selv "programmører" eller endda "softwareingeniør".

Datatyper Data i et program skal tilhøre en bestemt datatype. Hvilke datatyper, der kan anvendes, afhænger af programmeringssproget, men groft sagt kan de deles op i:

Primitive datatyper Heltal Her er der flere typer afhængig af, hvor store heltal man har behov for at kunne beregne. Decimaltal Her er der også flere typer afhængig af behovet for regnenøjagtighed (eng. precision) på decimaler. Sandhedsværdi (boolean) Disse kan kun antage to værdier, sandt eller falsk. Tegn / karakter Kan være et hvilket som helst tegn i det tegnsæt, programmet anvender. Peger (eng. pointer) Indeholder en reference til en variabel og består egentlig af variabelens adresse i hukommelsen.

Sammensatte datatyper

Tekststreng En tekststreng (eng. string) er et stykke tekst bestående af et antal tegn (karakterer). Grundlæggende er alle inputdata og outputdata til et program af denne type, der så af programmet skal oversættes til f.eks. heltal. Array Er en statisk, indiceret samling af variable af samme datatype. Post (eng. record) Består af felter af forskellig datatype. Denne afspejler bl.a. en post i en database-tabel.

Objekter

Objekt En avanceret datatype, som i nyere objektorienteret programmering er en type med både har data og adfærd. I et objektorienteret sprog dækker et objekt over andre sammensatte datatyper.

Operatorer For at regne på de enkelte datatyper opstiller man regneudtryk, der består af dataværdier og operatorer. Operatorerne kan deles op i: Aritmetiske operatorer, der regner på talværdier. Konkatenering, hvor to tekststrenge sættes sammen til én. Logiske operatorer, der sammenligner værdier og regner på sandhedsværdier. Derudover har de enkelte programmeringssprog en række ekstra operatorer for at håndtere sprogets sætninger og datatyper (især objekterne).

En vigtig del af et programmeringssprog er dets operatorpræcedens, der angiver rækkefølgen for at bruge de enkelte operatorer, hvis der optræder flere forskellige i samme udtryk.

Variable og konstanter En dataværdi placeres ofte i en eller flere variable (pladsholder). En variabel er kendetegnet ved et alfanumerisk variabelnavn og en bestemt datatype, men dens konkrete værdi kan skifte undervejs i programmet. Har man brug for en pladsholder, der ikke må skifte værdi, har de fleste sprog mulighed for at definere en konstant.

Sætninger

For at opfylde sine formål gennemgår programmet nogle algoritmer, der er sekvenser af beregninger. De enkelte trin i sprogets implementering af en algoritme kaldes sætninger, som grundlæggende opdeles i: Variabelerklæringer, hvor man opretter en variabel og angiver dens datatype. Tildelinger (eng. assignment), hvor man giver en variabel en bestemt dataværdi, der måske udregnes i den samme sætning. Forgreninger, hvor et sandhedsudtryk afgør, om programmet skal udføre den ene eller anden gruppe sætninger. Løkker, hvor et sandhedsudtryk er afgørende for, hvor mange gange man skal udføre en gruppe sætninger. Funktionskald, hvor en gruppe sammenhørende beregninger er blevet samlet i en selvstændig programdel (funktion, procedure, metode), som så kaldes fra andre dele af programmet.

Forgreninger Forgreninger er noget af det mest basale i et program, fordi grundlaget for computerberegninger netop er forgreninger, hvor der overalt evalueres på, om noget er sandt eller falsk. For at en algoritme ikke blot er en lineær sekvens af beregninger, men kan variere beregningerne afhængig af de givne data, er man nødt til at vurdere på, hvorvidt en betingelse er opfyldt eller ej. Enhver forgrening indledes derfor med en betingelse. Forgreninger kan også være indlejrede i hinanden (eng. nested), så man kan gå tre eller flere veje det givne sted i algoritmen.

thumb|280px|En programstump i BASIC med eksempler på GOTO-sætninger. I de ældste programmeringssprog implementerede man forgreninger ved hjælp af etiketter (eng. labels) ved bestemte sætninger eller linienumre kombineret med GOTO-sætninger, der fortalte, hvor i programmet man skulle gå hen. GOTO-sætninger kunne dog nemt medføre fejl i programmets flow, fordi der til enhver "gren" i en forgrening skulle være en GOTO-sætning både for at starte på grenen og for at afslutte den. I dag har man andre metoder til at vise, at en gruppe sætninger hører sammen i en "gren". Som regel bruger man nøgleord som IF ... THEN ... ELSE ... for at implementere en forgrening, eller SWITCH ..., SELECT ... el.lign. ved en bredere forgrening.

Løkker Hvis en gruppe sætninger skal udføres flere gange, indfører man en løkke i programmet. Også her skal der anvendes en betingelse, der skal evalueres hver gang en iteration i løkken indledes eller afsluttes. Et meget vigtigt element i programmeringen af en løkke er at sikre sig, at gruppen af sætninger i løkken ændrer på data på en sådan måde, at betingelsen på et tidspunkt får programmet til at hoppe væk fra løkken. Hvis ikke, går programmet ind i en uendelig løkke med fatale følger for dets gennemførelse.

Også løkker blev i de ældste programmeringssprog implementeret vha. GOTO-sætninger, og ligesom i en forgrening kunne det være komplekst at placere GOTO-sætninger rigtigt i programmet. I dag er løkker implementeret med nøgleord som f.eks. WHILE ... DO ... , REPEAT ... UNTIL ... eller <tt>FOR ... NEXT ... </tt>.

Funktionskald Hvis man har brug for at udføre den samme type beregninger flere steder i et program, eller hvis en gruppe sætninger hører så meget sammen i forhold til sætningerne omkring dem, at man har et ønske om at "pakke dem ind", kan man med fordel oprette en funktion (kaldes også procedure, (sub)rutine, metode). Funktionen kan modtage én til flere parametre som sine "input-data", og den kan tilsvarende returnere et resultat som "output-data". De steder i programmet, hvor beregningerne skal udføres, gennemfører man så et kald af funktionen med nogle aktuelle værdier som parametre, og en eventuelt returværdi fra funktionskaldet kan man så opfange og arbejde videre med. En fordel ved funktioner er, at variable, som kun oprettes af hensyn til beregningerne internt i funktion, kan erklæres lokalt i funktionen, så andre dele af programmet ikke kan manipulere, endsige se dem.

Funktionskald var svære at gennemføre, da man kun havde GOTO-sætninger til rådighed. Det kunne lade sig gøre med lidt datadisciplin, for alle variable, også de lokale i funktionen, kunne i princippet anvendes overalt (globalt). I det mindste skulle både parametrene og returværdierne (grænsefladen mellem det kaldende sted i programmet og funktionen), anvendes både inden for og uden for funktionens gruppe af sætninger. Endelig skulle der være en variabel, der viste, hvilken etiket programmet skulle returnere til, når funktionen var færdig. Endnu mere komplekst blev det, hvis man skulle lave en såkaldt rekursion, hvor en funktion internt i sine beregninger kalder sig selv. Da hver funktionskald skulle kunne finde tilbage til det kaldende sted i programmet, var man nødt til programmeringsmæssigt at lave en begrænsning for, hvor mange rekursive kald der kunne være inden i hinanden.

Struktureret programmering Den omfattende brug af GOTO-sætninger i implementeringen af forgreninger, løkker og funktionskald kunne meget nemt føre til uoverskuelig spaghettikode. Især var det begrænsningerne ved funktionskald, der fremkaldte et behov for at kunne "indhegne" en gruppe sammenhørende sætninger i en blok, f.eks. med en parentetisk BEGIN ... END-struktur eller andre typer parenteser. Sådanne blokke anvendes både omkring de sætninger, der skal udføres i en forgrening og en iteration i en løkke, men de er især anvendelige til at erklære funktioner med parametre, returværdier og lokale variable. Sammen med de nye sprog med sådanne faciliteter opstod programmeringsparadigmet struktureret programmering.

I de fleste sprog designet til struktureret programmering har man også muligheden for at erklære en funktion inde i "kroppen" af en anden funktion. På den måde kan en funktion ikke kun indeholde lokale variable, men også lokale funktioner. Der gælder nemlig som regel, at lokale variable eller funktioner i en funktion ikke kan "ses" udefra; man taler om, at deres scope kun er funktionen selv eller funktioner erklæret inde i funktionen. I sprog, hvor dette ikke gælder automatisk, er det op til programmøren selv at udvise datadisciplin ved anvendelsen af variable. Udover at undgå anvendelsen af GOTO-sætninger er konsekvens omkring variables og funktioners scope nok det vigtigste middel til at undgå spaghettikode i struktureret programmering.

Kompleksitet Struktureret programmering åbner også større muligheder for at arbejde med abstrakte datatyper, dvs. komplekse datastrukturer, der vha. reference-typer (pegere/pointere), post-typer og specielle funktioner er optimeret til at kunne udføre f.eks. indsættelse af elementer eller søgning efter elementer. Med de større muligheder blev der også større behov for at vurdere effektiviteten af et program, særligt med henblik på en algoritmes kompleksitet. Hermed menes en vurdering af, i hvilket omfang beregningstiden i algoritmen vokser, når datamængden stiger. Hermed fik programmøren redskaber til at finde frem til den mest effektive algoritme for sit program.

Objektorienteret programmering