• No results found

Programsystemkonstruktion med C++

N/A
N/A
Protected

Academic year: 2021

Share "Programsystemkonstruktion med C++"

Copied!
28
0
0

Loading.... (view fulltext now)

Full text

(1)

 Daniel Aarno

bishop@kth.se

Programsystemkonstruktion med C++

Övning 1

(2)

Översikt övning 1

Kompilering och länkning

Makefile

Preprocessordirektiv Funktioner

Funktionen main() Datatyper

Minneshantering Pekare och arrayer Vanliga slarvfel

Referenser

Statiska variabler

Kommentarer

(3)

Ett första program

En klass behöver både deklaration och definition

Deklaration i .h (.hh) och definition i .cpp (.cc) Private är förvalt

Student::learn()

Student::Student() Student::~Student()

Globala funktioner och variabler är OK.

main() är en global funktion

Macro (inleds med #) körs av preprocessorn

(4)

Ett första program (cont'd)

#ifndef _STUDENT_ 

#define _STUDENT_ 

#include <iostream> 

#include <string> 

using std::string;

class Student {  private: 

  string knowledge; 

public: 

  Student(); 

  ~Student() {}; 

  void learn

      (string info); 

  string speak(); 

}; 

#endif 

#include "student.h"  

Student::Student()

  knowledge=""; 

void Student::learn(string  info)

  knowledge += info; 

string Student::speak()

  return knowledge; 

}

student.h student.cpp

(5)

Ett första program (cont'd)

#include  "student.h"

int main()

  Student s; 

  s.learn("bla bla bla"); 

  std::cout << s.speak() << std::endl; 

  return 0; 

}

main.cpp

För att köra programmet:

> g++ ­o ex1 main.cpp student.cpp

> ./ex1

bla bla bla

(6)

Kompilator och länkare

(7)

Kompilator och länkare (cont'd)

Filer kan kompileras var för sig till objektfiler (.o)

> g++ ­c file.cpp

> g++ ­c main.cpp

> ls

... file.o   main.o

Flera objektfiler kan länkas samman till ett program (endast om main() är definerad)

> g++ ­o ex1 main.o file.o ...

> g++ ­o ex1_debug ­g ­O1 main.o file.o

debug optimeringsnivå 1

(8)

Beroenden (dependencies)

Om vi ändrar main.cpp räcker det att kompilera om den

Men om vi ändrar i student.cpp/h måste vi

eventuellt kompilera om både student.cpp och main.cpp (main.cpp beror på student.h)

Jobbigt hålla reda på beroenden

Långsamt att alltid kompilera om allt

”Intressanta” fel om allt som behöver kompileras

inte kompileras om

(9)

Makefiler

#variables CC = g++

FLAGS = ­g ­I~/c++kurs/student OBJ = main.o student.o

#rules

ex1: $(OBJ)

$(CC) $(FLAGS) ­o ex1 $(OBJ)

#don't forget tab!

main.o: main.cpp student.h

$(CC) $(FLAGS) ­c main.cpp student.o: student.h

$(CC) $(FLAGS) ­c student.cpp clean:

rm *.o ex1

(10)

Makefiler (cont'd)

#variables CC = g++

FLAGS = ­g ­I~/c++kurs/student OBJ = main.o student.o

SRC = main.cpp student.cpp

#rules

ex1: $(OBJ)

$(CC) $(FLAGS) ­o ex1 $(OBJ)

%.o: %.cpp

$(CC) $(FLAGS) ­c $*.cpp depend:

makedepend $(FLAGS) $(SRC) clean:

rm *.o ex1

http://www.gnu.org/manual/make3.79.1/html_chapter/make_toc.html

(11)

Preprocessorn

#include slår ihop filer innan kompilering

#ifndef ... #define ... #endif garanterar att en fil bara inkluderas en gång

// may be useful

#define MAX 10000 // dangerous

#define SQR1(A) A*A // less dangerous

#define SQR2(A) (A)*(A) 

(12)

Funktioner

En funktion

Behöver inte defineras där den deklareras Behöver deklareras innan den används

int foo(int x); // declaration of foo int bar(int x) {

return foo(x); // call to foo }

int foo(int x) { return x; } // definition of foo

Kan överlagras

int foo(int x) { // code here ... } int foo(float x) { // code here ... }

(13)

Funktioner (cont'd)

En funktion

Kan ha argument med förvalt värde

int foo(float f, 

int x = 0); //< OK int foo(float f = 0, 

int x, 

int y = 0); //< NOT OK

Kan vara inline

inline int sqr(int x) 

return x*x; 

}

(14)

Funktioner (cont'd)

Fördelar med funktionen sqr()

Mer läsbar kod (samma anledning som macrot SQR) Ett ställe att ändra på

Alla anrop till sqr funkar likadant Löser problemet med macrot SQR

Det går ”slött” att använda funktioner. Argument måste

kopieras och programmets exekvering måste styras om.

(15)

Funktioner (cont'd)

inline är användbart för korta funktioner som används ofta

Overhead vid funktionsanrop är störst för små funktioner Inline gör att funktionsanropet ersätts med koden det

innehåller vid kompileringstilfället

För mycket inlining kan ge långsammare program och större filer

För mycket inlining ger långsammare kompilering

(16)

Funktioner (cont'd)

Funktionen main() är speciell Kan inte heta något annat

argc är antalet argument inkl. programmets namn

argv är en array av C-strängar med argumenten som gavs till programmet

argv[0] är programmets namn (tex /usr/bin/zip eller zip) main() är en global funktion och således inte del av någon klass

main() behöver inte deklareras

(17)

Funktioner (cont'd)

#include <iostream>

int main(int argc, char* argv[]) {

for(int i = 0; i < argc; i++) {

std::cout << argv[i] << std::endl;

} }

> g++ main.cc ­o main

> ./main hej 12 ./main

hej 12

>

main.cpp

(18)

Datatyper

Inbyggda datatyper

bool (true/false (1 byte)) char (1 byte)

int (plattformsberoende storlek) short

long

float (4 byte) double (8 byte) long double

void (ingenting)

(19)

Datatyper (cont'd)

Egna datatyper

typedef char* charPtr;

enum Fruit { apple, banana, orange };

struct { int x; int y; double d; };

class {int x; public: void foo(); };

union {int x, bool ok, double d };

Testa sizeof(T); för olika typer T (int, double,

charPtr osv)

(20)

Minneshantering

Automatiska objekt

Städas automatiskt upp när scopet är slut Snabb allokering på stacken

Mindre risk för slarvfel

void foo(Student s) { //< begin scope   int x;

  

  for(int i = 0; i < 5; i++) { //< begin scope     int y = 2*i;

    x = 3 + y;

  } //< end scope (i,y)

} //< end scope (x,s)

(21)

Minneshantering

Dynamiska objekt

Heap större än stack

Arrayers längd kan bestämmas i run-time Objekt kan leva utanför scope där de skapas

void foo(int nmemb) {

   int *xPtr;

  

// Allocate array of nmemb ints xPtr = new int[nmemb]; 

// do stuff, then

// delete memory allocated by new[]

delete[] xPtr; 

}

(22)

Minneshantering

CODE/TEXT

Själva programkoden och konstanta variabler

DATA

Statiska (static) initialiserade variabler

BSS

Statiska icke initialiserade variabler

STACK

Automatiskt allokerade variabler vid körning Returvärden och returadresser

4kB på Linux, kan växa till 2MB (default)

(23)

Pekare och arrayer

void foo(Student *studPtr) {

  int *ptr, i; //< ptr is ptr to int, i is int    int* x, y;   //< x is ptr to int, y is int

  

  ptr = &i;    //< ptr now holds address  //< of i (e.g. 0xbfffff24)   *ptr = 5;    //< assign 5 to i

  x = ptr;     //< x now also points to i;

  cout << *x << endl; //< would print 5   (*studPtr).learn(”something”);

  studPtr­>learn(”more”);

  ptr = new int;  //< ptr now holds adr 

//< of an int on the heap   ptr = &y;  //< error no way to access 

  //< memory on heap anymore 

}

(24)

Pekare och arrayer (cont'd)

void foo(float f) {

  char array[4711]; //< array of 4711 uninitialized chars   int ary[] = {1,2,5}; //< array of 3 initialized ints

  

  // same as const char str[] = {'h','e','j',0};

  char str[] = ”hej”; 

  char* ptr = 0; //< char pointer to nothing

  const float *fPtr; //< The memory pointed to by f is  //< read­only

  float * const fcPtr=f; //< The pointer f is read­only   ptr = array;  //< same as ptr = &array[0];

  ptr[4] = 'x'; //< set fifth element of array to x;

  *(ptr + 4) = 'y';    //< same thing, but to y

  ptr = new char[512]; //< dynamically allocated array }

(25)

Vanliga slarvfel

void foo(int *p) {  delete p;

}

int* bar() {    int x=1; 

  return &x; // oops! 

}

void fun() {

  int* p1, p2; // p2 is normal int not pointer   int *p3 = new int[2]; 

  int *p4 = new int[2];

  p3 = p4;       // MEMORY LEAK!

  foo(p3);       // destruction of p3 (and p4)   int x = p4[1]; // error (segfault if LUCKY) }

(26)

Referenser

Alias för ett objekt Som en pekare vars adress inte får ändras Måste referera till ett objekt (inte NULL)

Snabbare skicka referens än objekt

void iswap(int &i1,   int &i2) {

int tmp = i1;

i1 = i2;

i2 = tmp;

}

void main() {

int i = 5;

int &iRef = i;

int *iPtr = &i;

iRef++;

// i, iRef and 

// *iPtr is now 6

}

(27)

Statiska variabler

void foo()

{ static int i = 5;

cout << i++ << endl;

}

int main() {

foo();

foo();

foo();

}

> ./static 5

6 7

>

static.cpp

(28)

Kommentarer

Funktionskommentarer förklarar användning (.h)

/**

 * Send a signal to the task.

 *

 * @param signal The signal to send (i.e. SIGINT)  * @return true on success, false on failiure.

 */

bool sigSend(int signal);

Procedurkommentarer förklarar implementationen (.cpp)

/* getline reads one line from stdin and stores it in  * the given buffer. The newline is stored.

 * The given buffer must be big enough to store the     * trailing \0 (i.e. it must be at least one bigger   * than nmax).

 */

void getline (char buf[], int nmax, int *nread) { //function implementation...

References

Related documents

The size of the actual data stored is 20, 480 megabytes and when inserting them into index lists with compression the size is 5, 400 megabytes for SCARY+, 8, 080 megabytes for

The Chairman of the Board plans the Board meetings together with the President. In advance of each Board meet- ing, the members of the Board receive a written agenda and

In summary, a new coupling of sulfoxides and Grignard reagents enabled by an unusual turbo-Hauser base has been developed that expands the scope of the original Pummerer reaction

This chapter analyzes the empirical data in relation to the theory and gives an answer to the research questions, about the antibiotics supply sector

[r]

Skruva därefter fast täcklocket för hand i guide- profilen efter utsatta hål i täcklocket enligt bild..!. Koppla in ström till

Egenskaper skadliga för fostret Inget av ämnena nämnda under avsnitt 3 är klassificerat som fosterskadande... Reproduktionsstörningar Inget av ämnena nämnda under avsnitt 3

avses att (a) avseende en eller flera Skuldförbindelser med ett sammantaget nomi- nellt värde om minst USD 10 000 000 (eller dess motvärde i annan valuta vid tiden