Föreläsning 3: Vector och struct



Relevanta dokument
TDIU01 - Programmering i C++, grundkurs

TDIU01 - Programmering i C++, grundkurs

( ostream ) << ( annan datatyp ) : ostream

Föreläsning 5: Rekursion

TDIU01 - Programmering i C++, grundkurs

C++ - En introduktion

Skizz till en enkel databas

Du ska nu skapa ett litet program som skriver ut Hello World.

Träning i bevisföring

Vi skall skriva uppsats

TDDC76 - Programmering och Datastrukturer

ELEV- HANDLEDNING (Ansökan via webben)

TDIU01 - Programmering i C++, grundkurs

ANVÄND NAVIGATIONEN I CAPITEX SÄLJSTÖD

Lathund till Annonsportalen

Tentamen i Programmering grundkurs och Programmering C

FRÅN A TILL Ö LäraMera Ab / och Allemansdata Ab / FRÅN A TILL Ö

Efter att du har installerat ExyPlus Office med tillhörande kartpaket börjar du med att göra följande inställningar:

Webb-bidrag. Sök bidrag på webben Gäller från

ANVÄNDARHANDLEDNING FÖR

Algebra, polynom & andragradsekvationer en pampig rubrik på ett annars relativt obetydligt dokument

Idag. Hur vet vi att vår databas är tillräckligt bra?

TIMREDOVISNINGSSYSTEM

TDDC76 - Programmering och Datastrukturer

Lathund, procent med bråk, åk 8

Lathund för överföring av rapporter och ljudfiler

7. SAMHÄLLSORIENTERING ÅK 5

Avsikt På ett lekfullt sätt färdighetsträna, utveckla elevers känsla för hur vårt talsystem är uppbyggt samt hitta mönster som uppkommer.

Instruktioner för beställning och kontoadministration för abonnenter av inlästa läromedel

TDDC76 - Programmering och Datastrukturer

Manual för Min sida 1/ rev

Hur du arbetar med VFU-portfölj i Mondo. en lathund för student

VÄRDERINGSÖVNINGAR. Vad är Svenskt?

Att komma igång. Vad är ett program? Kompilerande-Interpreterande Programmeringsmiljö Hello World! Att programmera och ett enkelt program

Visma Proceedo. Beställa IT-produkter - beställare. Version 2.0 /

Kampanj kommer från det franska ordet campagne och innebär att man under en tidsbegränsad period bedriver en viss verksamhet.

Sammanfatta era aktiviteter och effekten av dem i rutorna under punkt 1 på arbetsbladet.

Datorövning 2 Statistik med Excel (Office 2007, svenska)

För dig som är valutaväxlare. Så här följer du reglerna om penningtvätt i din dagliga verksamhet INFORMATION FRÅN FINANSINSPEKTIONEN

Användarmanual och policy för Göteborgs Evenemangskalender på goteborg.com

PROGRAMMERING A VB6 UTVECKLINGSVERKTYGET VISUAL BASIC

Manual för BPSD registret. Version 6 /

Idag: Dataabstraktion

Handledning för digitala verktyg Talsyntes och rättstavningsprogram. Vital, StavaRex och SpellRight

Skapa en rapport med snygg formatering, rubriker, sidnummer och innehållsförteckning

TDP004. Minne och pekare. Eric Elfving Institutionen för datavetenskap

TIMREDOVISNINGSSYSTEM

Axiell Arena. Samarbeta om bilder Regionbiblioteket i Kalmar län

Praktisk programmering

Sammanfattning på lättläst svenska

Mätningar på op-förstärkare. Del 3, växelspänningsförstärkning med balanserad ingång.

Administration Excelimport

Utbildningsmodulen i IdrottOnline-appen

C++ - En introduktion

Det andra alternativet är att ladda upp filer genom att klicka på plustecknet nere till vänster. Man klickar sig in på den mapp som man vill att

Design by. Manual Jossan.exe. Manual. till programmet. Jossan.exe. E-post:

Manual HSB Webb brf

