Scripting. Opslag til (Vol. D. Dahlerup. Bemærk. Anvendte bøger: "Sams. og proteiner.

Relaterede dokumenter
METODER ARV KLASSER. Grundlæggende programmering Lektion 5

Software Construction 1 semester (SWC) Spørgsmål 1

Software Construction 1. semester (SWC) januar 2014 Spørgsmål 1

Online kursus: Programming with ANSI C

AAU, Programmering i Java Intern skriftlig prøve 18. maj 2007

Kursusarbejde 3 Grundlæggende Programmering

Klasser og objekter. (Afsnit i manualen)

Eksempel: Skat i år 2000

Kursusarbejde 2 Grundlæggende Programmering

Ugeseddel 4 1. marts - 8. marts

Programmering i C. Lektion september 2009

Programmering for begyndere Lektion 2. Opsamling mm

Den forudsætter kendskab til C++ og lidt kendskab til SQL og MySQL C API.

Programmering i C. Lektion september 2009

Programmering i C Intro og grundlæggende C 5. marts 2007

Forelæsning Uge 4 Mandag

DANMARKS TEKNISKE UNIVERSITET

SWC eksamens-spørgsmål. Oversigt

DM507 Algoritmer og datastrukturer

Metoder Klasser Arv. Operatorer Løkker. Praksis eksempel. Grundlæggende programmering Lektion 3

DM507 Algoritmer og datastrukturer

Programmering i C. Lektion september 2009

Programmering i C. Lektion december 2008

Lige siden den elektroniske computers opfindelse i slutningen af 1940, har det været muligt at få en computer til at beregne ting.

PHP 3 UGERS FORLØB PHP, MYSQL & SQL

DM507 Algoritmer og datastrukturer

Start på Arduino og programmering

#AlleKanKode. Lektion 2 - Konstanter og Variabler

Forelæsning Uge 2 Torsdag

HTX, RTG. Rumlige Figurer. Matematik og programmering

Kursusarbejde 1 Grundlæggende Programmering. Arne Jørgensen, klasse dm032-1a

Programmering i C. Lektion november 2008

Forelæsning Uge 2 Mandag

Lektion 6. Grundlæggende programmering i VR

Aarhus Universitet, Science and Technology, Computer Science. Exam. Wednesday 27 June 2018, 9:00-11:00

Andreas Lauge V. Hansen klasse 3.3t Roskilde HTX

Python programmering. Per Tøfting. MacFest

Forelæsning Uge 4 Mandag

Systemkald DM Obligatoriske opgave. Antal sider: 7 inkl. 2 bilag Afleveret: d. 18/ Afleveret af: Jacob Christiansen,

Internt interrupt - Arduino

Datalogi OB, Efterår 2002 OH er, forelæsning 10/ Klasser og nedarvning

Programmering i C Videre med C (2 af 4) 19. marts 2007

Objektorienteret Programmering

Programmering C RTG

Programmering i C. Lektion oktober 2008

Klasser og nedarvning

Udvikling af DOTNET applikationer til MicroStation i C#

LØKKER METODER C S HISTORIE. Grundlæggende programmering Lektion 4

Project Step 7. Behavioral modeling of a dual ported register set. 1/8/ L11 Project Step 5 Copyright Joanne DeGroat, ECE, OSU 1

Tilfældige tal. Denne artikel introducerer generering af tilfældige tal og viser lidt om hvad man kan og ikke mindst hvad man ikke bør bruge.

b) Udvid din implementation af forme til at understøtte.equals. To objekter af samme form er ens hvis de har samme værdier i felterne.

Privat-, statslig- eller regional institution m.v. Andet Added Bekaempelsesudfoerende: string No Label: Bekæmpelsesudførende

Spil Master Mind. Indledning.

Pointers. Programmering i C. 11. december Lektion 5. Eksempel: denne plads. Getting the address of a variable:

Design by Contract Bertrand Meyer Design and Programming by Contract. Oversigt. Prædikater

Online kursus: C++ Programming

Abstrakte datatyper C#-version

DM507 Algoritmer og datastrukturer

Forelæsning Uge 4 Mandag

Skriftlig eksamen i Datalogi

