Introduktion til programmering i C, C++ og WIN32
- skrev denne artikel Tirsdag, 06 December 2005
C er et efterhånden meget gammelt programmeringssprog, det startede oprindeligt som en joke, men sproget blev hurtigt populært, faktisk så populært at det i lang tid tilbageholdt udvikling af objektorienterede sprog. Folk var simpelthen uvillige til at gå bort fra deres farvoritsprog, C med klasser blev udviklet men det var ikke nok. Løsningen kom fra danskeren Bjarne Stroustrup C++ overtog hvor C stoppede, det udbyggede C sproget uden at gøre det het ugyldigt. Man kan stadig programmere almindelig C og compile det i en C++ compiler uden de store problemer. Udover dette tilføjer C++ så sine egne småting til sproget, men vigtigst af alt er måske klasserne, når man har en instans af en klasse kaldes dette et objekt. Altså er C++ et objektorienteret sprog, selvom det ikke er helt så påkrævet som i Java hvor ALT er klasser og objekter. Jeg vil herefter ikke nævne J*** mere (selvom jeg må acceptere eksistensen af dette skræmmende sprog).Nej nej jeg er ikke færdig endnu, jeg har jo ikke nævnt WIN32, for at forstå WIN32 må vi forstå hvordan det hele startede, imidlertid kan vi blot se bort fra pre 8086 tiden, 8086 cpu'er blev til at starte med konstrueret som 16 bit cpu'er med 16 bit cpu'er kom 16 bit OS det første som de fleste stadig har hørt om må være DOS et gammelt kommandobaseret OS som næsten aldrig crashede, uheldigvis lod det meget tilbage at ønske når det kom til grafik. så vi skiftede videre til et GUI eller mere nøjagtigt et WIMP GUI, Windows, til at starte med fik disse udgaver fine numre op til windows 3.11 men nu begyndte man så samtidig at ville have større hastighed, et af problemerne med  dette var at 16 bit ikke gav store beregninger nøjagtigt og hurtigt nok. Altså begyndte man at benytte 32 bit cpu'er men hvad godt er en 32 bit cpu hvis man ikke har et system der kan udnytte dette, løsningen hed windows 95 det første WIN32 OS. Dette fik også betydning for grafikken og efter nogen tid begyndte firmaer at lave 32 bit programmer som kun kunne starte i windows 95 eller nyere. I dag er mange af disse programmer blevet forældede, efterhånden som der er kommet nyere windows grene de nyeste er dem på NT grenen som f.eks. Windows NT, 2000 og XP. Nu spørger du nok dig selv om der er et formål med alt det her historie, men det er der faktisk ikke udover selvfølgelig en lektion i aldrig at sige noget holder for evigt.

--- Herefter er det færdigt med historie, 1/3 af det der står over dette punkt er nok forkert. ---

--- Nu er jeg på hjemmebane så herefter er det 99% korrekt, hvis du finder fejl så lad være med at læse det du har jo ikke behov for det så. ---

forudsætninger: IQ >= 110, interesse nok til at have læst det ovenstående uden at falde i søvn, eller til at scrolle herned for at se om det blev mere spændende og herefter  en dedikation til at lære at programmere, dette er en MEGET kort introduktion det ville være fornuftigt at forstå på forhånd at linierne eksekveres sekventielt, hvis du  ikke forstår dette så lad i det mindste som om programmet er en stil, du kan godt lave krydshenvisninger til ting længere fremme men hvis ikke du specifikt gør dette kender  læseren ikke det der kommer efter det du skriver nu.

Det er smart at have en compiler så man kan prøve disse ting, jeg anbefaler den gratis compiler Dev-C++, eller den dyre  compiler Microsoft Visual Studio, alle eksempler jeg laver er afprøvet til at virke i Dev-C++ hvis ikke de virker i M$ VS så sig til så kigger jeg på hvorfor, grunden til  jeg ikke dobbelt-tester hele vejen er at jeg ikke går ud fra at folk der bare vil lære C++ har behov for en dyr compiler som kan det samme eller i nogen tilfælde mindre. Der er selvfølgelig fordele men da jeg vil gennemgå forskellige triks bliver mange af disse overflødige, i øvrigt kan der ofte downloades gratis programmer der kan efterligne  mange af fordelene. Den allerstørste fejl ved Dev-C++ er at den som standard ikke er sat til at vise hvad en klasse indeholder når man trykker '.' eller '->' som VS er  dette kan dog slås til. En bug i Dev-C++ gør at dette ofte får maskinen til at tænke længe og af og til får den til at crashe. Grunden til jeg ikke anbefaler watcom er at  den ikke kommer med et IDE hvis du ved hvad dette er og beslutter dig for at bruge Watcom har du nok ikke behov for denne tutorial, ihvertfald ikke når det kommer til  kompatibilitet og compilering så sæt dig ned og lad værre med at skrive til mig om dette.