Klasser och objekt i C#

Programmera en NXT Robot

Tränarguide del 1. Mattelek.

Tillämpad UNIX. Laborations-PM Christian von Schultz, Programpaket och processhantering

Partnerskapsförord. giftorättsgods görs till enskild egendom 1, 2. Parter 3. Partnerskapsförordets innehåll: 4

Vad är WordPress? Medlemmar

Lathund. Drift Teknisk Förvaltning Redigera driftåtgärder INFORMATION FRÅN VITEC

Hel tjänstledighet för att prova annan anställning inom Göteborgs universitet.

En grafisk guide till vår identitet

L(9/G)MA10 Kombinatorik och geometri Gruppövning 1

Visma Proceedo. Att attestera - Manual. Version 1.4. Version 1.4 /

Skriva B gammalt nationellt prov

NATIONELLA MATEMATIKTÄVLING

Hur skapar man formula r

Kulturmöten. Det var vi som gjorde det.

Dina inloggningsuppgifter är samma som du använder för att logga in på skolans datorer.

MBX Mobilapplikation IOS Android - Handledning

Laganmälan & Laghantering

4-6 Trianglar Namn:..

Hävarmen. Peter Kock

Individuellt Mjukvaruutvecklingsprojekt

Gissa det hemliga talet

Administrera utskick på utbildningstillfälle

Manual Ledningskollen i mobilen

FOLKUNIVERSITETET 1 (11) Bildmanér för Webb3. Vår referens: Fredrik Suter Version 1. Stockholm

Guide till Wordpress text- och bildredskap

Bokjuryn på Haganässkolan, Älmhult

Gruppenkät. Lycka till! Kommun: Stadsdel: (Gäller endast Göteborg)

Handbok Ämnesprov 2016 Lärarinmatning I Dexter Åk 3. Uppdaterad: /HL Version: IST AB

Boken om Teknik. Boken om Teknik är en grundbok i Teknik för åk 4 6.

Omvandla Vinklar. 1 Mattematiskt Tankesätt

Elektronen och laddning

UTMANINGAR OCH MÖJLIGHETER HAR DU 730 DAGAR OCH ETT STARKT DRIV DÅ HAR VI EN LEDARROLL TILL DIG

Övningar Dag 2 En första klass

Q1 Hur många undervisningstillfällen har du haft under september månad?

Föräldrar i Skola24. Schema

TDIU01 - Programmering i C++, grundkurs

GRUNDERNA I SJÄLVLEDARSKAP

Manual fö r kursspecifika ansö kningsförmula r Fölkhö gsköla.nu

KUPOL en studie om skolmiljöns betydelse för ungdomars hälsa ENKÄT TILL ELEVER I ÅRSKURS 9

Vet du vilka rättigheter du har?

Laborationspecifikation

Snabbslumpade uppgifter från flera moment.

Transkript:

Föreläsning 3: Vector och struct Nu är det dags att börja prata lite datastrukturer i c++. Vi börjar med fält. Vill man ha ett klassiskt fält så kan man i sitt c++-program deklarera t.e.x int tio_heltal[] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10; eller int fem_heltal[5]; for (int i = 0; i < 5; ++i) fem_heltal[i] = i Dessa fält är i grund och botten bara pekare, så det finns t.ex. inga kontroller (så som i Ada) på om man går utanför. Det skulle t.ex. vara helt ok att göra, så länge det minnesutrymme som man råka peka ut inte ligger utanför det minne som tillhör programmet: cout << fem_heltal[10]; En char* (c-sträng) är ett typexempel på ett sådant fält. Jag går nog inte in mer på sådana fält nu eftersom vi i c++ har en riktigt juste implementation på ett dynamiskt fält, nämligen vector. En vector är ett fält som kan växa och krympa, vilket är praktiskt. Det liknar ganska mycket den enkellänkade listan som ni redan har gjort. Vi tar lite exempel på vad man kan göra: #include <iostream> #include <vector> vector<int> mitt_falt; mitt_falt.push_back(5); mitt_falt.push_back(10); mitt_falt.push_back(15); Jag måste ta med biblioteket för vector. Jag deklarerar att mitt_falt är en vektor som består av heltal. <- hakarna finns där för att tala om att vector är generisk, man kan lagra vilken datatyp man vill i en vector. Men precis som med vanliga fält måste det vara samma datatyp på varje plats. Jag stoppar sen in en femma, en tia och femton med funktionen push_back, som lägger på på slutet av vektorn. mitt_falt: 5 10 15 0 1 2 Precis som ett vanligt fät har vectorn index på varje plats. Indexeringen börjar från 0 i c++. Om jag nu t.ex. vill skriva ut fältet så kan jag göra följande: cout << mitt_falt.at(0) << mitt_falt.at(1) << mitt_falt.at(2) << endl;

