sose' 2014 markus geveler inst. f. applied mathematics ... · static members statische...

Post on 28-Aug-2019

217 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Programmierkurs

markus.geveler@math.tu-dortmund.de

Markus GevelerInst. f. Applied Mathematics, TU Dortmund

'SoSe' 2014

Lesson 6

Was machen wir heute hier?

Vertiefung:

→ kurz: static member, operator overloading, scope

→ C++ standard lib & Standard Template Library (STL)

→ mehr zu Speicher, pointer und references

→ debugging

[→ Hardware und Software]

static membersStatische (static) member variables

→ num_instances wird von allen Objekten der Klasse geteilt!

struct Foo{ static unsigned num_instances; unsigned id;

Foo() : id(++num_instances) { }};

unsigned Foo::num_instances = 0;

int main(){ Foo f; Foo g;

cout << f.id << endl; cout << g.id << endl; cout << Foo::num_instances << endl;}

static membersStatische (static) member functions

→ bisher: class-member immer an Objekte gebunden→ jetzt: static class-member: nur an Klasse gebunden -

keine Instanziierung nötig!→ deklarieren mit static→ Zugriff mit scope operator ::→ drüber reden: wozu? → noch ein Beispiel: private static member getter

struct VectorSum{

static Vector& value(Vector& v1, Vector& v2){

for(unsigned long i(0) ; i < v1.size() ; ++i){

v1[i] += v2[i];}return v1;

}};...Vector v_1;Vector v_2;VectorSum::value(v_1, v_2);

operator overloadingoperators sind functions!

→ Syntax: intuitiv klar→ was passiert?

struct Scalar{

float data;Scalar(float d = 0.f) :

data(d){}

};

Scalar& operator+(Scalar& a, Scalar& b){

a.data += b.data;return a;

};

operator overloadingcopy assignment operator

→ um mit unseren Scalar – Objekten rechnen zu können, brauchen wir nochEtwas:

→ der ist etwas anders als operator+→ drüber reden: was ist anders?

struct Scalar{

float data;Scalar(float d) :

data(d){}

Scalar& operator=(Scalar& b){

this->data = b.data;return *this;

}};

operator overloading

→ was kann man damit denn jetzt machen?

→ jetzt mitdenken: übertragen auf unsere Vektor- und Matrix-Klassen?→ … ist auch eine Übungsaufgabe...

Scalar a(2.f);Scalar b(3.f);Scalar c;c = a + b;

scopeSichtbarkeit in C++

→ es gibt in C++ mehrere Arten von Sichtbarkeit→ sie geben an, ob und von wem ein bestimmtes 'Stück' Code

(Variable/Konstante, function oder Klasse) zugreifbar ist→ diese Sichtbarkeitstufen (scope) sind:

→ 'class': innerhalb einer Klasse sichtbar→ 'global': für alle sichtbar (bzw. zunächst nur in der Datei. Daherauch oft: 'file')→ 'local': nur in der einschließenden Struktur (z.B.: function) sichtbar→ 'namespace': Namensräume können verwendet werden, um ein

Projekt weiter zu strukturieren: jetzt

→ einen solchen namespace kennen wir schon: std, den namespace fürdie C++ standard Bibliothek

namespacesBeispiel:

→ so ist Consumer zunächst nur im Namensraum people sichtbares gibt mehrere Möglichkeiten auf Consumer zuzugreifen

→ innerhalb von people: klar→ haben wir schon gesehen: der scope-operator '::' wie in std::cout→ auch people::Consumer→ das using-statement:

namespace people{

class Consumer{

...};

...}

using namespace people;

C++ standard lib

#include <iostream>#include <fstream>#include <string>

using namespace std;

int main (){

string filename;cin >> filename;ifstream ifs ( s , ifstream::in );while (ifs.good())

cout << (char)ifs.get();ifs.close();

}

Datei Ein/Ausgabe – ein Beispiel:

→ weiter lesen: http://www.cplusplus.com/doc/tutorial/basic_io/ → weiter lesen: http://www.cplusplus.com/doc/tutorial/files/

C++ standard lib

→ http://www.cplusplus.com/reference/ Tutorial

STLWas enthält die STL?

→ Container zur Speicherung von Daten, z.B.: Vektoren, Listen, ...→ Iteratoren für den Zugriff auf die Daten im Container (lernen wir

gleich)→ Algorithmen zu diesen Containern: Sortieren, u.a.

Wofür?

→ der sichere und effiziente Umgang mit Daten im Speicher istschwierig: die STL wurde gemacht, um möglichst viel davon vorEntwicklern zu verstecken; Beispiel: vermeide (Re-)Allokationen

