Tips og triks i programmering.

Programmering i sin ytterste konsekvens er en livsstil. Hvis du skal lage et bra program er alt avhengig av hvordan du ser på det. Hvis du ikke har følelser for programmet vil det bli dårlig og uten sjel. En god programmør legger noe av seg selv i ethvert program han eller hun lager. Du trenger ikke å bli like god som Mel , men litt bør du legge i et program.


Programmering

Det er flere måter å programmere på, og alle har sine fordeler og ulemper. Det de fleste hobby-programmører gjør er å begynne rett på kildekoden og la programmet vokse ut fra dette. For små program virker dette ok, men hvis du skal lage noe stort bør du forberede deg litt.

Først bør du finne ut hvorfor du skal lage programmet. Hvilket behov skal det fylle? Skriv ned dette svaret så du ikke glemmer det. Når du programmerer er det lett å miste oversikten og skli ut. Å skrive ned målet gjør det lettere å unngå å lage programmet som har alt også.

Så begynner du å lete etter et program som gjør akkurat det du trenger. Du vil bli forbauset over hvor mange slike program som finnes. Prøv å få med deg kildekoden til noen og lær av dem.

Hvis du ikke ble fornøyd med programmene du fant, lager du det selv. Da kan det være lurt å plukke ut de tingene du likte best med de andre programmene og kombinere dem i ditt eget.

En ting som kan spare deg for en god del arbeide er å finne deg et bibliotek som gjør programmeringa litt enklere. Da kan du konsentrere deg mer om hva som skal skje istedenfor hvordan. Hvis du skal prøve et nytt bibliotek er det lurt å lese dokumentasjonen grundig. Det vil gjernest spare deg for en god del svette og tårer.


Angrepsvinkel

Når du begynner å programmere kan du velge om du vil begynne nedenfra eller ovenfra. Å programmere nedenfra er å lage alle funksjonene først og så binde det hele sammen i main(). Den andre måten er å lage et omriss av programmet (med kommentarer, en meny eller noe slikt), og så lage funksjonene som trengs. Personlig liker jeg å variere litt. Jeg begynner ofte med å lage et omriss av programmet med kommentarer før jeg lager noen funksjoner og klasser jeg vet jeg vil trenge. Så syr jeg det hele sammen når jeg har fått oversikten. Da blir det mindre omskrivinger.

Programmering i C++ foregår nesten utelukkende i tekst. Tekst er et medium som er 'flatt' og har dårlig oppløsning , men det har også fordeler som du bør utnytte.

Når du programmerer skal du alltid ha blyant, viskelær og tegneblokk i nærheten. Dette er programmørens viktigste hjelpemiddel etter editoren. På papiret kan du kjappt skrive ned ideer som faller deg inn, tegne grafer og modeller, simulere variabler under kjøring etc etc.


Den kreative prosessen.

Det viktigste du gjør når du får en ide, er å skrive den ned, ellers vil du glemme den før du får sukk for deg. Hvis du ikke har tid til å skrive og tenke ut hele ideen akkurat der og da, kan du skrive ned meningen med den (stikkord eller noe som vil gjøre at du husker den igjen). Så tar du og går gjennom den når du får tid. Ikke la det gå mer enn noen få dager fra du får ideen til du tenker gjennom den.

En ide er gjerne en løsning på et problem eller en måte å gjøre noe på gjennom kombinasjon av noen ting. Derfor er det ikke noe overaskelse at du får de fleste ideer mens du ligger i halvsøvne om morra'n. Da er de 'vanlige' bariærene mot fantasi ikke der, og underbevistheten har 'fordrøyd' problemet du hadde i går. Da har du optimale sjanser for å finne ei løsning.

Når det gjelder problemløsing går det an å bruke dette bevisst ved å tenke på et problem rett før du sovner. Helst still deg spørsmål om problemet.