lad os starte med begrebet variabel, disse er altid vigtige. Variabler indeholder data som programmet skal bruge senere, forestil dig en persondatabase hvor vi vil gemme data om en person, vi vil vide hans/hendes navn, alder, køn og penge i hans/hendes pung. Hver af disse informationer skal gemmes i en separat variabel hvis type er bestemt herudfra. Alderen må formentlig være et heltal, heltal på engelsk hedder integer og forkortes i C som int, køn kan kun have 2 muligheder så vi kunne måske bare lave en  variabel der hed mand og så sætte den til sand(1) eller falsk(0) dette kan altså repræsenteres med 1 bit (vi kunne lige så godt gemme dette som enten 'm' eller 'k' i en  char da en enkelt bit ikke er reserverbar i en 8086 cpu men lad os nu lege med her ikke), disse 1 bit variabler kalder vi boolean og forkorter bool. vi skulle også have information om penge i pungen da disse ikke nødvendigvis er et heltal må vi repræsentere dem med noget der kan håndtere komma tal normalt bruger vi her floating point values, vi forkorter dette til float, normalt ville man ikke bruge float her jeg vil forklare senere hvorfor. Til tider vil de ovennævnte typer blive ændret lidt hist og her og jeg  vil forklare disse ændringer efterhånden som de opstår. Nej jeg har endnu ikke glemt navn helt endnu men navn fortjener en lidt længere fortolkning vi vil lave en kort en  her og uddybe MEGET senere. I vores computer bliver variablerne tildelt et stykke af vores ram svarende til deres størrelse men da programmet ikke bare kan gætte på hvor  store vores tekststykker bliver må vi hjælpe den lidt med at specificere en maks længde de kan have når vi skaber dem dette gøres mellem en '[' og en ']' vi kan nogen gange  undlade at specificere denne grænse, men det er næsten altid smart at gøre. Jeg vil nu give et eksempel på noget C kildekode og gennemgå de dele der indgår.

001   #include <string.h>
002  
003   int main(int argc,char **argv){
004    char navn[256];
005    int alder;
006    bool mand;
007    float penge;
008  
009    strcpy(navn,"Jens");
010    alder=42;
011    mand=1;
012    penge=11.50;
013    return 0;
014   }


numrene foran linierne skal ikke med, de er der udelukkende så du ikke skal tælle selv.

linie 01; programmet skal bruge hjælpebiblioteker hvor vi kan hente funktioner fra, funktioner vil blive forklaret senere så for nu må linien bare godtages som værende nødvendig.
linie 03; ikke så meget at sige det er introduktionen til selve C programmet den skal altid med, forklaring på hvorfor den ser således ud kommer senere.
linie 04; i C og C++ skal alle variabler initialiseres, initialisering vil sige at vi giver dem et navn og siger hvad de kan indeholde, char vil sige at det er bogstaver 'navn' er navnet på variablen og [256] er hvor mange tegn der er, altså vi laver navn som indeholde max 256 tegn uheldigvis skal alle tekststrenge (den tekniske betegnelse for en samling af bogstaver) slutte med et 0 ikke tegnet '0' men ASCII værdien 0, derfor kan navn reelt kun indeholde 255 bogstaver men så langt navn har Jens ikke og det er lige nu maksimum vi skal bruge.
linie 05; vi laver en variabel mere en integer med navnet 'alder' vi bruger disse navne når vi senere skal specificere hvilken variabel vi taler om.
linie 06; som forklaret ovenfor laver vi en boolean til køn og kalder den mand.
linie 07; en float til penge, normalt ville man gemme dette i en int fordi vi på forhånd ved at vi bare kan udtrykke det i ører og så bare dividere med 100 når vi skal angive ting i kr., årsagen til at man ofte bruger int her er at man ikke kan tvinge computeren til at glemme alt efter 2 pladser efter komma, udover dette er integer regning MEGET hurtigere (ikke at du ville kunne mærke det på noget med over 8 MHz medmindre du skal bruge MANGE).
linie 09; da vi nu har specificeret vores variabler tildeler vi så disse værdier, du undrer dig måske over strcpy men dette er simpelthen måden man kopierer en streng på den hænger sammen med de der fine '[]' vi lavede og en nærmere forklaring på hvorfor navn="Jens"; er en MEGET dårlig ide kommer senere under arrays.
linie 10-12; det er selvfølgelig ikke matematisk korrekt, men det er nu måden det oftest gøres på i nyere programmeringssprog, = er simpelthen en tildeligsoperator. Den tildeler det der står på højre side til det der står på venstre side (den kopierer det hvis vi skal være helt nøjagtige).
linie 13; return 0; afslutter programmet og fortæller dos (ja det her kører i dos windows eksemplet kommer lige om lidt) at programmet sluttede med succes (ikke at dos gør noget ved dette medmindre vi beder den om det).
linie 14; vi havde en '{' i linie 3 rummet mellem '{' og '}' er det område hvor programmet står, mere korrekt er den en gruppering af data men uden en meget dybere forklaring på eksekvering af maskinkode, må vi acceptere at det er en blok af instruktioner der hører sammen.