→ es gibt gute Lösungen für bestimmte Aufgaben - das Rad muss nichtneu erfunden werden; Beispiel: quicksort (der für die meisten Fälleschnellste Sortieralgorithmus)

STL containergenerische sequentielle Container: vector, list undandere

Container – interface: allgemein → bool empty() const : ist der Container leer?→ size type size() const : wieviele Elemente? size type ist

nur sowas wie unsigned long→ void clear() : alle Elemente entfernen

#include <vector>using namespace std;...vector<double> v;v.push_back(23.4);v.push_back(0.);v.push_back(-2.222);v.push_back(2.*1./3.);double a(v.front());unsigned long i(v.size());

STL iteratorenWas ist das?

→ Iteratoren repräsentieren Elemente in einem Container→ stellen eine Verbindung zwischen den Daten und ihrer

Position im Container her→ Iteratoren sind demnach Container-spezifisch→ in sequentiellen Containern wie vector verhalten sich Iteratoren wie

Indices→ offenbar gibt es in vector spezielle Iteratoren: begin und end→ man kann Iterator dereferenzieren(wie pointer): Zugriff auf Daten darunter→ man kann iterator erhöhen (mit ihm rechnen): Zugriff auf Position

vector<float> v;...vector<float>::iterator current = v.begin();while(current != v.end()){

std::cout << *current << std::endl;++current;

}

STL iteratorenWozu Iteratoren?

→ etwas langsamer als anderer Zugriff→ sicher!→ manche Operationen erfordern Iteratoren→ was ist eigentlich vector<int>::iterator ?

vector<int> v;...v.erase(v.begin() + 5);

class VectorIterator {};

template<typename T>class vector{

typedef VectorIterator iterator;};

STL containerContainer – interface: sequentielle Container→schon gesehen: push back→ auch möglich (deque, ...) : push_front→ auch möglich: pop front/back→ zusätzlich: [ ] overload für indizierten Zugriff→ zusätzlich: at( ) member-function für indizierten Zugriff

→ was ist der Unterschied? - Semantisch: keiner, aber......intern wird bei Verwendung von at auf Gültigkeit des Zugriffsüberprüft und eine exception geworfen, falls dies nicht der Fall ist!Der access operator macht das nicht! Implikation: at ist langsameraber sicherer!

vector<Cat> v;Cat meow_1(v.at(i));Cat meow_2(v[i]);

STL containerContainer – interface: sequentielle Container→ nochmal: es geht wie immer besser→ die STL arbeitet mit C++11 eng zusammen→ Beispiel: ranged for-loops

→ Semantik: 'for all v_i in v'

vector<int> vec;vec.push_back(10);vec.push_back(111);

for(auto v_i : vec){

cout << v_i << endl;}

STL algorithmAlgorithmen der STL:

→ sequence : z.B.: count, find→ sorting : z.B.: sort, partial sort, max, lower bound,...→ numeric : z.B.: accumulate, inner product, ...

#include <vector>#include <algorithm>#include <iostream>

vector<int> v;vector<int>::iterator item;ostream_iterator<int> out(cout," ");

// generate arrayfor ( long i(0) ; i < 10; ++i)

v.push_back(i);// shuffle the arrayrandom_shuffle( v.begin(), v.end() );copy( v.begin(), v.end(), out );// sort the array in ascending ordersort( v.begin(), v.end() );copy( v.begin(), v.end(), out );

STL

→ http://www.cplusplus.com/reference/stl/

Tutorial

nochmal Speicherpointer arithmetics

→ Speicheraddressen sind pointer variables in C++ : wissen wir→ wie schlau sind die?

→ was kommt z.B. raus wenn int 4 byte groß sind?

int nValue = 7;int *pnPtr = &nValue; cout << pnPtr << endl;cout << pnPtr + 1 << endl;cout << pnPtr + 2 << endl;cout << pnPtr + 3 << endl;

0012FF7C0012FF800012FF840012FF88

nochmal Speicherpointer arithmetics

→ nochmal, diesmal am Beispiel mit array→ arrays und pointer sind dasselbe: wissen wir→ Konsequenzen?

int an_array[5] = { 9, 7, 5, 3, 1 };

cout << *(an_array + 1) << endl; // prints 7

debugging mit gdb

Führen Sie eine Speicherschutzverletzung mit pointer-arithmeticsherbei

PÜ→ verwenden Sie ein array→ dereferenzieren Sie einen pointer, der sich aus der

Basisaddresse plus Addressarithmetik ergibt