Ett lite problem med denne måten å få ideer på er at når du våkner helt og reiser deg for å få tak i papir og blyant, 'forsvinner' ideen som dugg for sola. Grunnen er at 'den virkelige verden' kommer stormende inn gjennom sansene dine og bygger opp bariærene mot fantasi igjen. Løsninga er ganske enkel, ha alltid papir og blyant innenfor rekkevidde, og skriv ideen ned mens du ligger der i halv-ørska.

En annen teknikk er å sette seg godt til rette i godstolen, lene seg tilbake og høre på musikk. Først blir du avslappet, og så kommer du på en masse småting du har å gjøre. Ikke reis deg, men bare sitt og hør på musikken, du har masser av tid til å gjøre de småtingene senere en gang.

Etter ei stund kan du få ideer om ting du lage eller som du mener kunne vært gjort bedre enn det du har sett fra før. Nå kommer ideene strømmende på...


Programmeringsfilosofi.

Dataorientert:
I den elektroniske datamaskinas steinalder (etterkrigstida), fantes det ikke noen programmeringsspråk. Å programmere ei datamaskin var en nitidig prosess som tok lang tid og nøye planlegging. I den tida var minne mangelvare (type 1k var luksus), og disk fantes ikke (hullbånd derimot...). Prosessorene var veldig trege (etter dagens standarder) og derfor var det veldig viktig å være 'snill' med maskina og ikke gjøre mere enn akkurat det som var nødvendig. På grunn av plassproblemene ble det lagt stor vekt på at størrelsen på programmet skulle være minst mulig. Data ble satt i sentrum. Dette var mest fordi oppdragene var 'data'-orienterte. I denne tida var det viktigst å programmere så maskinytelsen var optimal.

Funksjonsorientert
Etterhvert som minne ble billigere og lagerplassen større, ble det lagt mere vekt på funksjonalitet og gjenbruk av kildekode. Strukturert programmering kom som et svar på vansklighetene med å holde styr på større programmeringsprosjekt. Funksjonsorienterte språk ble utviklet og forbedret, men fremdeles sto data høyt på lista over viktige ting å tenke på.

Objektorientert
I det siste har det blitt viktigere å få laget en riktig modell av problemet enn å lage programmet maskin-effektivt. Data har fått en mye mindre rolle i denne filosofien enn i de forrige og det er lagt mer vekt på å gi programmøren bedre hjelpemidler.


Midt om natten...

Noen folk klager over at de får vondt i hodet av å sitte foran datamaskina i lengre tid. En god del av disse får ikke vondt av den grunnen, men av at de ikke drikker nok væske. Du mister væske ganske fort foran en dataskjerm pga den statiske elektrisiteten (lufta blir ofte tørr og full av støv). Derfor bør du drikke litt hele tida når du sitter og jobber. En halv liter i timen er sån passe, men det skader ikke å drikke mer.

Det er ikke rart at ingen kan finne ei sittestilling som er perfekt. Da sitter du i ro, og en eller annen del av kroppen får langvarig belastning, og en annen del får lite blod. Dessuten er det tungt for hjertet når du sitter lenge i samme stilling fordi ingen andre muskler hjelper til med å pumpe blodet. Dette kan du hjelpe på ved å puste riktig, strekke deg, variere sittestillinga di og gå deg en liten tur nå og da.

Det går veldig hardt på tennene å sitte oppe natta over fordi du spiser noe og skipper tannpussen. Tannleger kan nok være sympatiske folk, men jeg har ikke spesiel lyst til å avlegge visitt, så jeg har tannkost etc i skapet på skolen (siden jeg er mest her likevel mener jeg... ;-).