SWC Elementer i klassedefinition

#AlleKanKode. Lektion 4 - Kontrol flow

Indledning. Hvorfor det forholder sig sådan har jeg en masse idéer om, men det bliver for meget at komme ind på her. God fornøjelse med læsningen.

Arduino Programmering

#AlleKanKode. Lektion 3 - Operatorer

Forelæsning Uge 4 Torsdag

WT-1011RC Programmer User Guide

Løsning af skyline-problemet

Microcontroller, Arduino

Dokumentation af programmering i Python 2.75

Undtagelseshåndtering i C#

PARALLELIZATION OF ATTILA SIMULATOR WITH OPENMP MIGUEL ÁNGEL MARTÍNEZ DEL AMOR MINIPROJECT OF TDT24 NTNU

Studiepraktik. Thomas Bøgholm Mikkel Hansen Jacob Elefsen

Hvilket sprog er hurtigst

Sekvensafstand DM34 - Eksamensopgave. Jacob Aae Mikkelsen

Opsætning af Backup. Hvis programmet registreres korrekt vises nedenstående skærmbillede. Genstart herefter programmet.

DM507 Algoritmer og datastrukturer

MS Visual Studio Basic En kort vejledning

Projekt arbejde til kurset Advanced Models and Programs, SASP-AMP 2008 Poul Brønnum, IT Universitetet i København, Maj Indholdsfortegnelse

Tree klassen fra sidste forelæsning

Introduktion til funktioner, moduler og scopes i Python

Klasse 1.4 Michael Jokil

Programmering. Det rent og skært nødvendige, det elementært nødvendige! Morten Dam Jørgensen

! #!! $ % $! & " &'"! & *+ "! " $ $ ""!,-! $!.! $! " # 1!! &' "

Sproget Rascal (v. 2)

Videregående Programmering for Diplom-E Noter

Opsætning af Backup. Dette er en guide til opsætning af backup med Octopus File Synchronizer.

Forelæsning Uge 3 Mandag

Polymorfi. Arv (inheritance) Abstrakte klasser, substitutionsprincippet, overriding, statisk og dynamisk type. Coercion

Lær Python dag 1 - modul 1

Forelæsning Uge 2 Mandag

Forelæsning Uge 4 Torsdag