→ kompilieren Sie mit dem zusätzlichen flag '-ggdb'→ starten Sie den Debbugger mit 'gdb <executable>'→ starten Sie das Programm im Debugmodus mit 'run'→ rufen Sie den Aufrufstack ab mit 'bt'→ finden Sie die richtige Zeile mit 'list'

nochmal Speichermemory leaks

→ wie entstehen Speicherlöcher?

→ wenn man diese function aufruft, wird Speicher alloziiert, der nie wiederfreigegeben werden kann

→ heap Variablen haben effektiv keinen scope→ der pointer schon!→ der pointer geht out of scope, wenn die function terminiert

→ Speicherlöcher beeinträchtigen das Programm und alle anderen Programme im System

void do_something(){ int* pnValue = new int;}

nochmal Speichermemory leaks

→ noch mehr Beispiele:

→ pointer reassignment

→ double-allocation

int nValue = 5;int* pnValue = new int;pnValue = &nValue; // old address lost, memory leak results

int* pnValue = new int;pnValue = new int; // old address lost, memory leak results

memory leak detection

Führen Sie ein Speicherloch herbei

PÜ→ machen Sie absichtlich einen der Fehler

(pointer out-of-scope, pointer reassignment oder reallocation) wie auf den letzten Folien

→ starten sie ihr Programm mit 'valgrind <executable>'

smart pointerDas Problem:→

Die Lösung→ std::shared_ptr ist ein sog. smart pointer (auch auto-pointer)→ wir müssen uns nicht mehr um manuelles Löschen bemühen→ wird der DTOR von shared_ptr aufgerufen, wird nur wenn keine

anderen Kopien mehr die Daten benötigen (ownership) gelöscht→ wichtig in Verbindung mit STL Containern!'

Vec<double>* a(new Vec<double>());Vec<double>* b(a);delete a;

//EVIL!!!b->data()[0] = 0;

#include<memory>

//do not care about deletionstd::shared_ptr<Vec<double> > astl(new Vec<double>());std::shared_ptr<Vec<double> > bstl(astl);

smart pointer

Das Problem:→

→ was passiert, wenn man nun pop_back aufruft?→ implizit wird erst mal der Person* im Speicher des Containers gelöscht

...der liegt ja auf dem Heap...→ drüber nachdenken - ist eine Übungsaufgabe

vector<Person*> persons;persons.push_back(new Producer("Knut"));

nochmal Speicherpointer und constness

int nValue = 5;

int* const pnPtr1 = &nValue; //const pointer

const int* pnPtr2 = &nValue; //pointer to const

const int* const pnPtr3 = &nValue; //const pointer to const

nochmal Speicherreferences und pointer

int nValue = 5;Int* const pnValue = &nValue;Int& rnValue = nValue;

*pnValue = 6;rnValue = 6;

call paradigm, return paradigm

int foo1(Bar b) {} //call by value

int foo2(Bar& b) {} //call by reference

int foo3(Bar* b) {} //call by address

int foo1() {} //return by value

int& foo2() {} //return by reference

int* foo3() {} //return by address

pointers und lvaluesclass Foo{

public:float* get_data(){

return data;}

private:float* data;

};

Foo f;f.get_data() = new float[100000]; //will not compile, why?

pointers und lvaluesclass Foo{

public:float*& get_data(){

return data;}

private:float* data;

};

Foo f;f.get_data() = new float[100000]; //correct, but beware!

→ An lvalue (locator value) represents an object that occupies some identifiable location in memory (i.e. has an address).

Es gibt inzwischen fünf Arten von expressions. Uns reicht:Eine expression ist 'lvalue oder nicht' .

pointer und arrays

float matrix[30][500];

//set all values to zerofor(unsigned long i(0) ; i < 30 ; ++i){

for(unsigned long j(0) ; j < 500 ; ++j){

matrix[i][j] = 0.f;}

}

mehrdimensionale arrays

float** matrix;...matrix = new float*[n];

for(int i(0) ; i < n ; ++i)matrix[i] = new float[m];

...

Hardware und SoftwareHardware

materielle Teile des Computers

→ CPU + Arbeitsspeicher→ Persistenzspeicher (Festplatte)→ Grafikchip→ Mainboard, auf das alles aufgebracht ist

Hardware und SoftwareSoftware

erst einmal für uns: 'Programme'

→ befindet sich bei der Ausführung im Arbeitsspeicher→ hauptsächlich: Anweisungen zur Informationsverarbeitung→ ein Betriebssystem ist ein solches Programm

HardwareAufbau eines Computers 'in unserem Sinne'