Hvis du skal sitte oppe ei heil natt kan en i nødsfall overleve rimelig bra på noe som:

  • stiller sultfølelsen. (en pose med noe salt)
  • gir deg energi, eller rettere: blodsukker. (søtsaker)
  • holder deg våken. (sterk smak, koffeinholdig drikke)

    Hvis jeg har nødt til å være oppe ei natt og matsjappene har stengt, kjøper jeg som regel en pose baconcrisp, en sjokolade og 1 1/2 liter Cola. Det er viktig at du ikke tyler i deg hele sjokoladen på en gang, men 'sprer' den utover natta. Da vil du holde blodsukkeret oppe mye lenger.


    Viktigheten av å være nøyaktig.

    Når det er en ting du ikke forstår er det ofte fordi det er en ting du har oversett. Når du formulerer et spørsmål tvinger du deg selv til å tenke gjennom hva som skal skje, men hva du tenker er avhengig av nøyaktigheten på spørsmålet. En formulering som "Hva er feil (med det derre)?" vil som regel ikke gi noe vettugt svar. "Hvorfor blir denne delen aldri utført?" har mer detalj og krever at du tenker gjennom problemet mer strukturert, derfor er den formuleringen bedre. Nesten bestandig gjelder at jo mer nøyaktig du er, dess fortere finner du feilen.

    Hvis du ikke er av den typen som kan kompilere et program i hodet bør du også være nøye når du setter navn på funksjoner, variabler, konstanter osv. Navn på en funksjon skal si akkurat hva den gjør. Ikke hvordan, ikke hvorfor men eksakt hva. På samme måte skal du gi navn på variabler. Spørsmålet du skal stille er "Eksakt hva er denne variablen?".

    Generelt skal funksjonsnavn være i imperativ (en komando), og variabler, konstanter, klassenavn etc skal være substantiv. Navnet på en boolsk variabel bør være et logisk uttrykk. 'Fortsett' eller 'Funnet' er typisk bra navn, mens, 'Ok' og 'Sant' er dårlige navn.

    Hvis du er konsekvent med alle navn, får du en ekstra bonus. Da trenger du ikke å lete etter en funksjon for å se hvordan den skrives. Det er bare å skrive hva du vil ha gjort på 'navneform'. Det samme gjelder for variabler og konstanter.

    Hvis du er nøye med navngiving vil du se at det blir mye mindre feil når du kompilerer. Dette er fordi det du skriver gir deg en mening, og ikke bare er noen funksjoner og variabler med tilfeldige navn som s3 eller haha4.


    Kommentarer

    Det finnes to slags kommentarer: de som er beskrivende og de som er forklarende. De skal bestå av vanlig tekst. De beskrivende står først i ei fil og forran funksjoner. De står helst utenfor kildekoden og skal være supplement til funksjons- eller klassenavnet. De andre er der for å forklare ting som er vanskelige å forstå. Et uttrykk som ser slik ut (C):

      k = (i==1)<< + (i==3)<< << - !(i==3 || i==1)*7.14;
    
    bør ha en forklarende kommentar, mens
    if (i==1)
    	k = 2;
    else if (i==3)
    	k = 4;
    else
            k = -7.14;
    
    ikke trenger det (begge uttrykkene gjør det samme).

    Eksempel på beskrivende kommentar er noe slikt:

    /*
     * File         : streng.h
     * Purpose      : Lage en strengtype som er mer robust og enklere
     *                å håndtere enn standard strenger
     * Language     : C++
     * Author       : Per Gunnar Hansø, pergh@colargol.stud.idb.hist.no
     * Edited by    :
     *              :
     *              :
     * Last changed : 24.01.95
     * Comments     : Er ikke helt ferdig enda.
     */
    
    
    Hvis du har tenkt å gjøre noe seriøs programmering bør du lage deg noe slikt som du legger i hver fil du lager (den 'Edited by' kan du egentlig skippe). Det skader ikke om du lager en slik til å ha foran funksjoner heller:
    //---------------------------------------------------------------------
    // Setter pekeren Aktuell til å peke på neste element hvis det finnes.
    // Returnerer 1 hvis Aktuell ble forandret, 0 ellers.
    // 
    


    Latskap er roten til alt godt.

    Den som er lat av natur har en fordel framfor andre programmører. Han eller hun vil gjøre hva som helst for å slippe å gjøre noe som helst. Dvs at han (eller hun) vil prøve å finne nye og enklere måter å få ting gjort på.

    En måte å 'spare arbeid' på er å lage funksjoner generelle og putte dem i et bibliotek . En annen ting er å finne tak i kildekode andre har laget og bruke det. Da skal en la den som har laget det stå som 'Author' og sette seg selv under 'Edited by'.

    I følge Larry Wall, er det tre ting som skiller en god programmør fra en middelmåtig:

    1. Latskap
    2. Utolmodighet
    3. Stolthet


    Debugging

    Du kan aldri garantere at et program er 100% feilfritt. Det sies at et feilfritt program er et utdatert program.

    Det finnes to hovedtyper av feil: logiske- og programmeringsmessige feil. Logiske feil er som regel de vanskeligste å finne, for du får ikke annen feilmelding enn den som brukeren forteller deg.

    Den beste måten å fjerne feil på er å la være å lage dem. Dette gjør du ved å følge en programmeringsstil, være konsis med navn, ha gode rutiner, bruke kildekode du har brukt og debugga før, evt noe som er ferdilaga og debugga av andre.

    Kompileringsfeil

    Disse angies med linjenummer, så de er relativt lette å finne. Det en skal være oppmerksom på er at feilen ligger en annen plass en der kompilatoren tror. Den ligger forsåvidt alltid før kompilatorfeilen og er oftest manglende sluttparantes.

    Unexpected end of file

    Du har glemt av å av å slutte ei blokk med } eller noe slikt. Denne kan være gjenglemt i ei fil du har inkludert også.

    En bug i Visual C++ gjør at du må ha et linjeskift helt på slutten av alle .cpp filer.

    Local functions not supported

    Du har glemt en } i funksjonen over.

    Modifiers not allowed on non member functions

    Du har glemt en ; i funksjonen over.

    Bad magic number

    Når du kompilerer på UNIX må du ha et gyldig suffiks på filene du kompilerer. Gyldige suffiks for C++ er .cc, .cxx og .C.

    Function should return a value

    Du får feilen selv om du har en return til slutt. Du har glemt en { i en konstruksjon ovenfor.

    Linkerfeil

    Unresolved external

    Vanligvis en av tre ting:

    1. Skrivefeil enten i funksjonsdefinisjonen eller -deklarasjonen.
    2. Du har inkludert ei .h-fil, men ikke den tilhørende .cpp-fila.
    3. Det mangler en path til bibliotek-funksjonene til linkeren.

    Kjøretidsfeil

    Stack overflow

    Du har en 'uendelig' rekursiv funksjon eller flere funksjonskall der det er alt for mye data som overføres.

    Logiske feil

    Her er det ingen standard måte å finne fram til feilen på. En metode kan være å ta utskrift av den delen av programmet som feiler, og gå gjennom kildekoden samtidig som du kjører programmet.

    En annen god måte å finne feilen på er å bruke debugger. En god debugger vil være til stor hjelp hvis du lærer deg å bruke den.


    Gode vaner

    Lag funksjoner, ikke prosedyrer. Funksjoner er mer anvendelige fordi de kan brukes direkte i uttrykk. En prosedyre vil være det samme som en funksjon med returverdi void.

    En funksjon skal gjøre bare en oppgave. Da blir koden din mye mer fleksibel og generel.

    Dess kortere du lager funksjonene dine, dess enklere er det å bruke dem igjen senere. Dessuten gjør du mindre feil hvis funksjonen er på få linjer.

    Variabler skal alltid ha lovlige verdier. Helst skal de også ha fornuftige verdier. Dette gjør du best vet å initialisere alle variablene du lager med verdien de skal ha. Hvis du gjør dette bestandig, vil det bli mye enklere å finne feil i programmene dine.

    Når du allokerer minne dynamisk skal du alltid ha en sjekk på om du fikk det minnet du spurte etter. Hvis du ikke gjør det, vil programmet ditt en eller annen gang gå rett til nordpolen.

    Hvis det er mulig bør du frigjøre minnet på samme nivå som du satte det av. Da blir det enkelt å unngå minnelekasjer. Hvis du ikke har muligheten bør du kommentere det.


    Hjelp på forskjellige ting.

    I Visual C++ og Borland C++ har en den eminente F1. Kombinert med enten ctrl eller alt, får du rimelig kjapt hjelp.

    Under Unix er saken litt anderledes. Det første en prøver der, er man-sidene. Disse inneholder info om det meste som er på Unix, bl.a. systemkall, kommandoer, info om spesielle filer etc. Prøv 'man man' for mer info.

    Men du har mere snacks på Unix. Hvis du fx lurer på hvilken fil du skal inkludere for å få bruke en standardfunksjon, kan du ta en

    grep funksjon\( /usr/include/*
    
    eller du kan (for å finne ei spesiell fil fra der du står) skrive
    find . -name navn -p
    

    Dessuten er det masse andre ting på nettet som kan hjelpe deg med å løse problemer av forskjellige slag. En god startplass er news. Her kan du finne slike newsgrupper som comp.lang.c++ og comp.unix.programmer og mange fler. Før du bare kaster deg inn i en newsgruppe og roper hjelp, bør du ta en kikk på nettiketten. Hver av disse newsgruppene har sin egen FAQ. comp.lang.c++ har for eksempel denne FAQ 'en.

    På Web finns det også masse kule ting. En kan jo ta et lite søk i et C++-kurs eller noe slikt. Det kan også la seg gjøre å bruke et søkeverktøy for å finne slike resurser på nettet.

    Hvis alt annet feiler, kan du jo prøve å få litt hjelp fra biblioteket til Orakel. Ellers kan du jo ta en titt i vedleggene i boka, eller du kan gå videre ut (av byggningen) og prøve biblioteket i Gunnerudsgt, Hovedbiblioteket eller kanskje helst Universitetsbiblioteket rett borti striten her (ved siden av Vitenskapsmuseet). Hvis du er skikkelig i beit for hjelp, så kan du jo dra på Walseth eller Tapir og se om det finnes ei skikkelig bok om emnet der.

    Bortsett fra slike skrevne kilder, finnes det jo også folk her på bygget som kan hjelpe. Ikke bare lærere, men også studentassistenter og Orakel.

    
    Hva som er under skriving:
    
    Portabel kode
     - hvordan skrive
     - hvorfor skrive?
    
    Gode programmeringsregler for C++
    
    Shotgun debugging (1)
    
    lage en #include med det samme du bruker en funksjon inni der
    
     
    Ting som hører logisk sammen bør samles på ett sted. (ei fil eller directory)
    
    
    
     - defines-triks
    #define vector vector
    #ifdef DEBUG
     - effektivitet
    
    bruk av browsere og indent
    
    Hvis en bruker klarer å kræsje programmet ditt.. er det du som ikke
    har gjort godt nok arbeide.
    
    Plassering av konstanter, typer, variabler, funksjoner etc
    
    Prosjekt/Makefile
    Enkel forklaring på hvordan en bruker make og 
    et newsinnlegg med eksempel på makefil.
    
    lage guestbook av dokumentet her så alle kan skrive inn sine tips...
    
    Forskjell på kompilatorer, parameterrekkefølge etc
    
    skille mellom programmerer og bruker. 
     - unngår omkompilering ved testing.
     - får bedre program.
    
    Debug-level (1-9)
    
    Optimaliserings-side:
    Ting som ikke er 'pene' å gjøre
    
    Rekursjon er å legge til sides midlertidige data (utregninger), og regne
    ut når vi har et overkommelig problem.
    
    Rekursjon er å dele opp et problem til vi står igjen med noe vi kan å løse.
    
    


    Made avaliable by Per Gunnar Hansø
    Updated: 16.3.98.