Det var jo ikke så slemt, var det? Men jeg lovede at oversætte det til Windows kode, jeg er ikke sikker på det er den bedste idé jeg har fået, men jeg vil nu fortsætte med  at lave tutorials som alle er i windows årsagen til at jeg tog dos først var for at skræmme alle væk der nok ikke har fortjent at lære at programmere, hvis du stadig læser  og du ikke har revet 2/3 af dit hår af i frustration kan du roligt læse videre.
jeg vil give det samme eksempel som ovenfor og forklare de linier jeg har ændret.

001   #include <windows.h>
002  
003   int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow){
004    char navn[256];
005    int alder;
006    bool mand;
007    float penge;
008  
009    strcpy(navn,"Jens");
010    alder=42;
011    mand=1;
012    penge=11.50;
013    return 0;
014   }


Hvis det ikke vil compile så husk at du først skal ind og sætte den til windows start et nyt projekt (hvis du ikke kan gennemskue hvordan det skal gøres skulle du måske  starte med et pc grundkursus!!!), og sæt din over på win32 (ikke den med consol vi kan ikke lide consoler medmindre det er til debug og det er endnu ikke nødvendigt og til  den tid kan vi tricks så vi stadig ikke behøver det). Slet alt der står i vinduet og sæt mit ind i stedet, fjern så numrene før hver linie og compiler(det burde du også  kunne finde knappen der gør uden hjælp, ellers er det den der ligner indholdet af et windows logo skildt ad (nej det er ikke det den skal ligne det er bare det den ligner  mest)). Kør er knappen ved siden af, og den ved siden af den er compiler og kør (dette er altså i Dev-C++ i VS trykker du bare play).

linie 1; i stedet for string.h har vi nu windows.h, vi havde ikke behøvet ændre dette men jeg mente det var ok at have den med.
linie 3; i stedet for main har vi WinMain og så har vi ændret på tingene i parantesen, så når folk fremover fortæller dig at dos er meget simplere at lære en windows så mind dem lige om at den enste forskel er en længere main linie. Dette er måske en oversimplificering men windows programmet her gør det samme som dos programmet ovenover  hvilket er mere eller mindre ingenting. Du havde måske forventet at få noget af hvide når du startede programmet men som du sikkert har opdaget gør det intet. Årsagen er at  vi ikke har noget output fra programmet, hvis du tror jeg nu vil fortælle hvordan det gøres i dos så tog du fejl, jeg vil i stedet vise det i windows med den værste form  for output du kan forestille dig, en MessageBox (det er du der der spørger dig om du er sikker på du vil lukke programmet eller fortæller dig du skal trykke på ok). en  MessageBox laves med funktionen MessageBox. Det der er i parantesen efter en funktions navn når vi kalder den kaldes argumenter tidligere så vi på funktionskaldet strcpy  fra string.h og bagefter den samme fra windows.h, der er mange funktioner i disse filer og jeg vil kun gennemgå en lille del af dem der er i windows.h, MessageBox forventer  nogle bestemte argumenter den forventer et vindue den kan vises på, en tekst, en overskrift og en beskrivelse af hvordan den skal se ud, et vindue i WIN32 er en variabel at  typen HWND, vi kunne lave en af disse i vores program men det er for besværligt i stedet bruger vi 0 dette fortæller at boxen ikke tilhører et bestemt vindue men bare skal  vises, som tekst kan du skrive hvad du vil mellem to " " disse indikerer at det der står mellem dem er en tekststreng, som overskrift kan du også prøve en hvilken som helst  tekststreng igen med " omkring. Til sidst mangler der bare hvordan den skal se ud til at starte med kan vi jo nøjes med MB_OK dette er en helt almindelig MessageBox med en