Zentraleinheit: Hauptprozessor CPUArbeitsspeicher (random access memory RAM)→ zur kurzfristigen Speicherung von Informationen,→ Kennzeichen: klein, schnell,→ Informationen sind weg, wenn kein Strom mehr daPlattenspeicher (hard disk, storage)→ zur langfristigen Speicherung,→ Kennzeichen: gross, langsam, Informationen bleiben

langfristig erhaltenEingabegeräte: Tastatur, Maus, etc.Ausgabegeräte: Monitor, Drucker, etc.Verbindung über Netzwerk:�→ verschiedene Techniken je nach Anwendungszweck→ unterschiedliche Leistungsparameter

HardwareDie CPU: Von-Neumann Architektur

Steuerwerk (CU)→ steuert die Ausführung von Programmen→ hat dafür eigenen Speicher (wichtig!)

Rechenwerk (ALU)→ führt einfache arithmetische Operationen aus:

→ addieren, multiplizieren

Gemeinsamer Speicher→ für Programm und Daten

I/O→ zum Bildschirm→ von der Tastatur, etc.

HardwareJenseits der CPU...

Hardware ist nicht so 'einfach'→ Hardware ist parallel→ Hardware ist verteilt→ im Folgenden: immer nur eine, normale CPU

Software IBetriebssystem (OS)

Ein Betriebssystem ist die Software, die die Verwendung eines Computers ermöglicht. Es verwaltet Betriebsmittel wie Speicher, Ein- und Ausgabegeräte und steuert die Ausführung von Programmen, insbesondere:

→ Benutzerverwaltung→ Laden und Ausführung von Programmen→ Verwaltung der Prozessorzeit→ Verwaltung des Speicherplatzes für Anwendungen→ Verwaltung der angeschlossenen Ger ate�→ Verbindung zur Aussenwelt (Netzwerk)

Software IBetriebssystemkernel

Betriebssysteme bestehen in der Regel aus einem Kern (kernel), der die Hardware des Computers verwaltet, sowie grundlegenden Systemprogrammen, die dem Start des Betriebssystems und dessen Konfiguration dienen.

Beispiele für Betriebssysteme:Windows, Mac OS, Linux, Android, iOS

Zugang zum OS:→ Kommandozeile (lernen wir gleich kennen)→ grafische Benutzeroberfläche

Software IICompiler

ein geschriebenes Programm nicht ohne weiteres für den Rechner verständlich→ vor der Ausführung durch den Rechner Umwandlung

Notwendig Programm muss übersetzt werden→ Übersetzung durch Compiler→ erst danach Ausführung durch Rechner möglich

→ auch Betriebssystem und Compiler sind Programme

ProgrammierungDefinition

Programmiersprache: formalisierte Sprache→ die Sätze bestehen aus Worten eines

festgelegten Zeichenvorrats (Alphabet)→ gültige Sätze müssen anhand einer endlichen

Regelmenge (Syntax) gebildet werden→ legt die Bedeutung (Semantik) eines Satzes fest

Programm: eine Reihe von Sätzen, die in einerProgrammiersprache formuliert sind

ProgrammiersprachenArten

maschinennahe Programmiersprachen:→ betrachten explizit Speicherzellen und Register→ hängen vom konkreten Prozessor und der

Rechnerarchitektur ab→ Maschinensprache, Assemblersprachehöhere Programmiersprachen:→ Abstraktion von der konkreten Hardware→ Cobol, Fortran, C, C++, Java→ Akademisches Interesse: Prolog, Lisp

ProgrammiersprachenArten höherer Programmiersprachen

imperative Sprachen:→ Pascal, C, C++, Java→ ablauforientierte Sicht→ persistenter Zustand wird schrittweise verändertfunktionale Sprachen: Lisp, Haskell→ Problemlösung durch mathematische Funktionen beschreibenlogische Sprachen: Prolog→ Problemlösung durch logische Formeln beschreiben

Merke: Objektorientierung ist nur eine Ausprägung vonimperativen Sprachen

Software IIILinker

Was ist in unserem HelloWorld – Programm passiert?→ eine einzelne Datei, die den Quelltext (Sourcecode) enthält,wurde zu einem Programm (einer Objektdatei) compiliert:

Software IIILinker

Objekte nicht unbedingt aus einer Datei: das können ganzeBibliotheken sein!→ auch externe Bibliotheken (Wiederverwendung)→ unterscheide statisches/dynamisches Linken→ wir haben den Linker gerade implizit mitaufgerufen

Software IIILinker

Unter einem Linker oder Binder (auch: Bindelader)versteht man ein Computerprogramm, das einzelne

Programmmodule zu einem ausführbaren Programm zusammenstellt (verbindet).

top related