Då får vi ut: 51015 Vi gör nu detta lite generellt och snyggt med ett underprogram: vector<int> mitt_falt; for (int i = 5; i < 20; i+=5) mitt_falt.push_back(i); print(mitt_falt); void print(const vector<int>& falt) for (int i = 0; i < falt.size(); ++i) cout << falt.at(i) << endl; Vi kan alltså komma åt elementen med funktionen at! Om vi vill kan vi använda []-parenteserna här också, men at rekommenderas eftersom den kontrollerar att elementet faktiskt finns. Försöker man gå utanför kommer man få undantaget out_of_range. Ett annat sätt att fylla en vektor med värden är att använda initiering: vector<int> annat_falt1, 2, 3, 4, 5; Ett annat sätt att loopa över talen i vectorn är att använda den intervallbaserade for-loopen: for (int tal : annat_falt) cout << tal << endl; Här kommer tal anta varje värde från annat_falt tills alla talen har gåtts igenom. Om man vill ändra på talen medan mar går igenom så kan man använda sig av referenser här: for (int& tal : annat_falt) ++tal; print(annat_falt); // vi får ut 2 3 4 5 Vi kan jämföra två vector med operatorn "<", då blir det precis som i Ada att man jämför element för element från vänster (tänk bokstavsordning). Detta fungerar så länge typen som ligger i fältet går att jämföra med "<". Det finns många bra inbyggda funktioner som jobbar med vektorer! T.ex: annat_falt.clear(); //rensar hela fältet.

Poster Nu går vi över till poster. I c++ (och många andra språk) heter post struct. Om vi t.ex. vill representera en bok kan vi skapa datatypen Book: struct Book string title; string author; int pages; ; Här får man inte glömma det där semi-kolonet efter struct-deklarationen! Nu kan vi skapa hur många Bookvariabler vi vill! Book b; b.title = "Ada 95 för nybörjare och erfarna"; b.author = "Torbjörn Jonsson"; b.pages = "331"; return 0; Vi kan även här använda initiering med om vi vill: Book primer "C++ primer", "Lippman", 885; Då fyller vi på delarna av posten i ordningen som de deklarerades. Om vi inte fyller i hela listan med värden så får de delar som inte fick något värde bara default värden (tom sträng, 0 o.s.v.): Book b2 "Professional C++"; Vi kan självklart göra tilldelning av hela structar: b2 = b; Om vi skall skicka structar som parameter så bör vi använda const-referens, annars blir det mycket onödig kopiering. Att komma åt delar av posten ser exakt lika dant ut som i Ada.: i main: my_print(b); void my_print(const Book& book) cout << "Title: " << book.title << endl << "Author: " << book.author << endl << book.pages << " pages" << endl; Vi kan ju passa på och göra en inläsningsrutin samtidigt:

void my_input(book& book) cout << "Input book: "; cin >> book.title >> book.author >> book.pages; Självklart kan man kombinera vector och struct på vilka sätt man känner för! Just detta skall ni göra på laborationen! Vi kan också passa på att skapa oss en operator som jämför två böcker. Man kanske vill ha en hel bokhylla, då vill man självklart jämföra först på författare och sedan på titel. bool operator<(const Book& left, const Book& right) if (left.author == right.author) return left.title < right.author; return left.author < right.author; Egna Headerfiler Nu har vi gjort många bra funktioner för vår datatyp Book. Detta kan säkert komma till nytta i fler program, så vi skulle gärna vilja lägga detta på en egen fil så att vi kan inkludera det på andra ställen senare. Vi gör då en egen headerfil som vi lägger vår kod i. Som ett första steg skulle vi kunna flytta ut det som har med Book att göra till en.h-fil, t.ex. book_handling.h. Vi måste då komma ihåg att lägga till de bibliotek som behövs där: #include <iostream> struct Book string title; string author; int pages; ; void my_print(const Book& book) cout << "Title: " << book.title << endl << "Author: " << book.author << endl << book.pages << " pages" << endl; void my_input(book& book) cout << "Input book: "; cin >> book.title >> book.author >> book.pages;

bool operator<(const Book& left, const Book& right) if (left.author == right.author) return left.title < right.author; return left.author < right.author; Huvudprogrammet blir då ganska litet: #include <iostream> #include "book_handling.h" Book b; cout << "Mata in en bok:"; my_input(b); my_print(b); Observera att vi använder "-tecken för att inkludera headerfiler som vi gjort själva. Gör vi på detta sätt får vi dock ingen uppdelning mellan specifikation och implementation (som i Ada). Man skall också komma ihåg att om man gör "" så gäller ju det tillsvidare eftersom koden från book_handling.h i princip "klipps in" ovanför main. Detta kanske inte gör så mycket, om man inte vill jobba med fler namnrymder smatidigt. Om vi nu skulle dela upp detta ytterligare så skulle vi kunna flytta själva implementationerna till en implementationsfil, t.ex. book_handling.cpp. Då blir book_handling.h bara detta: #include <string> struct Book std::string title; std::string author; int pages; ; void my_print(const Book& b); bool operator<(const Book& left, const Book& right); void my_input(book& b); Och book_handling.cpp:

#include <iostream> #include "book_handling.h" void my_print(const Book& b) cout << "Titel: " << b.title << endl << "Författare: " << b.author << endl << "Sidor: " << b.pages << endl; bool operator<(const Book& left, const Book& right) if (lhs.author == rhs.author) return lhs.title < rhs.title; return lhs.author < rhs.author; void my_input(book& b) getline(cin, b.title); getline(cin, b.author); cin >> b.pages; cin.ignore(1000, '\n'); Observera att vi i implmenentationsfilen måste inkludera specifikationsfilen! Att vi väljer att kalla dessa.h och.cpp för samma sak nu är bara en behändighetsgrej, kompilatorn kommer inte göra någon koppling mellan filer bara för att de heter lika (som gnatmake gör). Nej, för att få detta ihoplänkat rätt så måste vi vara mycket specifika. När vi nu kompilerar skriver vi då: g++ std=c++11 main.cpp book_handling.cpp Eftersom vi inte använde iostream i h-filen längre så tog jag bort den. Det enda som egentligen behövdes var string, så den tar vi med. Istället för att köra using kan vi då helt enkelt skriva strings fulla namn, d.v.s. std::string. I implementationsfilen är det behändigt att använda using eftersom vi där använder mycket cout, cin och endl. I vissa lägen kan man råka ut för tråkigheter när man gör #include. Det kan hända att saker inkluderas flera gånger (om man t.ex. har tre filer A, B, C där A inkluderar B och C, och B också inkluderar C). Då kommer man att få "multipla deklarationer". Det man kan göra då är att lägga till ett preprocessordirektiv som ser till att koden bara inkluderas en gång. Längst upp i vår h-fil lägger vi då (i vårt fall): #ifndef BOOK_HANDLING_H #define BOOK_HANDLING_H och längst ner i den filen: #endif Detta kallas för en "inkluderingsgard" och betyder helt enkelt, "om följande symbol inte redan finns: definiera den och lägg till allt det här"