ok knap. eks:
MessageBox(0,"Jeg er stadig totalt N00B","Hallo World!",MB_OK);
Som du sikkert kan se giver denne linie en fin MessageBox, hvis du har overset indtil nu at der er ';' efter alle linier når jeg skriver kode så er det nok fordi du  allerede er vant til at programmere grunden til at de er der er for at fortælle computeren at det før ; er en instruktion du kan sagtens have flere af disse på en linie  hele programmet kunne kortes ned til 2 linier men for din egen skyld bør du ihvertfald i starten nøjes med 1 instruktion per linie.

Lad os lave lidt sjov, prøv at gætte hvad der sker med linien:
MessageBox(0,"Jeg er stadig totalt N00B",navn,MB_OK);

hvis du gættede det viser det at du er opmærksom og skarpsindet, hvis du glemte at det skulle være i det program vi havde ovenover så fik du nok en fejl og hvis du udfra den kan gætte dig til hvad der burde ske er du også lidt skarpsindet (hvis du kiggede på den og tænkte den var nødt til at være i den hvor variablen navn var defineret  hvorefter du skrev en definition på navn ovenover og satte den til en værdi visser det at du tænker i baner der gør at du nok skal blive en god programmør, desuden viser det  at du har lært noget).
Men vi ville måske også skrive noget om Jens inde i boksen. Gerne over flere linier noget i retning af:

Der er et lille problem i dette, vi burde have lavet køn som en streng det havde gjort det meget nemmere, i stedet må vi nu lære om if sætninger, (nej nej det var ikke  planlagt) en if sætning er en måde vi kan styre på om noget kode skal udføres eller ej, vi skriver "if(" og så en betingelse og så en ")" vi skifter linie men uden en ';'  bagpå så skriver vi hvad den skal gøre hvis det er sandt for at få det til at se pænt ud rykker vi lige 2 mellemrum eller 1 tabulator eller hvad du nu har lyst til ind.  Efter dette husker vi selvfølgelig ';' på næste linie kan vi hvis vi vil skrive "else" og så på linien derefter skrive hvad der skal gøres hvis udtrykket imellem '(' og ')'  er falskt (som jeg nævnte for længe siden er falsk 0, i C er alt som ikke giver 0 sandt og dermed er "0" sandt fordi "0" er en streng tegnet '0' ville også være sandt mens  '\0' er falsk da dette er ASCII 0), i denne betingelse kunne vi teste om alder var 17 så ville vi skrive alder==17 som betingelse vi har 2 '='da vi gerne vil sammenligne og  ikke tildele (nogen gange vil vi tildele og C giver os lov til det resultatet af en tildeling er den værdi vi tildeler så alder=17 ville tildele 17 til alder og vil køre  linien efter if fordi 17 i C er sandt). Nu burde du være rustet til at forstå følgende kildekode. Udover if sætningen må vi også introducere en måde at forvandle tal til tekststrenge da det er det eneste vi kan vise med MessageBox så vi benytter sprintf fra stdio.h den forventer en  streng efterfulgt af en streng og så ellers andre argumenter resten af vejen. Den første streng er hvor vi skal skrive til lav en variabel der hedder output som er i stand  til at håndtere alt vores tekst (brug 256 eller 512 så er vi da sikrede), brug så output som første argument, næste argument er det der kaldes en format specifikation her  skriver du det du vil kopiere til output mellem to " som altid, forskellen er så af du kan skrive %d, %f osv. disse indikerer at du vil sætte en variabel ind på denne  plads. \n indikerer linieskift, %d indikerer at du vil have en int ind her, %f at du vil have en float ind her. De efterfølgende argumenter er så hvilke variabler du vil  have ind på %d og %f's plads i den samme rækkefølge som de kom i format strengen. Prøv nu om du selv kan lave den MessageBox jeg havde, det er ikke så nemt igen vel. Men  det er heller ikke umuligt. Jeg vil nu give et eksempel på hvordan det kan laves kun med de ting jeg har forklaret indtil nu.
001   #include <windows.h>
002   #include <stdio.h>
003  
004   int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow){
005    char output[512];
006    char navn[256];
007    int alder;
008    bool mand;
009    float penge;
010  
011    strcpy(navn,"Jens");
012    alder=42;
013    mand=1;
014    penge=11.50;
015  
016    if(mand)
017      sprintf(output,"Alder: %d\nKøn: Mand\npenge: %f",alder,penge);
018    else
019      sprintf(output,"Alder: %d\nKøn: Kvinde\npenge: %f",alder,penge);
020   
021    MessageBox(0,output,navn,MB_OK);
022    return 0;
023   }