% &$ # '$ ## () %! #! & # &, # / # 0&. ) / & #& #

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { int wmid, wmevent; programmering med

Kursusarbejde 4 Grundlæggende Programmering

Operation Manual SMS Air Conditioner Remote Controller Model No.: SR-001

Mircobit Kursus Lektion 1

Java Programmering. En bog for begyndere. Skrevet af Henrik Kressner

ATTRIBUTES MULTITHREADING DYNAMIC PROGRAMMING. Grundlæggende programmering Lektion 11

30 Objekt-orienteret Programmering i Andre Sprog.

Transkript:

Bioinformatisk C++ Scripting i Xubuntu Vol. 2 Opslag til Dybdegående Bioinformatisk Scripting i Xubuntu 12.10 (Vol. 2) Henrik D. Dahlerup, Maj 2015 kontakt: henrik@ddahlerup.com Anvendte bøger: "Sams Publishing"-books. Bemærk - Nye programmeringssprog, så som C++, er i dag genkendt af flere som yderst anvendelig til størrere bioinformatiske opgaver. På trods af dette findes der ikke litteratur som helt konkret - ned i detaljer - viser eksempler på disse muligheder. Dette er muligvis fordi udviklingenn af dette sprog går så stærkt, at hvad var foreslået i går, er meget mindre effektivt i dag. Dette dokument vil, på trods af dette, bidrage med konkrete ned-i-detaljer-eksempler. Alt dette bliver her udført i Xubuntu C++ version 4.6.3. Udover dette er der mange steder anvendt talesprog hvor der ikke tages hensyn til den bioinformatiske termologi. Dennee tilgang har til hensigt at gøre det nemmere at gennemskue den praktiske værdi af disse til tider abstrakte bioinformatiske værktøjer - brugt til at analysere DNA, RNA og proteiner. Copyright 2014 Henrik D. Dahlerup

Indhold Overblik og opsamling i en ny vinkel... 3 Typer og objekter brugt i C++ programmering... 3 Brugen af funktioner og klasser... 14 Konkret programmering i C++... 39 Effektivt brug af funktioner... 40 Objekt-orienteret struktur... 75 Implementering af inheritance... 83 Avanceret brug af arrays... 114 Strukturen som skaber polymorfisme... 145 Overblik... 179 Debug dine C++ scripts... 208 Anvendelse - Her er brugt simple og meget praktiske forklaringer som gør det nemt at forklare det fremlagte videre til andre, uden at tale forbi dem - hvis du for eksempel er hjælpelærer på et bioinformatisk kursus eller lignende. 2

Overblik og opsamling i en ny vinkel Her er en hurtig og konkret beskrivelse af udvalgte redskaber anvendt under bioinformatisk scripting i C++. Nye meget anvendelige metoder og vinkler er til stede i dette kapitel, men du kan nemt skippe dette kapitel hvis du ønsker at undgå gentagelser. Siden scripts bruger amerikansk punktum- og komma-notation, er det samme anvendt i teksten af dette dokument. Typer og objekter brugt i C++ programmering Her introduceres de grundlæggende typer og objekter brugt i C++ programmer. Et program kan bruge flere forskellige redskaber (data'er) til at løse et givet problem, for eksempel, karakterer, integers eller floating-point numre. Siden en computer bruger forskellige metoder til at behandle og gemme data på, må selve data-typen være kendt. Selve typen definer: Den indre repræsentation af data (For eksempel sandt er 1 og falskt er 0). Mængden af hukommelse der skal allokeres. C++ compiler'en genkender de forskellige built-in typer som alle andre typer (vektorer, pointers, klasser,...) er baseret på. Type-bool Resultatet som du opnår, når du laver en sammenligning eller en logisk kobling ved at bruge AND eller OR er en boolean værdi, som kan være sand eller falsk. C++ bruger bool-typen til at repræsentere boolean-værdier. En ekspression af type-bool'en kan enten være sand eller falsk, hvor den indre værdi for sand vil blive repræsenteret som en numerisk værdi 1 og falsk via et nul. char og wchar_t typer Disse typer er brugt til at gemme karakter-koder. En karakter-kode er faktisk en integer koblet med hver karakter. Bogstavet A er repræsenteret af koden 65, som et eksempel. Karakter-sættet definer hvilken kode der repræsenter en specifik karakter. Når karakterer vises på skærmen, er den pågældende karakter-kode brugt og modtageren som er skærmen, har netop ansvaret for at tolke koden korrekt. C++ sproget bruger ASCII kode. Denne 7-bit-kode indeholder netop definitioner for 32 kontrolkarakterer (koderne 0 31) og 96 printbare karakterer (koderne 32 127). char (character)-typen er brugt til at lagre karakter-koder i en byte (8 bits). Dette antal af bits som lagres er faktisk nok til udvidede karakter-sæts, som for eksempel, ANSI karakter-sættet der indeholder ASCII koden og yderligere karakterer så som tysk 'umlaut'. wchar_t (wide character type) typen giver, på samme måde, mindst 2 bytes (16 bits) og er derfor i stand til at lagrer moderne Unicode-karakterer. Unicode er en 16-bit kode også brugt i Windows og den indeholder kode for cirka 35,000 karakterer i 24 sprog. Et program som output'ter værdien for specifikke konstanter. #include <iostream> #include <climits> // Definition of INT_MIN,... using namespace std; int main() 3

Et eksempel på at declare funktioner: int toupper(int); double pow(double, double); Dette informer faktisk compileren om at funktionen toupper() er af typen int, som betyder at dens returnerings-værdi er af typen int og at compileren netop forventer et argument af typen int. Den anden funktion er pow() og er af typen double. Her skal to argumenter af typen double pass'es til funktionen når den er call'et. Typerne af argumenterne kan faktisk blive efterfulgt af navne. Dog, er navnene kun opfattet som kommentarer af compileren. Et eksempel på at declare funktioner: int toupper(int c); double pow(double base, double exponent); Fra compiler'ens synspunkt er disse prototyper faktisk ens med prototyperne i det forrige eksempel, netop fordi begge junctions (mellemled) er standard-junctions. Husk, at standard funktionsprototyper skal ikke declares for det er de allerede blevet i standard-header-filerne. Hvis headerfilen er inkluderet i programmernes source kode via et #include directiv, kan funktionen faktisk blive brugt med det samme. Et eksempel på at declare funktioner: #include <cmath> Følgende direktiv, som er de matematiske standard funktioner så som sin(), cos() og pow(), er tilgængelige her. Et program som viser funktions-calls. // Calculating powers with // the standard function pow() #include <iostream> // Declaration of cout #include <cmath> // Prototype of pow(), thus: // double pow( double, double); using namespace std; int main() { double x = 2.5, y; // By means of a prototype, the compiler generates // the correct call or an error message! // Computes x raised to the power 3: y = pow("x", 3.0); // Error! String is not a number y = pow(x + 3.0); // Error! Just one argument y = pow(x, 3.0); // ok! y = pow(x, 3); // ok! The compiler converts the // int value 3 to double. cout << "2.5 raised to 3 yields: " << y << endl; // Calculating with pow() is possible: cout << "2 + (5 raised to the power 2.5) yields: " 15

36: 37: Cat::~Cat() 38: { 39: delete itsage; 40: itsage = 0; 41: delete itsweight; 42: itsweight = 0; 43: } 44: 45: int main() 46: { 47: Cat Frisky; 48: cout << "Frisky's age: " << Frisky.GetAge() << endl; 49: cout << "Setting Frisky to 6...\n"; 50: Frisky.SetAge(6); 51: cout << "Creating Boots from Frisky\n"; 52: Cat Boots(Frisky); 53: cout << "Frisky's age: " << Frisky.GetAge() << endl; 54: cout << "Boots' age: " << Boots.GetAge() << endl; 55: cout << "setting Frisky to 7...\n"; 56: Frisky.SetAge(7); 57: cout << "Frisky's age: " << Frisky.GetAge() << endl; 58: cout << "boot's age: " << Boots.GetAge() << endl; 59: return 0; 60: } $ program2_4.cpp Frisky's age: 5 Setting Frisky to 6... Creating Boots from Frisky Frisky's age: 6 Boots' age: 6 setting Frisky to 7... Frisky's age: 7 Boots' age: 6 I linjerne 6 19 er Cat klassen declared. Bemærk at i linje 9 er en default constructor declared og i linje 10 er en copy-constructor declared. Du ved at det er en copy-constructor som er i linje 10, netop fordi constructor'en modtager en reference - en konstant-reference i denne situation - til et objekt af den samme type. I linjerne 17 og 18 er to member-variabler declared, begge to som en pointer til en integer. Typisk er der meget lidt grund til, at en klasse skal lagrer int membervariabler som pointers, men dette er gjort her for at vise hvordan du styrer member-variabler på det frie lager. Default constructor'en i linjerne 21 27 allokere plads på det frie lager til to int variabler og herefter assign'er den værdierne til dem. Copy-constructor'en starter i linje 29. Bemærk at parameteren er en rhs. Det er normalt at referer parameter'en til en copy-constructor som rhs, som står for 'right-hand side'. Når du ser på assignment'erne i linjerne 33 og 34, vil du se at objektet som er pass'et ind som en parameter er på højre-hånds side af lighedstegnet. Her er hvordan det virker: 49

parametrer ud fra typen i stedet for ud fra et tal eller bidrager med forskellige implementeringer for forskellige parameter-type-kombinationer. o Når du skriver en klasse constructor, skal du gennemskue hvad du vil sætte i initialiseringen og hvad du vil sætte i body'en af constructor'en. En tommelfingerregel er at sætte så meget som muligt i initialiserings-fasen - Det betyder, at initialisere alle member-variablerne der. Nogle ting, så som udregninger (dem inkluderet som er brugt til selve initialiseringen) og printstatement'er skal være i body'en af constructor'en. o En overloaded funktion kan have en default-parameter. En eller flere af de overload'ede funktioner kan have sin egen default-værdi ved at følge de normale regler for default-variabler i enhver funktion. o Nogle af member-funktionerne er defineret indenfor klasse deklarationen og andre er ikke. Ved at definere implementeringen af en member-funktion indenfor deklarationen udfører den inline. Generalt set er dette kun gjort hvis funktionen er ekstremt simpel. Bemærk at du kan også gøre en member-funktion inline ved at bruge nøgleordet inline, selv hvis funktionen er declared udenfor selve klasse-deklarationen. Konkrete problemer 1. Når du overload'er member-funktioner, på hvilken måde skal de så være forskellige? Overloaded member-funktioner er funktioner i en klasse som deler et navn men er forskellige i antallet eller typer af deres parametrer. 2. Hvad er forskellen imellem en deklaration og en definition? En definition sætter hukommelse til side; En deklaration gør ikke. Næsten alle deklarationer er definitioner; Den store undtagelse er klasse-deklarationer, funktions-prototyper og typedef statement'er. 3. Hvornår er copy-constructor'en call'et? Når en midlertidig kopi af et objekt er dannet. Dette sker også hver gang et objekt er pass'et med en værdi. 4. Hvornår er destructor'en call'et? Destructor'en er call'et hver gang et objekt er ødelagt, enten fordi det går ud af scope eller fordi du call'er delete på en pointer der peger til den. 5. Hvordan er copy-constructor'en forskellig fra assignment-operator'en (=)? Assignmentoperator'en agere på et eksisterende objekt; Copy-constructor'en danner et nyt objekt. 6. Hvad er this pointer'en for noget? this-pointer'en er en gemt parameter i alle member-funktioner som peger til selve objektet. 7. Hvordan skelner du imellem overloading af præfiks- og postfiks-increment-operatorer? Præfiksoperatoren tager ikke parametrer. Postfiks-operatoren tager en enkelt int-parameter, som er brugt som et signal til compiler'en om at dette er selve postfiks-varianten. 8. Kan du overload'e en operator+ for short integers? Nej, du kan ikke overload'e nogen som helst operator for built-in typer. 70

class Calendar_Class { public: Calendar_Class(); ~Calendar_Class(); void Add( const Meeting& ); // add a meeting to the calendar void Delete( const Meeting& ); Meeting* Lookup( Time ); // see if there is a meeting at the // given time Block( Time, Duration, String reason = "" ); // allocate time to yourself... protected: OrderedListOfMeeting meetings; }; class Meeting { public: Meeting( ListOfPerson&, Room room, Time when, Duration duration, String purpose = "" ); ~Meeting(); protected: ListOfPerson people; Room room; Time when; Duration duration; String purpose; }; Du kan bruge private i stedet for protected hvis du ønsker det. Implementering af inheritance Tidligere er der blevet fortalt om et antal af objekt-orienteret forhold som inkluder specialisering/generalisering. C++ implementer dette forhold igennem inheritance. Nedenfor vil der blive fortalt om: Hvordan inheritance funger. Hvordan du bruger inheritance til at aflede en klasse fra en anden. Hvad beskyttet adgang er og hvordan du bruger det. Hvad virtuelle funktioner er. Dette ved du når du har læst "Implementering af inheritance" Der er her blevet fortalt om hvordan afledte klasser arver fra basis klasser. Klassen som blev forklaret her fortæller om public inheritance og virtuelle funktioner. Klasser arver alt det fra public og det beskyttede (protected) data samt funktioner fra deres basis klasser. Beskyttet adgang er public til afledte klasser og private til alle andre klasser. Selv afledte klasser kan ikke få adgang til private data eller funktioner i deres basis-klasser. 83

For at declare en array, skriv da typen på objektet lagret efterfulgt af navnet på array'en og et subscript med nummeret på objektet som findes i array'en. Eksempel 1 int MyIntegerArray[90]; Eksempel 2 long * ArrayOfPointersToLongs[100]; For at gå ind i members af array'en, brug da subscript operatoren. Brugen af array'er indeholdende objekter Ethvert objekt, uanset om det er en built-in eller en bruger-defineret, kan blive lagret i en array. Når du declare array'en til at indeholde objekter, siger du til compileren hvilken type af objekt den skal lagrer og antallet som den skal allokere for at lave plads. Compileren ved hvor meget plads der er brug for til hvert objekt baseret på klasse-deklarationen. Klassen skal have en default constructor som ikke tager argumenter så objekterne kan blive dannet når array'en er defineret. Det at gå ind i member-data i en array med objekter er en to-trins proces. Du identificer member'en af array'en ved at bruge indeks-operatoren ([ ]) og så indsætter du member-operatoren (.) for at kunne gå ind i den specifikke member-variabel. Opstillingen nedenfor viser hvordan du ville danne og gå ind i en array med fem Catte. Et program som danner en array af objekter. 0: // An array of objects 1: 2: #include <iostream> 3: using namespace std; 4: 5: class Cat 6: { 7: public: 8: Cat() { itsage = 1; itsweight=5; } 9: ~Cat() {} 10: int GetAge() const { return itsage; } 11: int GetWeight() const { return itsweight; } 12: void SetAge(int age) { itsage = age; } 13: 14: private: 15: int itsage; 16: int itsweight; 17: }; 18: 19: int main() 20: { 21: Cat Litter[5]; 22: int i; 23: for (i = 0; i < 5; i++) 24: Litter[i].SetAge(2*i +1); 25: 120

164: cout << "S1[999]:\t" << s1[999] << endl; 165: 166: String s2(" Another string"); 167: String s3; 168: s3 = s1+s2; 169: cout << "S3:\t" << s3.getstring() << endl; 170: 171: String s4; 172: s4 = "Why does this work?"; 173: cout << "S4:\t" << s4.getstring() << endl; 174: return 0; 175: } $ program5_14.cpp S1: initial test S1: Hello There temptwo: ; nice to be here! S1: Hello There; nice to be here! S1[4]: o S1: Hellx There; nice to be here! S1[999]:! S3: Hellx There; nice to be here! Another string S4: Why does this work? Din String klasses deklaration er i linjerne 7 31. For at tilsætte fleksibilitet til klassen, er der 3 constructor'er i linjerne 11 13: Default constructor'er, copy-constructor'er og en constructor som tager en eksisterende null-termineret (C-style) string. For at tillade at brugerne nemt kan manipulere strings, overload'er denne String-klasse flere operatorer der inkluder offset operatoren ([ ]), operatoren plus (+), og operatoren plus-ligmed (+=). Offset operatoren er overloaded to gange: En gang som en konstant-funktion der returner en char og igen som en ikke-konstant-funktion der returner en reference til en char. Ikke-konstant-versionen er brugt i statement'erne så som: S1[4]='x'; som set i linje 161. Dette giver direkte adgang til hver af karakterne i string'en. En reference til karakteren er returneret sådan så den call'ende funktion kan manipulere den. Den konstante version er brugt når der er gået ind i et konstant String objekt, så som i implementeringen af copyconstructor'en der starter i linje 63. Bemærk at rhs[i] er der gået ind i, dog er rhs declared som en const String &. Det er ikke tilladt at gå ind i dette objekt ved at bruge en ikke-konstant member funktion. Derfor skal offset operatoren være overloaded med en konstant accessor. Hvis objektet som der bliver returneret er stort, skal du declare returnerings-værdien til at være en konstant reference. Dog, netop fordi en char kun er 1 byte, vil der ikke være nogen ide med at gøre dette. Default constructor'en er implementeret i linjerne 34 39. Den danner en string vis længde er 0. Det er konventionen for denne String klasse at rapporter dens string uden at tælle de terminerende null'er. Denne default string indeholder kun et terminerende null. Copy-constructor'en er implementeret i linjerne 63 70. Denne constructor sætter den nye string's længde til det samme som den eksisterende string - plus en til det terminerende null. Den kopierer hver karakter fra den eksisterende string til den nye string og den null-terminere den nye string. Husk at afvigende fra assignment-operatorer, har copy-constructor'er ikke brug for at teste om string'en, som bliver kopieret ind i dette nye objekt, er den selv - dette kan nemlig aldrig ske. 140

293: pl.insert(ppart); 294: } 295: } 296: pl.iterate(); 297: return 0; 298: } $ program7_1.cpp (0)Quit (1)Car (2)Plane: 1 New PartNumber?: 2837 Model Year? 90 (0)Quit (1)Car (2)Plane: 2 New PartNumber?: 378 Engine Number?: 4938 (0)Quit (1)Car (2)Plane: 1 New PartNumber?: 4499 Model Year? 94 (0)Quit (1)Car (2)Plane: 1 New PartNumber?: 3000 Model Year? 93 (0)Quit (1)Car (2)Plane: 0 Part Number: 378 Engine No.: 4938 Part Number: 2837 Model Year: 90 Part Number: 3000 Model Year: 93 Part Number: 4499 Model Year: 94 Opstillingen ovenfor viser implementeringen af en linket liste for Part objekter. En linket liste er en dynamisk data struktur; Det betyder at den er ligesom en array men den er tilpasset til at passe løbende som objekter er tilsat eller fjernet. Linket lister inkluder også pointers til objekter på samme tid for at få koblet objekterne sammen. Denne specifikke linket liste er designet til at indeholde objekter af klassen Part, hvor Part er en abstract-data-type der funger som en basis klasse til ethvert objekt indeholdende et del-nummer. I dette eksempel, Part er blevet under-klasse-indelt ind i CarPart og AirPlanePart. Klassen Part er declared i linjerne 27 37 og indeholder et del-nummer og nogle accessors. Det forventes at denne klasse kan blive opdelt til at kunne indeholde andre vigtige informationer om delene, så som hvilke komponenter de er brugt i og hvor mange er der i beholdningen og så videre. Part er en abstract-data-type, styret af den rene virtuelle funktion Display(). Bemærk at Display() har en implementering i linjerne 41 44. Det er designernes intention at afledte klasser vil blive styret til at danne deres egne Display() metoder, men de kan dog også chain up (indgå i kæden) til denne metode. To simple afledte klasser, CarPart og AirPlanePart, er bidraget i linjerne 48 60 og 70 82. Hver bidrager med en overskrevet Display() metode, som faktisk chain up til basis-klassen Display() metoden. Klassens PartNode i linjerne 90 101 funger som interfacet imellem Part klassen og PartList klassen. Den indeholder en pointer til en del og en pointer til det næste mellemled i listen. Dens eneste metode er at modtage og sætte det næste mellemled på listen og at returner Part hvortil den peger. Informationerne fra listen er placeret korrekt i klassen PartsList, vis deklaration er i linjerne 133 148. PartsList indeholder en pointer til det første element på listen (phead) og bruger den til 186

