• Keine Ergebnisse gefunden

Grundlagen der Programmierung in C

N/A
N/A
Protected

Academic year: 2021

Aktie "Grundlagen der Programmierung in C"

Copied!
6
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Grundlagen der

Programmierung in C

Pointer & Funktionen

Wintersemester 2005/2006 G. Zachmann

Clausthal University, Germany zach@in.tu-clausthal.de

 Aufruf einer Funktion mit Parameter bisher

 Was genau passiert dabei?

 Kopieren und Wegwerfen

void foo( Typ x ) {

...

}

int main( ) {

Typ obj;

...

foo( obj );

}

(2)

G. Zachmann Grundlagen der Programmierung in C - WS 05/06 Pointer & Funktionen, 3

Call-by-Value

 Call-by-Value : tatsächliche Parameter werden kopiert und hinterher weggeworfen

 Problem: "große" Parameter, z.B. structs

struct someStruct { ... };

void foo( someStruct o, ... ) {

int i = sizeof( o );

...

}

int main( ) { ...

someStruct obj; ...

}

foo( obj, ... );

return adr 4 byte

obj

. . . n Bytes

... andere

lokale Vars in main

ar gu m en ts

i = 35 4 byte

... andere

Param.

o

. . . n Bytes

Call-by-Reference

 Lösung: übergebe nur Pointer

 Heißt Call-by-reference

void foo( someStruct * o, .. ) {

int i = sizeof( *o );

...

}

int main( ) { ...

someStruct obj; ...

}

stack:

function display

return adr 4 byte

obj

. . . n Bytes

... andere

lokale Vars in main

ar gu m en ts

i = 35 4 byte

... 4 Bytes

foo( &obj, ... );

o

(3)

G. Zachmann Grundlagen der Programmierung in C - WS 05/06 Pointer & Funktionen, 5

// n int's lesen und an list anhaengen for ( int i = 0; i < n; i ++ )

{ int a;

scanf( "%d", &a );

// neues ListElement mit a generieren ListElement* e = new ListElement;

e.data = a;

e->next = NULL;

// e an list anhaengen list->last->next = e;

list->last = e;

}

Beispiel: Nochmal Anhängen an Liste

 Selbe Aufgabe wie im vorigen Kapitel (dyn. Speicher)

 Operationen auf Listen sind fast immer Kandidaten für Funktionen!

 Erinnerung:

 Besser als Funktion:

void append( List * list, ListElement * e ) {

list->last->next = e;

list->last = e;

ListElement* append( List * list, int a ) {

ListElement* e = new ListElement;

e->data = a;

append( list, e );

return e;

}

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

int a;

scanf( "%d", &a );

append( list, a );

}

(4)

G. Zachmann Grundlagen der Programmierung in C - WS 05/06 Pointer & Funktionen, 11

Rüchgabe von Pointern und Referenzen

 Vorsicht! Beispiel:

struct TrigVals {

double sinus, cosinus, tangens;

};

TrigVals* calcTrigVals( double x ) {

TrigVals resultat;

resultat.sinus = sin( x );

resultat.cosinus = cos( x );

resultat.tangens = tan( x );

return & resultat; // BUG!

}

int main() {

TrigVals* trigvals;

trigvals main() resultat

sin cosinus tangens calcTrig resultat

sinus cosinus tangens

x

trigvals = calcTrigVals( 0.5 );

TrigVals * calcTrigVals( double x ) {

TrigVals resultat;

. . .

return & resultat;

}

// back in main()

printf("sin(x) = %f\n", trigvals->sin );

(5)

G. Zachmann Grundlagen der Programmierung in C - WS 05/06 Pointer & Funktionen, 13

 Bessere Lösung:

 Aber: nicht thread-safe!

TrigVals* calcTrigVals( double x ) {

static TrigVals resultat;

resultat.sinus = sin( x );

resultat.cosinus = cos( x );

resultat.tangens = tan( x );

return & resultat; // besser }

 Beste Lösung: "return by value"

 Oder: "Out-Parameter"

TrigVals calcTrigVals( double x ) {

TrigVals resultat;

resultat.sinus = sin( x );

...

return resultat;

}

void calcTrigVals( double x,

TrigVals * trigvals ) {

resultat->sinus = sin( x );

...

}

(6)

G. Zachmann Grundlagen der Programmierung in C - WS 05/06 Pointer & Funktionen, 15

 Fazit:

 Gebe nie Pointer (oder Referenz) auf lokale Variable zurück!

 Referenzen sind noch schlimmer (man sieht es ihnen nicht an)

 Gebe auch keinen Pointer auf eine lokale static Variable zurück (auch nicht als Out-Parameter)

 Return-by-Value macht heute keine Kopie mehr

(war früher ein Performance-Problem)

Referenzen

ÄHNLICHE DOKUMENTE

Zachmann Grundlagen der Programmierung in C - WS 05/06 Zusammengesetzte Typen, 3. Das

- Enum-Namen werden fortlaufend numeriert - Erster Enum-Name = 0. enum ColorE { RED, YELLOW, GREEN,

Every set of cards made for any formula will at any future time recalculate that formula with whatever constants may be required. Thus the Analytical Engine

ein Speicherblock ist zu genau einem Objekt (z.B. ein Double) zugeordnet, dieser Block hat genau einen Typ, und es gibt keine Möglichkeit im Programm, diesen Speicherblock als

 Sprache (Interpreter / Virtual Machine) erkennt, wenn Objekt vom Programm nicht mehr zugreifbar ist (kein Zeiger führt mehr darauf).  Garbage-Collector läuft im Hintergrund

 Gebe auch keinen Pointer auf eine lokale static Variable zurück (auch nicht als Out-Parameter).  Return-by-Value macht heute keine Kopie mehr (war früher

alle Members ab private: sind nur in Methoden innerhalb der Klasse sichtbar.

Aber auch Programme für Geräte aller Art werden mit C programmiert (eingebettete Systeme). Grund