linie 5; jeg sagde jo du skulle indsætte denne linie.
i linie 16 og 18 ser vi den fine if sætning struktur jeg beskrev. Men der er noget galt, den skriver jo 11.500000 i stedet for 11.50, som jeg tidligere nævnte burde vi have gjort det med en int i stedet men da det nu er en float vi har skriver vi bare %.2f i stedet for %f, dette angiver at vi vil have 2 cifre efter kommaet. nu ville du måske af og til gerne putte en streng ind i stedet for et tal, til dette bruges %s, nu tror du måske man kan skrive noget i retning af:
sprintf(output,"Alder: %d\nKøn: %s\npenge: %f",alder,if(mand) "Mand" else "Kvinde",penge);
og det kan man faktisk det ser ikke helt sådan ud, i stedet bruger man ?: operatoren, dens syntax (et fint ord du lige må slå op hvis ikke du kender det) er betingelse?sandt tilfælde:falsk tilfælde, f.eks:
sprintf(output,"Alder: %d\nKøn: %s\npenge: %.2f",alder,mand?"Mand":"Kvinde",penge);
dette ville lave en MessageBox med præcis den kode jeg havde da jeg tog screenshot. Det er kortere end en if i dette tilfælde og det var kun en simpel detalje der skulle ændres, det ser desuden pænt ud i kilekoden og det er vigtigt (selvom det nok foreløbig kun er dig og en apatisk compiler der skal læse det).

for at du ikke behøver slette det mindre gode kode (det kunne jo være du fandt ud af det eksekverede hurtigere senere) kan man udkommentere koden dvs. lave det der står om til en kommentar i C starter en kommentar med /* og den slutter med */ alt imellem bliver overset af kompileren i C++ kan man desuden bruge // som gør resten af linien til en kommentar, kommentarer i kode er populære fordi de hjælper dig når du 3 år senere skal skrive kode der skal læses af andre uden din fantastiske hukommelse og viden om hvordan sproget virker. Jeg har tilføjet lidt kommentarer i min kode, hvis du tilføjede lige så meget i en ikke tutorial ville folk nok fortælle dig du overkommenterer det er dårlig skik at kommentere simple tildelinger. Til gengæld er det ok at kommentere variable deklarationer hvis det ikke er åbenlyst udfra navnet hvad de bruges til:

001   ////////////////////////////////////////////////////
002   // Program: Tutorial 1 - intro
003   // Author: Allan A. Olsen AKA. Orange_Newton
004   // Dato: 06-12-2005,07-12-2005 (den krydsede midnat for lidt siden)
005   ////////////////////////////////////////////////////
006  
007   #include <windows.h>
008   #include <stdio.h>
009  
010   int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow){
011    char output[512];    //output bruges til at skrive teksten inde i MessageBox'en
012    char navn[256];      //navn er navnet på personen og det bruges som overkrift
013    int alder;            //alder er personens alder
014    bool mand;            //sandt hvis det er en mand eller falsk hvis det er kvinde
015    float penge;          //mængden af penge personen har i sin lomme
016  
017    strcpy(navn,"Jens");  //navn sættes til Jens
018    alder=42;            //Jens er 42 år gammel
019    mand=1;              //Jens er en mand
020    penge=11.50;          //Jens har 11kr og 50øre i lommen
021  
022    // vi vil nu fylde information i output
023   /* //gammel version
024    if(mand)
025      sprintf(output,"Alder: %d\nKøn: Mand\npenge: %f",alder,penge);
026    else
027      sprintf(output,"Alder: %d\nKøn: Kvinde\npenge: %f",alder,penge);
028   */
029  
030    //hurtig version
031   //  sprintf(output,"Alder: %d\nKøn: %s\npenge: %.2f",alder,mand?"Mand":"Kvinde",penge);
032  
033    //ny version
034    sprintf(output,"%s er en %d år gammel %s, med %.2f kr. i lommen.",navn,alder,mand?"mand":"kvinde",penge);
035   
036    MessageBox(0,output,navn,MB_OK);//vi viser nu output
037    return 0;
038   }


jeg har mixet og matchet de forskellige stile med hinanden her, brug den du bedst kan lide eller mix dem på samme måde, den på linie 34 laver det hele som en pæn tekst i stedet for hårde facts, jeg har kommenteret den hurtige og den gamle væk, da jeg bedst kunne lide den nye, du kan selv finde ud af hvilken du bedst kan lide ved at fjerne udkommenteringen fra den ene og udkommentere den nye i stedet. Jeg vil nu mene det tutorial er slut, har du spørgsmål så skriv til mig på:
admin@AODASoft.net
Den færdige kildekode kan hentes her.