87. Old value = 0 88. New value = -1 89. 0x08048654 in factorial (n=-1) at main.cpp:20 90. 20 while(n--) 91. (gdb) 92. Continuing. Nu bliver n til -1 og loop'et har ikke tilladelse til at køre igen fordi n-- returner 0 og funktionen returner resultatets aktuelle værdi 0. Lad os se hvad der sker når funktionen exit'ter. 93. 94. Watchpoint 2 deleted because the program has left the block in 95. which its expression is valid. 96. 97. Watchpoint 3 deleted because the program has left the block in 98. which its expression is valid. Her er hvad der sker med et watchpoint når variablen går ud af scope. 99. 0x08048605 in main () at main.cpp:11 100. 11 long val=factorial(n); 101. (gdb) print val 102. $1 = 1293357044 print val viser en affalds-værdi fordi gdb peger til en linje før den er executed og ikke efter. 103. (gdb) next 104. 12 cout<<val; 105. (gdb) continue 106. Continuing. 107. 0[Inferior 1 (process 2499) exited normally] 108. (gdb) quit Her er hvordan løsning bør se ud: 1 while(n>0) //doesn't let n reach 0 2 { 3 4 result*=n; n--; //decrements only after the evaluation 5 } GDB indeholder mere hjælp Husk at GDB indeholder et hælpe-system. Du indtaster help i (gdb) prompten og du vil blive præsenteret for muligheder som du kunne få brug for. For at få detaljer om en specifik kommando, brug da følgende syntaks: help <command> Du kan også bruge genveje så som 'q' for 'quit'. 213