3. Arrays und Pointer
|
|
|
- Theresa Hertz
- vor 10 Jahren
- Abrufe
Transkript
1 C und C++ (CPP) 3. Arrays und Pointer Prof. Dr. Marc Rennhard Institut für angewandte Informationstechnologie InIT ZHAW Zürcher Hochschule für Angewandte Wissenschaften Marc Rennhard, , CPP_ArraysPointer.ppt 1 1
2 Ablauf Arrays in C Strings nichts anderes als char-arrays String Funktionen der Standard Library Pointer Zusammenhang zwischen Arrays und Pointer, Pointerarithmetik Dynamische Allozierung von Speicherplatz Strukturen und Pointer Marc Rennhard, , CPP_ArraysPointer.ppt 2 2
3 Ziele Sie wissen was Arrays in C sind und wie sie abgespeichert werden Sie verstehen die Darstellung von Strings als char-arrays und kennen die wichtigsten String Funktionen der Standard Library und können diese einsetzen Sie verstehen das Konzept der Pointer und können den Zusammenhang zwischen Pointern und Arrays erklären Sie kennen die Regeln der Pointerarithmetik und können diese richtig anwenden Sie wissen, dass es in C statische und dynamische Allozierung des Speichers gibt, können die wichtigsten Unterschiede erklären und beides anwenden Marc Rennhard, , CPP_ArraysPointer.ppt 3 3
4 Arrays (1) Ein Array enthält mehrere Elemente des gleichen Datentyps Bei der Deklaration werden ein Name für den Array, der Datentyp der Elemente und die Anzahl Elemente angegeben Der Index der Elemente läuft von 0 (Anzahl Elemente 1) Arrays in Java sind Objekte Werden dynamisch (zur Laufzeit) mit new erzeugt, der Speicherplatz wird auf dem Heap alloziert und man erhält eine Referenz auf den Array Neben den eigentlichen Array-Elementen kennt das Array-Objekt auch seine Länge und prüft bei Zugriffen, ob diese innerhalb des Arrays liegen Beispiele: int[] data = new int[100]; /* Deklariert einen int Array mit 100 Elementen und Namen data */ data[7] = 20; /* Setzt das Element mit Index 7 auf den Wert 20 */ int b = data[200]; /* Zugriff ausserhalb des Arrays ArrayOutOfBoundsException */ int c = data.length; /* Gibt die Länge des Arrays zurück */ Marc Rennhard, , CPP_ArraysPointer.ppt 4 4
5 Arrays (2) Arrays in C sind keine Objekte sondern viel einfacher aufgebaut Die Elemente eines Arrays der Länge n sind einfach direkt hintereinander im Speicher abgelegt Es ist keinerlei zusätzliche Information abgespeichert Ein Array mit 100 int-elementen belegt genau 400 Bytes Speicherplatz (falls ein int 4 Bytes Speicher beansprucht) Der Speicherplatz wird statisch (zur Kompilierungszeit) auf dem Stack alloziert (genau wie bei normalen Variablen) Deklaration eines Arrays: int data[100]; /* Deklariert einen int Array mit 100 Elementen und Namen data */ Die Arrayelemente erhalten bei der Deklaration keine Default-Werte Dieser einfache Aufbau hat mit der engen Verwandtschaft von Arrays und Pointern zu tun (siehe später) Vorteil: sehr effizient und flexibel im Gebrauch Nachteil: ein Array kennt seine Länge nicht (es gibt kein data.length), Zugriff ist über die Arraygrenzen hinaus möglich Marc Rennhard, , CPP_ArraysPointer.ppt 5 Ein Array vom Typ t der Länge len in C ist im Speicher nichts anderes als len mal hintereinander der Typ t und der Speicherplatz, der beansprucht wird, ist genau len * t. Darin ist keinerlei zusätzliche Information wie zb die Länge des Arrays enthalten. Arrayelemente erhalten genau wie normale lokale Variablen (int, double etc.) keinen Default-Wert bei der Deklaration, sondern haben die Werte, die gerade dort abgespeichert sind, wo der Speicherplatz für den Array alloziert wird. Man beachte, dass in C die eckigen Klammern beim Namen des Arrays stehen (int data[100];), während diese in Java beim Datentyp stehen (int[] data;). 5
6 Arrays (3) Arrays können gleich bei der Deklaration Werte zugewiesen erhalten int a[5] = {4,7,12,77,2}; /* Alle 5 Elemente werden initialisiert */ int b[] = {4,7,12,77,2}; /* Länge wird implizit auf 5 gesetzt */ int c[5] = {4,3,88,5}; /* OK, letztes Element erhält Wert 0 */ int d[5] = {4,3,88,5,3,6}; /* Kompilierfehler */ Der Zugriff auf die Arrayelemente funktioniert wie in Java a[3] = 5; b[2] = b[4] + a[0]; a: a[0] a[1] a[2] a[3] a[4] Zur Laufzeit wird nicht geprüft, ob der Zugriff auf ein Arrayelement wirklich innerhalb des Arrays liegt! potentielle Fehlerquelle! int a[5] = {4,7,12,77,2}; a[3] = 4; a[8] = 222; /* Kein Fehler zur Laufzeit!!! */ a[-3] = 36; /* Kein Fehler zur Laufzeit!!! */ Marc Rennhard, , CPP_ArraysPointer.ppt 6 Werden bei der Initialisierung weniger Elemente angegeben als die Arraygrösse, so werden die restlichen Elemente auf den numerischen Wert 0 initialisiert. Dies kommt im Beispiel oben bei der Initialisierung von c[5] zum tragen, wo das letzte Element (c[4]) automatisch auf 0 initialisiert wird. Man beachte, dass diese Initialisierung mit 0-Werten nur dann geschieht, wenn der Array überhaupt explizit initialisiert wird. Wird eine Array ohne jegliche Initialisierung deklariert, dann erhalten die Elemente im Array keinen Default-Wert, sondern sie erhalten die Werte, die dort, wo der Speicherplatz für den Array angelegt wird, gerade im Speicher stehen. Die Zuweisung mit {...} funktioniert nur bei der Deklaration der Variablen. Folgendes gibt einen Kompilierfehler: int a[5]; a = {1, 3, 66, 34, 7}; /* Fehler */ 6
7 Arrays (4) Arrays können wie primitive Datentypen als konstant definiert werden Werte des Arrays können nach der Deklaration nicht mehr verändert werden Eine Initialisierung bei der Deklaration ist dabei natürlich sinnvoll, wird vom Compiler aber nicht erzwungen int a[5] = {0,1,2,3,4}; const int b[5]; const int c[5] = {5,6,7,8,9}; const int d[] = {10,11,12,13,14}; a[0] = 4; /* OK */ b[1] = 55; /* Kompilierfehler */ c[2] = 666; /* Kompilierfehler */ d[3] = 6666; /* Kompilierfehler */ /* Funktioniert, macht aber kaum Sinn */ Marc Rennhard, , CPP_ArraysPointer.ppt 7 7
8 Mehrdimensionale Arrays Arrays können mehrere Dimensionen aufweisen 2-dimensionale Arrays (Matrix) kommen dabei am häufigsten vor: int a[2][3] = {{1,2,3},{4,5,6}}; /* 2-dimensionaler Array mit 2 Zeilen und 3 Spalten */ a[0][0] a[0][1] a[0][2] a: a[1][0] a[1][1] a[1][2] Zugriff auf die Elemente erfolgt durch spezifizieren beider Indices (oder aller n Indices im n-dimensionalen Fall): int b; b = a[0][0]; /* b ist jetzt = 1 */ a[1][2] += 2 * b; /* a[1][2] ist jetzt = 8 */ a[3][3] = 7; /* Auch hier findet keine Überprüfung der Grenzen statt! */ Marc Rennhard, , CPP_ArraysPointer.ppt 8 8
9 char-arrays und Strings (1) Java: Datentyp (Klasse) String C: kein Typ string, ein String wird als char-array dargestellt Jedes Zeichen entspricht einem char des Arrays (als ASCII-Wert) Konvention: nach dem letzten Zeichen im String folgt das Zeichen '\0' (NUL) damit kann das Ende eines Strings bestimmt werden Eine String Konstante (String Literal) wird in "..." geschrieben (wie Java) "Ich bin ein String" 18 Zeichen Interne Darstellung mit einem \0 am Ende 19 Zeichen I c h b i n e i n S t r i n g \0 Anwendung von String Literals: Direkt in einer Funktion: printf("hello, world"); Bei der Deklaration eines char-arrays: char hello[] = "hello, world"; Marc Rennhard, , CPP_ArraysPointer.ppt 9 C kennt also eigentlich keine Strings (in C++ gibt es einen Datentyp string). Strings werden also aus einem Array of Characters gebastelt, wobei die Konvention gilt, dass ein \0-Zeichen den String terminiert. 9
10 char-arrays und Strings (2) Deklaration eines char-arrays, Initialisierung mit String Literal: char hello1[] = "hello, world"; /* Array mit 13 Zeichen */ h e l l o, w o r l d \0 char hello2[13] = "hello, world"; /* OK, 13 Zeichen */ h e l l o, w o r l d \0 char hello3[12] = "hello, world"; /* OK in C, \0 fehlt! Kompilerfehler in C++ */ h e l l o, w o r l d char hello4[14] = "hello, world"; /* OK, mit \0, weitere h e l l o, w o r l d \0 \0 Arrayelemente werden per Default ebenfalls auf \0 initialisiert (= nummerischer Wert 0) */ Marc Rennhard, , CPP_ArraysPointer.ppt 10 Die Zuwesiung eines String Literals zu einem char-array ist nur bei der Deklaration möglich, später nicht mehr. Meist soll man die Bestimmung der Länge eines char-arrays, um einen Sring Literal aufzunehmen, dem Compiler überlassen (also mit []). Der letzte der vier Fälle kann Sinn machen, wenn man bewusst einen zu grossen Array allozieren will, um später einen noch längeren String darin abzuspeichern. 10
11 char-arrays und Strings (3) Deklaration eines char-arrays ohne Initialisierung: char ca1[20]; /* char-array für 20 chars, hat noch nichts mit einem String zu tun! */ char ca2[]; /* Kompilierfehler */ ca1 = "hello, world"; /* Kompilierfehler */ ca1[0] = 'h'; ca1[1] = 'e';... ca1[11] = 'd'; ca1[12] = '\0'; /* Jetzt kann man sagen, in ca1 ist ein String abgelegt! */ Marc Rennhard, , CPP_ArraysPointer.ppt 11 Ein char-array ist prinzipiell einmal einfach ein Array, der char-elemente enthält, genauso wie ein int-array int-elemente enthält.. Der Programmierer entscheidet, ob er ihn einfach als char-array oder für einen String verwenden will. Erst mit dem Setzen eines \0-Zeichens als Abschluss eines Strings kann man sagen, im char-array ist ein String abgelegt. 11
12 char-arrays und Strings (4) Beispiel mit Strings und printf: /* string_printf.c */ #include <stdio.h> int main(void) { char a[] = "Hans"; char b[5]; } printf("%s\n", a); /* String in a wird ausgegeben "Hans", printf erkennt \0 am Ende */ b[0] = 'H'; b[1] = 'a'; b[2] = 'n'; b[3] = 's'; printf("%s\n", b); /* String in b wird ausgegeben "Hans", kein \0 nach dem s printf gibt weiter Zeichen aus bis irgendwann \0 im Speicher gefunden wird */ b[4] = '\0'; printf("%s\n", b); /* \0 am Ende wird von printf erkannt */ Marc Rennhard, , CPP_ArraysPointer.ppt 12 printf verwendet den Konvertierungsoperator %s, wenn ein String ausgegeben werden soll. Der entsprechende Parameter ist ein char-array, denn Strings gibt es in C ja eigentlich nicht. %s heisst also, printf soll alle Zeichen hintereinander aus bis ein \0-zeichen gefunden wird. 12
13 Wichtige String-Funktionen #include <string.h> bindet String Funktionen der Std. Library ein: Länge eines Strings (ohne abschliessendes '\0'): int strlen(const char s[]); Vergleich zweier Strings (s1 > s2 >0, s1 = s2 0, s1 < s2 <0): int strcmp(const char s1[], const char s2[]); Beispiel: strcmp("hans", "Haus") gibt einen Wert <0 zurück, weil das Zeichen 'n' kleiner (ASCII-Code ist kleiner) ist als das Zeichen 'u' Kopieren eines Strings von source nach dest (und Rückgabe eines Pointers auf dest); Achtung: der dest-array muss vor dem Aufruf der Funktion genügend gross sein, um source zu erhalten: char* strcpy(char dest[], const char source[]); Zusammenhängen zweier Strings (s2 wird an s1 angehängt, zudem wird noch ein Pointer auf s1 von der Funktion zurückgegeben; auch hier muss s1 genügend gross sein!) char* strcat(char s1[], const char s2[]); All diese Funktionen bearbeiten die Strings jeweils so lange, bis sie das \0 Zeichen finden! Marc Rennhard, , CPP_ArraysPointer.ppt 13 13
14 Übung zu Strings Beantworten Sie zum folgenden Programmcode die eingefügten Fragen: /* strings.c */ #include <stdio.h> #include <string.h> int main(void) { char a[] = "Hund"; char b[10] = "Katze"; char c[4] = "Maus"; int len; } len = strlen(a); /* Wert von len = 4 */ len = strlen(b); /* Wert von len = 5 */ len = strlen(c); /* Wert von len = 9 (Stack: c vor b) */ strcat(b, a); printf("%s\n", b); /* Was wird ausgegeben: KatzeHund */ strcat(b, c); printf("%s\n", b); /* Was wird ausgegeben: Segmentation Fault */ Marc Rennhard, , CPP_ArraysPointer.ppt 14 14
15 Erklärungen zur Übung zu Strings Lokale Variablen werden auf dem Stack alloziert; der Stack wächst in Richtung der kleineren Adressen; entsprechend werden a, b und c auf dem Stack alloziert strcat(b, c): b = "KatzeHund", c = "MausKatzeHund"; Problem: das Abschlusszeichen (\0) von c (und alle folgenden Zeichen) werden überschrieben Segmentation fault vor strcat(b, a): nach strcat(b, a): nach strcat(b, c): Adr. Adr. Adr M a u s 3052 M a u s 3052 M a u s 3056 K a t z 3056 K a t z 3056 K a t z 3060 e \ e H u n 3060 e H u n d \ d M a u 3068 H u n d 3068 H u n d 3068 s K a t 3072 \ \ z e H u n d M a u s K a... Marc Rennhard, , CPP_ArraysPointer.ppt 15 15
16 Pointer (1) Bisher: Zugriff erfolgte immer direkt auf die Variablen; ohne Berücksichtigung wo (unter welcher Adresse) diese Variable im Speicher abgelegt ist In C/C++ arbeitet man sehr häufig mit den Adressen von Variablen dazu existieren in C/C++ die Pointer (oder Zeiger) Ein Pointer ist eine Variable, welche eine Adresse enthält Wenn der Pointer die Adresse einer anderen Variable enthält, dann sagt man, dass der Pointer auf diese Variable zeigt Diese andere Variable wird oft als Objekt bezeichnet Das hat aber nichts mit Objekten im Sinne der OO-Programmierung zu tun Pointer Objekt Marc Rennhard, , CPP_ArraysPointer.ppt 16 In einer normalen Variablen steht immer der Wert, den man in dieser Variablen speichern will. Ein int a beansprucht zb meist 4 Bytes Speicher und in diesen 4 Bytes steht der entsprechende int- Wert, zb 68. Ein Pointer, int* ap, ist auch eine Variable und beansprucht auf 32-Bit Architekturen ebenfalls 4 Bytes Speicher; an diesen 4 Bytes steht aber nicht irgendein Zahlenwert, sondern eine Speicheradresse einer anderen Variable. Man sagt dann, dass der Pointer auf diese andere Variable zeigt, denn er enthält ja deren Adresse. Belegt a im Speicher die Adressen 112, 113, 114 und 115 und zeigt ap auf a, so steht in ap die tiefste der Adressen von a, also 112. Als Java-Programmierer kennen Sie keine Pointer, obwohl die Referenzen auf Objekte eigentlich auch Pointer sind auch wenn der Programmierer dies nicht direkt sieht. 16
17 Pointer (2) Bei der Deklaration eines Pointers wird der Typ des Objekts, auf welches der Pointer zeigt, angegeben: int *p; /* p ist ein Pointer auf ein Objekt vom Typ int */ int* p; /* Eine andere Schreibweise für das Gleiche */ double *d[20]; /* d ist ein Array von 20 Pointern auf Objekte vom Typ double */ double (*d)[20]; /* d ist ein Pointer auf einen double Array mit 20 Elementen */ char **ppc; /* Pointer auf einen Pointer auf ein Objekt vom Typ char */ Marc Rennhard, , CPP_ArraysPointer.ppt 17 Betreffend der Schreibweise ist int* p oft klarer als int *p, denn damit liest man den Datentyp als Pointer auf int und den Namen der Variable als p. Die vierte Zeile, double (*d)[20] ist gewöhnungsbedürftig, eigentlich wäre double[20]* d einleuchtender ( d ist ein Pointer auf einen double[20]-array ), aber die Sprache lässt die nicht zu. Es mag erstaunen, dass bei der Deklaration eines Pointers der Datentyp des Objekts, auf welchen der Pointer zeigen wird, angegeben werden muss. Ein Pointer enthält ja schliesslich einfach eine Speicheradresse und die ist immer gleich gross, egal ob der Pointer auf einen int oder einen double zeigt. Der Grund, wieso die Angabe des Datentyps notwendig ist wird klar, sobald wir uns weiter hinten im Kapitel mit Pointerarithmetik befassen werden. 17
18 Pointer (3) Achtung: int *p, q; /* p ist ein Pointer auf ein Objekt vom Typ int, q ist eine Variable vom Typ int */ int *p, *q; /* p und q sind Pointer auf ein Objekt vom Typ int */ Es gibt zwei Operatoren im Zusammenhang mit Pointern: Der Referenzoperator oder Adressoperator & liefert die Adresse eines Objekts Der Dereferenzoperator oder Zugriffsoperator * kann auf Pointer angewendet werden, und liefert die Daten des Objekts, auf welches der Pointer zeigt int i; /* eine Variable vom Typ int int *ip; /* ein Pointer auf int */ ip = &i; /* Zuweisung der Adresse von i; ip zeigt jetzt auf i */ *ip = 3; /* ip wird dereferenziert und dem Objekt wird 3 zugewiesen; die Variable i ist jetzt also 3 */ i: ip: 3 * & Marc Rennhard, , CPP_ArraysPointer.ppt 18 Bei der Deklaration gehört * zum Variablennamen, auch wenn er beim Typ geschrieben wird. Bei int* p, q; ist also nur p ein Pointer. Der Name Referenzoperator, kommt daher, dass man eine Adresse auch eine Referenz nennt. 18
19 Pointer (4) Da Pointer eine Adresse enthalten, sind sie auf Computern mit einer 32- bit Architektur (zb Intel Pentium xy) typischerweise 4 Bytes gross Typischer Fehler mit Pointern: int *ip; *ip = 25; ip:? Pointer werden in C wie einfache Variablen behandelt, es gibt also auch für Pointer keine Default-Werte In der ersten Zeile wird zwar ein Pointer auf einen int deklariert, und der dazugehörige Speicherplatz reserviert, aber der Wert von ip ist noch nicht definiert In der zweiten Zeile wird deshalb irgendeine Stelle im Speicher mit 25 überschrieben mysteriöse Programmabstürze möglich Marc Rennhard, , CPP_ArraysPointer.ppt 19 Unabhängig davon, ob ein Pointer auf einen int, double, long etc. zeigt ist die Variable mit dem Pointer immer gleich gross heute meist 4 Bytes. 19
20 void Pointer Pointer können auch vom Typ void sein; ein solcher Pointer kann auf irgendetwas zeigen double d; double *dp1 = &d; void *vp = dp1; Um einen void Pointer in einen expliziten Typen zu konvertieren, wird in C++ ein cast benötigt (optional in C) double *dp2; dp2 = (double *) vp; void Pointer sind nützlich, um mit einem Pointer einen Block von Daten zu referenzieren, ohne zu wissen, was in den Daten drinsteht oder wozu der Datenblock gebraucht wird malloc (um dynamisch Speicher zu allozieren, siehe später in dieser Vorlesung) liefert z.b. einen void Pointer auf einen Datenbereich, denn malloc weiss nicht, wofür dieser Datenbereich gebraucht wird Marc Rennhard, , CPP_ArraysPointer.ppt 20 20
21 Pointer und const double *cdp; double *const cdp; const double *dp; /* Pointer auf double, *cdp = 5.0 und cdp++ möglich */ /* Konstanter Pointer, *cdp = 5.0 möglich, nicht aber cdp++ */ /* Pointer auf Konstante, cdp++ möglich, nicht aber *cdp = 5.0 */ const double *const dp; /* Konstanter Pointer auf Konstante, cdp++ und *cdp = 5.0 nicht möglich*/ Beispiele: const double pi = ; /* Konstante pi, Wert kann nicht mehr verändert werden */ double *dp = π /* Fehler, Vermeiden von *dp = 5.0 */ double *const dp = π /* Fehler, Vermeiden von *dp = 5.0 */ const double *dp = π /* OK, Pointer auf Konstante, *dp = 5.0 nicht mehr möglich */ const double *const dp = π /* OK, Konstanter Pointer auf Konstante */ Marc Rennhard, , CPP_ArraysPointer.ppt 21 Steht ein const rechts vom *, so ist der Pointer konstant. Steht ein const links vom *, so ist das Objekt, auf welches der Pointer zeigt, konstant. Die beiden mit Fehler bezeichneten Situationen oben müssen übrigens nicht unbedingt in einem Kompilierfehler resultieren. Je nach Compiler wird auch nur eine Warnung ausgegeben (bei gcc ist dies z.b. der Fall, g++ gibt hingegen einen Fehler aus), d.h. das ausführbare Programm wird trotzdem generiert. In diesem Fall ist es dann auch möglich, über den Umweg eines Pointers (der nicht auf eine Konstante zeigt), eine zuvor mit const deklarierte Variable trotzdem zu verändern. Ein umsichtiger Programmierer sollte generell immer auf Warnungen des Compilers reagieren, da diese meist auf eine sehr wahrscheinliche Fehlersituation aufmerksam machen. Im obigen Fall sollte sich der Programmierer also überlegen, ob pi wirklich konstant sein soll (und in diesem Fall den Pointer so anpassen, dass es ein Pointer auf eine Konstante ist) oder allenfalls pi als nicht konstant deklarieren, falls die Variable tatsächlich modifizierbar sein soll. 21
22 Pointer und NULL Die Adresse 0 ist in einem C/C++ Programm niemals eine gültige Speicheradresse Wird deshalb oft für einen Pointer verwendet, der explizit auf nichts zeigt stdio.h definiert dafür eine symbolische Konstante NULL Gibt eine Funktion einen Pointer zurück, wird der Rückgabewert NULL zudem oft verwendet, um abnormales Verhalten zu signalisieren /* null_pointer.c, gibt drei Zeilen aus */ #include <stdio.h> int main(void) { int *p1 = 0; /* das funktioniert */ int *p2 = NULL; /* das ist aber sauberer */ } if (p1 == NULL) printf("p1 ist NULL\n"); if (p2 == 0) printf("p2 ist 0\n"); if (p1 == p2) printf("p1 ist gleich p2\n"); Marc Rennhard, , CPP_ArraysPointer.ppt 22 22
23 Übung zu Pointern Geben Sie jeweils die Werte der Variablen nach der Ausführung der einzelnen Programmzeilen an /* pointers.c */ int main(void) { int *ap, *bp; int c = 5, d; } ap = &c; /* ap = *ap = 5 */ c++; /* c = 6 *ap = 6 */ *ap = -10; /* c = -10 *ap = -10 */ bp = &c; c = 15; /* *ap = 15 *bp = 15 */ *bp = *ap / 2; /* c = 7 */ ap = &d; /* *ap = *bp = 7 */ d = 3; /* *ap = 3 *bp = 7 */ Marc Rennhard, , CPP_ArraysPointer.ppt 23 23
24 Arrays und Pointer (1) In C gibt es einen klaren Zusammenhang zwischen Arrays und Pointer: Der Name des Arrays stellt die fixe Startadresse des Arrays dar, diese Adresse kann nicht verändert werden Wird ein Array in einem Ausdruck verwendet, so wird er vom Compiler immer implizit in den entsprechenden Pointer konvertiert Beispiel: int a[3] = {2, 4, 6}; int b[3] = {2, 4, 6}; int *pa; a == b; /* ist false, weil die Startadressen von a und b unterschiedlich sind! */ a = b; /* Kompilierfehler, weil die Startadresse nicht veränderbar ist */ pa = a; /* OK, a wird in int* const konvertiert pa zeigt jetzt auf den Array a; genauer: auf das erste Element a[0] */ pa: a: b: Marc Rennhard, , CPP_ArraysPointer.ppt 24 In C gibt es eigentlich auch keine Arrays. Ein Array ist einfach ein zusammenhängender Speicherbereich, wobei der Anfang dieses Bereichs mit einem konstanten Pointer spezifiziert wird (Startadresse). Arrays in C sind also eigentlich nur syntactic sugar und der Compiler arbeitet dabei nur mit Pointern. Bei der letzten Zeile im Beispiel (pa = a) wird ein konstanter Pointer einem Pointer zugewiesen das ist völlig legal und pa wird dadurch keineswegs konstant. Der Array selbst wird aber nicht kopiert (sondern nur dessen die Staradresse) und ist auch nach der Zuweisung nur einmal im Speicher vorhanden! 24
25 Arrays und Pointer (2) Zugriff auf Elemente eines Array bisher: Verwendung der Indices int a[4] = {2, 4, 6, 8}; int b = 3; a[0] = a[1] + a[2]; a[3] = b; b = a[2]; a: Speicherdressen (zb): In C wird ein Array wird im Speicher immer linear abgespeichert (die Elemente folgen nacheinander) auch mit Pointern kann auf die einzelnen Elemente zugegriffen werden Einen Fall kennen wir bereits, den Zugriff auf das erste Element: int a[3] = {2, 4, 6}; int *pa = a; /* pa zeigt jetzt auf a und damit auf a[0] */ *pa = 7; /* entspricht a[0] = 7; a[0] ist jetzt 7 */ Allg. Zugriff auf Elemente im Array mit Pointern: Pointerarithmetik Marc Rennhard, , CPP_ArraysPointer.ppt 25 25
26 Pointerarithmetik (1) Ausser den bereits eingeführten speziellen Pointeroperatoren (* und &) sind diverse weitere Operatoren auf Pointer anwendbar: Vergleichsoperatoren: ==,!=, <, >, <=, >= Addition + und Subtraktion Inkrement ++, Dekrement -- und zusammengesetzte Operatoren +=, = Regel: ist pa ein Pointer auf das erste Element eines Arrays, so zeigt (pa + i) auf das i-te Element dieses Arrays Beispiel: int a[5] = {2, 4, 6, 8, 10}; int *pa = a; Diese Ausdrücke sind äquivalent pa: und bezeichnen das Arrayelement mit Index 2: a[2]; *(pa + 2); *(a + 2); pa[2]; (pa + 1) (pa + 3) Der Compiler wandelt generell alle Zugriffe der Form x[n] in *(x + n) um; unabhängig davon, ob x der Name eines Arrays oder ein Pointer ist! a: Marc Rennhard, , CPP_ArraysPointer.ppt 26 26
27 Pointerarithmetik (2) Damit die Pointerarithmetik richtig funktioniert, wird der Datentyp des Pointers berücksichtigt: int a[5] = {2, 4, 6, 8, 10}; int *pa = a; /* pa zeigt auf das erste Element im Array */ int *pb = pa; /* pb zeigt auch auf das erste Element im Array */ pa++; /* pa zeigt auf das nächste Element im Array, dabei wurde der Wert von pa typischerweise um 4 inkrementiert (typischer Speicherplatz eines int in Bytes) und nicht einfach nur im 1! */ pb += 3; /* pb zeigt auf das Element mit Index 3 im Array, wodurch der Wert von pb um 3 * 4 = 12 (und nicht nur um 3) inkrementiert wurde */ Die Adressen einzelner Elemente im Array können mit dem Referenzoperator auch direkt einem Pointer zugewiesen werden: int a[5] = {2, 4, 6, 8, 10}; int *pa = &a[2]; *(pa + 2) = 13; /* a[4] ist jetzt = 13 */ *(pa - 2) = 20; /* a[0] ist jetzt = 20 */ Marc Rennhard, , CPP_ArraysPointer.ppt 27 Würde statt int* zb double* verwendet, so wirkt sich eine Operation +1 auf den Pointer effektiv um +8 aus (Annahme: ein double braucht 8 bytes Speicherplatz). Bei char* ist es effektiv ein +1 auf der Adresse, da ein char 1 Bytes beansprucht. 27
28 Pointerarithmetik (3) Diese Programme sind alle äquivalent! int main(void) { int a[5]; int i; int main(void) { int a[5]; int *pi = a; int *pe = &a[4]; } for (i = 0; i < 5; i++) { a[i] = 0; /* od *(a + i) = 0; */ } } for (; pi <= pe; pi++) { *pi = 0; } int main(void) { int a[5]; int *pi = a; int i; } for (i = 0; i < 5; i++) { *(pi + i) = 0; /* oder pi[i] = 0; */ } pi: pe: a: Marc Rennhard, , CPP_ArraysPointer.ppt 28 28
29 Übung zu Arrays und Pointer Erklären Sie, was bei der Ausführung des folgenden Programms geschieht: /* arraypointer.c */ #include <stdio.h> int main(void) { double table[10]; double *pt, *qt; pt = table; *pt = 0; *(pt + 2) = 3.14; pt[5] = 2.5; /* Inhalt von table[i]? */ pt = table + 2; qt = pt; *qt = 2.718; qt[4] = 3.5;... }... *(table + 8) = 6.7; /* Inhalt von table[i]? */ pt = table; qt = table + 10; printf("%d\n", qt pt); /* Ausgabe? */ printf("%d\n", (int)qt (int)pt); /* Ausgabe? */ for (; pt < qt; pt++) { *pt = 1.23; } /* Inhalt von table[i]? */ Marc Rennhard, , CPP_ArraysPointer.ppt 29 29
30 String Literals und Pointer Man kann Arrays und Pointer mit einem String Literal initialisieren: char a[] = "hello, world"; char *pa = "hello, world"; Fast identisch, aber ein wichtiger Unterschied: a ist ein char-array und stellt dessen fixe Startadresse dar a kann nie auf einen anderen Speicherbereich zeigen pa ist eine Pointervariable, die die Startadresse des char-arrays enthält kann später auch pa: einen anderen Wert erhalten Beispiel: a: h e l l o, w o r l d \0 h e l l o, w o r l d \0 char a[] = "hello, Winterthur"; char *pa = "hello, Switzerland"; a = pa; /* Kompilierfehler */ pa = a; /* OK, zeigt auf "hello, Winterthur" */ Marc Rennhard, , CPP_ArraysPointer.ppt 30 Diese Initialisierung funktioniert nur mit char-arrays/pointer und String Literals. Für andere Typen, zb int, geht dies nicht: int a[] = {1, 2, 3}; /* OK */ int *pa = {1, 2, 3}; /* Kompilierfehler */ Die beiden obigen Varianten mit den String Literals haben einen weiteren Unterschied. Im ersten Fall (a[]) wird der Speicherplatz für den Array ganz normal auf dem Stack alloziert. Im zweiten Fall liegt nur der Pointer (*pa) auf dem Stack, während der Array selbst im Code-Segment liegt. Deshalb kann pa zwar einerseits während des Programms eine andere Adresse zugewiesen erhalten (also auf einen Anderen Array zeigen), man kann den bei der Initialisierung angegebenen char-array aber nicht verändern. Folgendes Programm, das zu einem Laufzeitfehler (Segmentation Fault) führt, illustriert dies: int main(void) { char a[] = "hello, world"; char *pa = "hello, world"; a1[7] = W ; /* OK, da a1 auf dem Stack liegt */ a2[7] = W ; /* Segmentation Fault, da der Array im Code-Segment (read-only) liegt */ } 30
31 2 Dimensionale Arrays und Pointer (1) Bisher haben wir die Beziehung von Array und Pointer nur für den Fall des 1-Dimensionalen Arrays betrachtet Dabei gelten folgende Regeln: Der Name des Arrays stellt die fixe Startadresse des Arrays dar, diese Adresse kann nicht verändert werden Wird ein Array in einem Ausdruck verwendet, so wird er implizit in den entsprechenden Pointer konvertiert Basierend auf den Regeln der Pointerarithmetik gilt: int a[5] = {1, 2, 3, 4, 5}; int *pa = a; /* Alle folgenden Ausdrücke sind äquivalent */ a[3]; pa[3]; *(a + 3); *(pa + 3); Marc Rennhard, , CPP_ArraysPointer.ppt 31 31
32 2 Dimensionale Arrays und Pointer (2) Im folgenden zeigen wir, dass die Array-Pointer-Beziehung auch bei 2- Dimensionalen Arrays gilt Zuerst etwas Repetition: wir betrachten die Datentypen im Zusammenhang mit einen 1-Dimensionalen Array: char module[4] = "CPP" Was sind die Typen von module, module[2] und module + 3? module: char[4] (gemäss Deklaration) module[2]: char (Zugriff auf das Element mit Index 2 des Arrays) module + 3: char* (Verwendung von module in einem Audruck char*, module + 3 zeigt auf das Element mit Index 3) Marc Rennhard, , CPP_ArraysPointer.ppt 32 32
33 2 Dimensionale Arrays und Pointer (3) Betrachten wir einen 2-Dimensionalen Array, der die Monatsnamen speichert (dieses Beispiel stammt aus dem Buch Mastering C++ von Cay S. Horstmann): char month[12][10] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; Der resultierende Array braucht einen Speicherplatz von 12 * 10 = 120 Bytes Die 12 einzelnen Arrays mit den Monatsnamen sind nacheinander im Speicher angeordnet: Zuerst 10 Zeichen für January\0, wovon 2 Zeichen nicht gebraucht werden dann 10 Zeichen für February\0 etc. Die Adresse von 'F' in February ist deshalb um 10 Bytes grösser als die Adresse des 'J' in January Was sind die Datentypen von month, month[2], month + 2, month[2][3], oder month[2] + 3? Was ist der Zusammenhang dieser Ausdrücke? month: January\0 February\0 March\0 April\0 May\0 June\0 July\0 August\0 September\0 October\0 November\0 December\0 Marc Rennhard, , CPP_ArraysPointer.ppt 33 33
34 2 Dimensionale Arrays und Pointer (4) Die Antworten sind durch die Array-Pointer-Beziehung von 1-Dimensionalen Arrays bestimmt: month hat den Datentyp char[12][10] (gemäss Deklaration); diesen 2-Dimensionalen Array mit char-elementen kann man auch als ein 1-Dimensionaler Array mit 12 Elementen auffassen, wobei die Elemente wiederum 1-Dimensionale Arrays vom Typchar[10] sind month[2] greift auf einen dieser 12 Arrays zu (auf den mit Index 2) und ist deshalb vom Typ char[10] month[2][3] wiederum bezeichnet ein Element (Index 3) des Arrays month[2] und hat damit den Datentyp char month[2] + 3: month[2] ist vom Typ char[10] (1-D Array) und wird in einem Ausdruck verwendet, also ist month[2] + 3 vom Typ char* month + 2: month ist ein 1-Dimensionaler Array mit Elementen vom Typ char[10] und wird in einem Ausdruck verwendet; dabei wird der Typ zu Pointer auf einenchar Array mit 10 Elementen, was alschar(*)[10] geschrieben wird Marc Rennhard, , CPP_ArraysPointer.ppt 34 34
35 2 Dimensionale Arrays und Pointer (5) Die nebenstehende Abbildung zeigt, welche Bereiche der Tabelle durch die Ausdrücke identifiziert werden Daraus sieht man, dass folgende Zusammenhänge gelten: *(month + 2) = month[2] *(month[2] + 3) = month[2][3] month January\0 February\0 month[2] March\0 April\0 month month[2] + 3 month[2][3] Dies geht auch auf, wenn die Datentypen betrachtet werden: month + 2: char(*)[10], month[2]: char[10] month[2] + 3: char*, month[2][3]: char Daraus folgt, dass bei 2-Dimensionalen Arrays die Array-Pointer- Beziehung sowohl in der ersten als auch in der zweiten Dimension gilt Treibt man dies weiter: generell gilt die Beziehung für alle Dimensionen eines n-dimensionalen Arrays Marc Rennhard, , CPP_ArraysPointer.ppt 35 Die Adressen, auf welche die Pointer month + 2 und month[2] + 3 zeigen, ergeben sich wie folgt (basiert auf der vorhergehenden Folie): month identifiziert die Startadresse des ganzen, 2-Dimensionalen Arrays. In einem Ausdruck wird der Typ von month zu char(*)[10], und identifiziert damit einen Datenbereich der Grösse von 10 char, also (im Normalfall wenn 1 char mit 1 Byte dargestellt wird) 10 Bytes. Daraus folgt, dass month Bytes grösser als die Staradresse von month ist (2 * 10 wegen Pointerarithmetik) und damit auf den Beginn des 21. Zeichens zeigt, was dem Array mit Monatsnamen March entspricht. month[2] identifiziert die Startadresse des Arrays mit Index 2, als der, in welchem March steht. In einem Ausdruck wird month[2] zum Datentyp char* und zeigt auf einen Datenbereich der Grösse 1 Byte (= 1 Zeichen). Daraus folgt, dass month[2] Bytes grösser als die Startadresse von month[2] ist (3 * 1 wegen Pointerarithmetik) und auf das Zeichen c im Array mit March zeigt. 35
36 2 Dimensionale Arrays und Pointer (6) Das Speichern von mehreren Strings (oder Arrays verschiedener Längen im Allgemeinen) als 2-Dimensionaler Array ist nicht effizient, weil jeder einzelne String soviel Speicher wie der längste dieser Strings braucht Besser: wir Speichern die einzelnen Strings als 1-Dimensionale Arrays irgendwo und merken uns deren Speicherstellen in einem Array von Pointern: char* pmonth[12] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; Die 12 Elemente in pmonth (Startadressen der Strings) sind immer noch linear nacheinander im Speicher angeordnet Es gibt jedoch keine Garantie, dass auch die einzelnen Strings selbst nacheinander im Speicher liegen! pmonth: January\0 February\0 March\0 April\0... Marc Rennhard, , CPP_ArraysPointer.ppt 36 36
37 2 Dimensionale Arrays und Pointer (7) Wiederum bestimmen wir die Datentypen: pmonth hat den Datentyp char*[12] (gemäss Deklaration) und ist ein 1-Dimensionaler Array mit 12 Elementen vom Typchar* pmonth[2] greift auf eines der 12 Arrayelemente in pmonth zu (auf das mit Index 2) und ist deshalb vom Typchar* pmonth[2] + 3: pmonth[2] ist vom Typ char*, also ist pmonth[2] + 3 ebenfalls vom Typ char* pmonth + 2: pmonth ist vom Typ char*[12] (1-D Array mit char* Elementen) und wird in einem Ausdruck verwendet, also ist pmonth + 2 vom Typ char** (Pointer auf einen Pointer auf einenchar) Marc Rennhard, , CPP_ArraysPointer.ppt 37 37
38 2 Dimensionale Arrays und Pointer (8) Wiederum zeigt die Abbildung, welche Bereiche der Tabelle durch die Ausdrücke identifiziert werden pmonth pmonth[2] pmonth + 2 January\0 February\0 March\0 April\0 Die Array-Pointer-Beziehung... in der ersten Dimension gilt immer noch: pmonth[2] + 3 *(pmonth + 2) = pmonth[2] pmonth[2] + 3 zeigt auf das gleiche pmonth[2][3] Zeichen wie month[2] + 3 im 2-Dimensionalen Array, nämlich auf das Zeichen c in March und hat auch den gleichen Datentyp (char*) Wir wissen: beim 2-Dimensionalen Array ist wegen der Array-Pointer- Beziehung *(month[2] + 3) dasselbe wie month[2][3] Ein C-Compiler wandelt Ausdrücke wie month[2][3] konsequent in *(month[2] + 3) um, deshalb kann auch pmonth[2][3] geschrieben werden, um das Zeichen c in March zu bezeichnen Fazit: man kann auch mit einem Array von Pointern auf Arrays so tun, als ob es ein 2-Dimensionaler Array wäre und mit der gewohnten Schreibweise auf Elemente zugreifen: pmonth[2][3] Marc Rennhard, , CPP_ArraysPointer.ppt 38 Die Adressen, auf welche die Pointer pmonth + 2 und pmonth[2] + 3 zeigen, ergeben sich wie folgt (basiert auf der vorhergehenden Folie): pmonth identifiziert die Startadresse des 1-Dimensionalen Arrays. In einem Ausdruck wird der Typ von pmonth zu char** (also ein Pointer auf eine variable, die wiederum einen Pointer bzw. eine Adresse enthält), und identifiziert damit einen Datenbereich der Grösse von 4 Bytes (wenn wir annehmen, dass char* 4 Bytes benötigt, was auf einer 32-bit Architektur eigentlich immer der Fall ist). Daraus folgt, dass pmonth Bytes grösser als die Startadresse von pmonth ist (2 * 4 wegen Pointerarithmetik) und damit auf das 3. Element im Array pmonth zeigt, das wiederum die Adresse des Arrays mit Monatsnamen March enthält. pmonth[2] identifiziert die Startadresse des Arrays, in welchem March steht und hat den Datentyp char*, zeigt also auf einen Datenbereich der Grösse 1 Byte (= 1 Zeichen). Daraus folgt, dass pmonth[2] Bytes grösser als pmonth[2] ist (3 * 1 wegen Pointerarithmetik) und damit auf das Zeichen c im Array mit March zeigt. Es scheint erstaunlich, dass man pmonth[2][3] verwenden darf, obwohl gar kein richtiger 2- Dimensionaler Array dahinter steckt. Der Grund, warum es funktioniert, liegt an der Tatsache, dass ein C-Compiler immer alle Array-Zugriffe in entsprechende Pointeroperationen umwandelt (hier in *(pmonth[2] + 3)), unabhängig davon, ob ein richtiger 2-Dimensionaler Array oder nur ein Array von Pointern auf Arrays verwendet wird. 38
39 Übung zu 2-Dimensionalen Arrays und Pointer Was wird bei diesem Programm ausgegeben? Tipp: sizeof(a) gibt die Anzahl Bytes zurück, welche der Datentyp von a beansprucht /* 2d.c */ #include <stdio.h> int main(void) { char days[7][10] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; char *pdays[7] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; } printf("%d %d\n", sizeof(days), sizeof(pdays)); printf("%d %d\n", sizeof(days + 1), sizeof(pdays + 1)); printf("%d %d\n", sizeof(days[1]), sizeof(pdays[1])); printf("%s %s\n", days[4], pdays[4]); printf("%d\n", days[4] - days[1]); printf("%d\n", pdays[4] - pdays[1]); printf("%d\n", &days[2][3] - &days[0][0]); printf("%d\n", &pdays[2][3] - &pdays[0][0]); Marc Rennhard, , CPP_ArraysPointer.ppt 39 39
40 Statisch und dynamisch allozierter Speicher Bis jetzt haben wir uns nicht darum gekümmert, wie/wo der Speicherplatz für Variablen alloziert wird Per Default wird dieser Speicherplatz immer statisch alloziert (auf dem Stack) Der Speicherplatz kann aber auch dynamisch (auf dem Heap) alloziert werden Speicherorganisation (aus der Sicht eines ausführenden Programms): Aufsteigende Speicheradressen Code Heap Stack Dynamischer Speicherbereich: alle mit malloc (C) und new (C++) erzeugten Variablen Statischer Speicherbereich: alle lokalen Variablen und Parameterübergabe an Funktionen Marc Rennhard, , CPP_ArraysPointer.ppt 40 Der Speicherbereich sämtlicher lokaler Variablen und Funktionsparameter wird während des Kompilierens durch den Compiler festgelegt; der entsprechende Speicherplatz befindet sich auf dem Stack. Weil der Programmierer darauf während der Ausführung des Programms keinen Einfluss nehmen kann, wird dieser Speicherbereich als statisch alloziert bezeichnet. Weil nach Verlassen einer Funktion der Stack immer wieder auf den Stand vor dem Eintritt in die Funktion abgebaut wird, muss man sich um lokale Variablen und Übergabeparameter nicht kümmern. Diese Variablen werden deshalb auch automatischen Variablen genannt eben weil sie automatisch kreiert werden und wieder verschwinden. Im Gegensatz dazu bezeichnet dynamisch allozierter Speicher den Speicher, den der Programmierer während der Laufzeit nach Bedarf alloziert (kreiert). Dies ist immer dann nötig, wenn der Programmierer zur Entwicklungszeit nicht weiss, wieviel Speicher zur Laufzeit benötigt. Denken Sie zb an ein Programm, das durch eine Liste von Personen durchgeht und diese in den Speicher einliest. Der Programmierer weiss nicht, ob die jeweilig verwendete Liste 5 oder Einträge enthält, deshalb wird er für jede eingelesene Person dynamisch Speicher auf dem Heap allozieren. Natürlich könnte der Programmierer im Programm einfach einen Array mit Elementen für die Personen statisch allozieren, dies wäre aber ineffizient, weil das Programm dann in jedem Fall Speicherplatz für Personen beansprucht, auch wenn zb nur 10 Personen eingelesen werden. Ausserdem wird das Programm dann für eine Liste ab Personen nicht mehr funktionieren. Mit dynamischer Speicherallozierung schafft ein Programmierer also die Voraussetzung, dass während der Laufzeit genau so viel Speicherplatz alloziert wird, wie auch benötigt wird. Natürlich ist dies aber nur in den Fällen nötig, wo der Programmierer zur Entwicklungszeit nicht weiss, wieviel Speicher benötigt wird (wie zb beim Einlesen einer unbekannten Anzahl von Personen). 40
41 Dynamisch allozierter Speicher (1) Dynamisch allozierter Speicher wird zur Laufzeit auf dem Heap mit der Standard Library Funktion malloc (stdlib.h) erzeugt: void *malloc(int size) Wird prinzipiell dann gebraucht, wenn zur Kompilierungszeit nicht bekannt ist, wieviel Speicher zur Laufzeit benötigt wird malloc macht zwei Dinge: alloziert Speicher der Grösse size Bytes auf dem Heap Gibt die Adresse (also einen Pointer) dieses Speicherplatz zurück (void *) der Pointer muss noch in den gewünschten Datentyp konvertiert werden Beispiel: int *ip; ip = (int *) malloc(sizeof(int)); *ip = 5; Der sizeof Operator (entweder sizeof(<typ>) oder sizeof(<variable>)) liefert die Grösse (benötigte Anzahl Bytes) des entsprechenden Datentyps ip: 5 Marc Rennhard, , CPP_ArraysPointer.ppt 41 Falls malloc den Speicher nicht allozieren kann, wird NULL zurückgegeben. 41
42 Dynamisch allozierter Speicher (2) Im Gegensatz zu statisch alloziertem Speicher wird dynamisch allozierter Speicher nicht automatisch freigegeben, wenn eine Variable nicht mehr benötigt wird (zb beim Verlassen einer Funktion) Java: dies wird vom Garbage Collector erledigt (kein Pendant zu new) Dynamisch allozierter Speicherplatz wird mit der Standard Library Funktion free (stdlib.h) freigegeben: void free(void *vp) Beispiel: int *ip; ip = (int *) malloc(sizeof(int)); *ip = 5;.. free(ip); /* Speicher wird freigegeben */ ip: 5 Ein Unterlassen der Speicherfreigabe kann langfristig das Programm zum Absturz bringen (sogenannte Memory Leaks)! Marc Rennhard, , CPP_ArraysPointer.ppt 42 Weil der Programmierer selbst den Speicher wieder freigeben muss, darf man den Pointer auf den entsprechenden Speicherbereich nicht verlieren. Wird obiges Beispiel zu int *ip; ip = (int *) malloc(sizeof(int)); /* Speicherbereich 1 */ ip = (int *) malloc(sizeof(int)); /* Speicherbereich 2 */ so wird der Pointer in der dritten Zeile mit der Adresse des Speicherbereichs 2 überschrieben. Die Adresse des Speicherbereichs 1 kennt man dann nicht mehr und man kann ihn auch nicht mehr freigeben. Sämtlicher Speicher wird natürlich immer freigegeben, wenn das Programm terminiert. Trotzdem soll dynamisch allozierter Speicher auch bei den Programmen, die nur wenig Speicher dynamisch allozieren, immer selbst freigegeben werden. Das ist guter Programmierstil und damit kann das Programm einfacher erweitert oder Teile davon wiederverwendet werden. Enthält der Pointer, der der Funktion free übergeben wird, einen ungültigen Wert (er zeigt also nicht auf einen allozierten Speicherbereich), so wird typischerweise zur Laufzeit ein Segmentation Fault produziert und das Programm bricht ab. Die Ausnahme ist, wenn der Pointer den Wert NULL enthält. Dann wird einfach keine Speicherfreigabe erfolgen, d.h. die Funktion free testet, ob der Wert des Pointers NULL ist, bevor Speicher freigegeben wird. Werden also Pointer, die auf Speicherbereiche auf den Heap zeigen, mit NULL initialisiert und nach der Freigabe von Speicher wieder auf NULL gesetzt, so muss der Programmierer nicht vor jeder Freigabe testen, ob der entsprechende Pointer überhaupt auf einen gültigen Speicherbereich auf dem Heap zeigt. 42
43 Dynamisch allozierter Speicher (3) Man kann auch dynamisch Speicher für einen Array allozieren Beispiel: Array für 250 int-werte: int *ap; n = 250; ap = (int *) malloc(n * sizeof(int)); Alloziert im Wesentlichen 1000 Bytes (wenn int = 4 Bytes) Diese 1000 Bytes liegen hintereinander auf dem Heap, Speicherstellen x... (x + 999) ap zeigt auf den Anfang dieses Bereichs Entspricht im Wesentlichen der internen Darstellung eines Arrays Der malloc-funktion ist es egal, wofür der Speicherplatz alloziert wird Sie gibt einfach so viele zusammenhängende Bytes zurück, wie verlangt wird Der Programmierer entscheidet, was er mit dem Speicherplatz tun will Soll es ein Array sein: Normaler Zugriff mit *(ap + 27), ap[200] etc... Marc Rennhard, , CPP_ArraysPointer.ppt 43 43
44 Beispiel zu dynamisch alloziertem Speicher Beide Programme machen im Prinzip das Gleiche Wo liegt der Unterschied? /* zahlen1.c */ #include <stdio.h> int main(void) { int n, i, numbers[100]; /* zahlen2.c */ #include <stdio.h> #include <stdlib.h> int main(void) { int n, i, *numbers; } printf("anzahl Zahlen: "); scanf("%d", &n); for (i = 0; i < n; i++) { printf("%d. Zahl: ", (i + 1)); scanf("%d", &numbers[i]); } printf("die Zahlen sind:"); for (i = 0; i < n; i++) { printf(" %d", numbers[i]); } printf("\n"); } printf("anzahl Zahlen: "); scanf("%d", &n); numbers = (int *) malloc(n*sizeof(int)); for (i = 0; i < n; i++) { printf("%d. Zahl: ", (i + 1)); scanf("%d", &numbers[i]); } printf("die Zahlen sind:"); for (i = 0; i < n; i++) { printf(" %d", numbers[i]); } printf("\n"); free(numbers); Marc Rennhard, , CPP_ArraysPointer.ppt 44 44
45 Strukturen und Pointer Oft verwendet man Pointer auf Strukturen; dabei gibt es eine abgekürzte Schreibweise (->), um auf Elemente in der Struktur zuzugreifen: struct student { /* Deklaration der struct student */ int studnr; char name[30]; char vorname[30]; }; struct student *sp, s; /* sp ist Pointer auf eine Struktur student */ s.studnr = 999; /* Initialisierung von s */ strcpy(s.name, "Mueller"); strcpy(s.vorname, "Max"); sp = &s; /* sp zeigt auf die Struktur s */ printf("student: %s %s, Nr. %d\n", (*sp).name, (*sp).vorname, (*sp).studnr); /* oder besser (wegen Lesbarkeit) /* printf("student: %s %s, Nr. %d\n", sp->name, sp->vorname, sp->studnr); Marc Rennhard, , CPP_ArraysPointer.ppt 45 Eine Struktur kann mit malloc auch dynamisch auf dem Heap alloziert werden: struct *sp; sp = (struct student*) malloc(sizeof(struct student)); 45
46 Zusammenfassung Arrays bieten die Möglichkeit, Elemente des gleichen Datentyps zusammenzufassen Ein String wird in C als char-array dargestellt und durch das Zeichen '\0' (NUL) terminiert Die Standard Library stellt wichtige Funktionen für Operationen auf Strings zur Verfügung Ein Pointer (Zeiger) ist eine Variable, welche eine Adresse enthält; der Pointer zeigt auf ein Objekt (enthält dessen Adresse), welches die eigentlichen Daten enthält In C gibt es einen klaren Zusammenhang zwischen Arrays und Pointer, wobei der Name des Arrays die fixe Startadresse des Arrays darstellt Mittels der Pointerarithmetik kann mit Pointern einfach auf Elemente im Array zugegriffen werden Variablen können statisch (auf dem Stack, Normalfall) und dynamisch (auf dem Heap) alloziert werden Marc Rennhard, , CPP_ArraysPointer.ppt 46 46
M. Graefenhan 2000-12-07. Übungen zu C. Blatt 3. Musterlösung
M. Graefenhan 2000-12-07 Aufgabe Lösungsweg Übungen zu C Blatt 3 Musterlösung Schreiben Sie ein Programm, das die Häufigkeit von Zeichen in einem eingelesenen String feststellt. Benutzen Sie dazu ein zweidimensionales
Einführung in die Java- Programmierung
Einführung in die Java- Programmierung Dr. Volker Riediger Tassilo Horn riediger [email protected] WiSe 2012/13 1 Wichtig... Mittags Pommes... Praktikum A 230 C 207 (Madeleine) F 112 F 113 (Kevin) E
2. Programmierung in C
2. Programmierung in C Inhalt: Überblick über Programmiersprachen, Allgemeines zur Sprache C C: Basisdatentypen, Variablen, Konstanten Operatoren, Ausdrücke und Anweisungen Kontrollstrukturen (Steuerfluss)
5 DATEN. 5.1. Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu
Daten Makro + VBA effektiv 5 DATEN 5.1. Variablen Variablen können beliebige Werte zugewiesen und im Gegensatz zu Konstanten jederzeit im Programm verändert werden. Als Variablen können beliebige Zeichenketten
Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster
Es gibt in Excel unter anderem die so genannten Suchfunktionen / Matrixfunktionen Damit können Sie Werte innerhalb eines bestimmten Bereichs suchen. Als Beispiel möchte ich die Funktion Sverweis zeigen.
Lineargleichungssysteme: Additions-/ Subtraktionsverfahren
Lineargleichungssysteme: Additions-/ Subtraktionsverfahren W. Kippels 22. Februar 2014 Inhaltsverzeichnis 1 Einleitung 2 2 Lineargleichungssysteme zweiten Grades 2 3 Lineargleichungssysteme höheren als
Einführung in die Java- Programmierung
Einführung in die Java- Programmierung Dr. Volker Riediger Tassilo Horn riediger [email protected] WiSe 2012/13 1 Wichtig... Mittags keine Pommes... Praktikum A 230 C 207 (Madeleine + Esma) F 112 F 113
Zählen von Objekten einer bestimmten Klasse
Zählen von Objekten einer bestimmten Klasse Ziel, Inhalt Zur Übung versuchen wir eine Klasse zu schreiben, mit der es möglich ist Objekte einer bestimmten Klasse zu zählen. Wir werden den ++ und den --
Tutorium Rechnerorganisation
Woche 2 Tutorien 3 und 4 zur Vorlesung Rechnerorganisation 1 Christian A. Mandery: KIT Universität des Landes Baden-Württemberg und nationales Grossforschungszentrum in der Helmholtz-Gemeinschaft www.kit.edu
Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen
Binäre Bäume 1. Allgemeines Binäre Bäume werden grundsätzlich verwendet, um Zahlen der Größe nach, oder Wörter dem Alphabet nach zu sortieren. Dem einfacheren Verständnis zu Liebe werde ich mich hier besonders
Modellierung und Programmierung 1
Modellierung und Programmierung 1 Prof. Dr. Sonja Prohaska Computational EvoDevo Group Institut für Informatik Universität Leipzig 19. November 2015 Gültigkeitsbereich (Scope) von Variablen { int m; {
Vorkurs C++ Programmierung
Vorkurs C++ Programmierung Klassen Letzte Stunde Speicherverwaltung automatische Speicherverwaltung auf dem Stack dynamische Speicherverwaltung auf dem Heap new/new[] und delete/delete[] Speicherklassen:
Professionelle Seminare im Bereich MS-Office
Der Name BEREICH.VERSCHIEBEN() ist etwas unglücklich gewählt. Man kann mit der Funktion Bereiche zwar verschieben, man kann Bereiche aber auch verkleinern oder vergrößern. Besser wäre es, die Funktion
1 Vom Problem zum Programm
Hintergrundinformationen zur Vorlesung GRUNDLAGEN DER INFORMATIK I Studiengang Elektrotechnik WS 02/03 AG Betriebssysteme FB3 Kirsten Berkenkötter 1 Vom Problem zum Programm Aufgabenstellung analysieren
17.1.2014 Einführung in die Programmierung Laborübung bei Korcan Y. Kirkici. 12.Übung 13.1. bis 17.1.2014
17.1.2014 Einführung in die Programmierung Laborübung bei Korcan Y. Kirkici 12.Übung 13.1. bis 17.1.2014 1 BEFRAGUNG http://1.bp.blogspot.com/- waaowrew9gc/tuhgqro4u_i/aaaaaaaaaey/3xhl 4Va2SOQ/s1600/crying%2Bmeme.png
Das Typsystem von Scala. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala
Das Typsystem von Scala 1 Eigenschaften Das Typsystem von Scala ist statisch, implizit und sicher 2 Nichts Primitives Alles ist ein Objekt, es gibt keine primitiven Datentypen scala> 42.hashCode() res0:
Fakultät Angewandte Informatik Lehrprofessur für Informatik 23.01.2012
WS 2011/2012 Fakultät Angewandte Informatik Lehrprofessur für Informatik 23.01.2012 Prof. Dr. Robert Lorenz Musterlösung zur Vorlesung Informatik I, Extrablatt zu komplexen Datenstrukturen Aufgabe 45 **
Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag
Ludwig-Maximilians-Universität München WS 2015/16 Institut für Informatik Übungsblatt 9 Prof. Dr. R. Hennicker, A. Klarl Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung:
Deklarationen in C. Prof. Dr. Margarita Esponda
Deklarationen in C 1 Deklarationen Deklarationen spielen eine zentrale Rolle in der C-Programmiersprache. Deklarationen Variablen Funktionen Die Deklarationen von Variablen und Funktionen haben viele Gemeinsamkeiten.
II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:
Technische Informatik für Ingenieure (TIfI) WS 2005/2006, Vorlesung 9 II. Grundlagen der Programmierung Ekkart Kindler Funktionen und Prozeduren Datenstrukturen 9. Datenstrukturen Daten zusammenfassen
Felder, Rückblick Mehrdimensionale Felder. Programmieren in C
Übersicht Felder, Rückblick Mehrdimensionale Felder Rückblick Vereinbarung von Feldern: typ name [anzahl]; typ name = {e1, e2, e3,..., en} Die Adressierung von Feldelementen beginnt bei 0 Die korrekte
1. Man schreibe die folgenden Aussagen jeweils in einen normalen Satz um. Zum Beispiel kann man die Aussage:
Zählen und Zahlbereiche Übungsblatt 1 1. Man schreibe die folgenden Aussagen jeweils in einen normalen Satz um. Zum Beispiel kann man die Aussage: Für alle m, n N gilt m + n = n + m. in den Satz umschreiben:
Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang
sysplus.ch outlook - mail-grundlagen Seite 1/8 Outlook Mail-Grundlagen Posteingang Es gibt verschiedene Möglichkeiten, um zum Posteingang zu gelangen. Man kann links im Outlook-Fenster auf die Schaltfläche
Dr. Monika Meiler. Inhalt
Inhalt 11 Dynamische Feldvereinbarung... 11-2 11.1 Dynamische Vereinbarung von Vektoren... 11-3 11.2 Dynamische Vereinbarung von Matrizen... 11-5 11.3 Die Kommandozeile... 11-8 Propädeutikum 11-1/8 11
PROGRAMMIEREN MIT C. }, wird kompiliert mit dem Befehl. (-o steht für output) und ausgeführt mit dem Befehl
PROGRAMMIEREN MIT C Allgemeine hinweise Alles was hier beschrieben wird, soll auch ausprobiert werden. Warum C? Weil die coolen Dinge mit C am einfachsten gehen. Das werden wir in den folgenden Übungen
Programmierung und Angewandte Mathematik
Programmierung und Angewandte Mathematik C++ /Scilab Programmierung und Einführung in das Konzept der objektorientierten Anwendungen zu wissenschaftlichen Rechnens SS 2012 Ablauf Was sind Funktionen/Methoden
Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = 0.51129 Euro ergeben.
Aufgabe 1.30 : Schreibe ein Programm DM_in_Euro.java zur Umrechnung eines DM-Betrags in Euro unter Verwendung einer Konstanten für den Umrechnungsfaktor. Das Programm soll den DM-Betrag als Parameter verarbeiten.
Das Persönliche Budget in verständlicher Sprache
Das Persönliche Budget in verständlicher Sprache Das Persönliche Budget mehr Selbstbestimmung, mehr Selbstständigkeit, mehr Selbstbewusstsein! Dieser Text soll den behinderten Menschen in Westfalen-Lippe,
Was meinen die Leute eigentlich mit: Grexit?
Was meinen die Leute eigentlich mit: Grexit? Grexit sind eigentlich 2 Wörter. 1. Griechenland 2. Exit Exit ist ein englisches Wort. Es bedeutet: Ausgang. Aber was haben diese 2 Sachen mit-einander zu tun?
Das große ElterngeldPlus 1x1. Alles über das ElterngeldPlus. Wer kann ElterngeldPlus beantragen? ElterngeldPlus verstehen ein paar einleitende Fakten
Das große x -4 Alles über das Wer kann beantragen? Generell kann jeder beantragen! Eltern (Mütter UND Väter), die schon während ihrer Elternzeit wieder in Teilzeit arbeiten möchten. Eltern, die während
Programmierkurs Java
Programmierkurs Java Dr. Dietrich Boles Aufgaben zu UE16-Rekursion (Stand 09.12.2011) Aufgabe 1: Implementieren Sie in Java ein Programm, das solange einzelne Zeichen vom Terminal einliest, bis ein #-Zeichen
Arbeiten mit UMLed und Delphi
Arbeiten mit UMLed und Delphi Diese Anleitung soll zeigen, wie man Klassen mit dem UML ( Unified Modeling Language ) Editor UMLed erstellt, in Delphi exportiert und dort so einbindet, dass diese (bis auf
Anleitung zur Daten zur Datensicherung und Datenrücksicherung. Datensicherung
Anleitung zur Daten zur Datensicherung und Datenrücksicherung Datensicherung Es gibt drei Möglichkeiten der Datensicherung. Zwei davon sind in Ges eingebaut, die dritte ist eine manuelle Möglichkeit. In
Einführung in die C++ Programmierung für Ingenieure
Einführung in die C++ Programmierung für Ingenieure MATTHIAS WALTER / JENS KLUNKER Universität Rostock, Lehrstuhl für Modellierung und Simulation 14. November 2012 c 2012 UNIVERSITÄT ROSTOCK FACULTY OF
Grundlagen von Python
Einführung in Python Grundlagen von Python Felix Döring, Felix Wittwer November 17, 2015 Scriptcharakter Programmierparadigmen Imperatives Programmieren Das Scoping Problem Objektorientiertes Programmieren
40-Tage-Wunder- Kurs. Umarme, was Du nicht ändern kannst.
40-Tage-Wunder- Kurs Umarme, was Du nicht ändern kannst. Das sagt Wikipedia: Als Wunder (griechisch thauma) gilt umgangssprachlich ein Ereignis, dessen Zustandekommen man sich nicht erklären kann, so dass
Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf http://informatik.swoke.de. Seite 1 von 18
Kapitel 3 Datentypen und Variablen Seite 1 von 18 Datentypen - Einführung - Für jede Variable muss ein Datentyp festgelegt werden. - Hierdurch werden die Wertemenge und die verwendbaren Operatoren festgelegt.
Objektorientierte Programmierung
Objektorientierte Programmierung 1 Geschichte Dahl, Nygaard: Simula 67 (Algol 60 + Objektorientierung) Kay et al.: Smalltalk (erste rein-objektorientierte Sprache) Object Pascal, Objective C, C++ (wiederum
2. Semester, 2. Prüfung, Lösung
2. Semester, 2. Prüfung, Lösung Name Die gesamte Prüfung bezieht sich auf die Programmierung in C++! Prüfungsdauer: 90 Minuten Mit Kugelschreiber oder Tinte schreiben Lösungen können direkt auf die Aufgabenblätter
icloud nicht neu, aber doch irgendwie anders
Kapitel 6 In diesem Kapitel zeigen wir Ihnen, welche Dienste die icloud beim Abgleich von Dateien und Informationen anbietet. Sie lernen icloud Drive kennen, den Fotostream, den icloud-schlüsselbund und
Tutorium Informatik 1. Aufgabe 2: Formatierte Ein- und Ausgabe
Tutorium Informatik 1 Aufgabe 2: Formatierte Ein- und Ausgabe Fachbereich: Elektrotechnik Inhaltsverzeichnis 1 Aufgabe 1 2 Benötigte Funktionen und Schlüsselwörter 2 Robert Halas / FH Regensburg - 2003
Tutorial - www.root13.de
Tutorial - www.root13.de Netzwerk unter Linux einrichten (SuSE 7.0 oder höher) Inhaltsverzeichnis: - Netzwerk einrichten - Apache einrichten - einfaches FTP einrichten - GRUB einrichten Seite 1 Netzwerk
Zeichen bei Zahlen entschlüsseln
Zeichen bei Zahlen entschlüsseln In diesem Kapitel... Verwendung des Zahlenstrahls Absolut richtige Bestimmung von absoluten Werten Operationen bei Zahlen mit Vorzeichen: Addieren, Subtrahieren, Multiplizieren
Abamsoft Finos im Zusammenspiel mit shop to date von DATA BECKER
Abamsoft Finos im Zusammenspiel mit shop to date von DATA BECKER Abamsoft Finos in Verbindung mit der Webshopanbindung wurde speziell auf die Shop-Software shop to date von DATA BECKER abgestimmt. Mit
Java Kurs für Anfänger Einheit 5 Methoden
Java Kurs für Anfänger Einheit 5 Methoden Ludwig-Maximilians-Universität München (Institut für Informatik: Programmierung und Softwaretechnik von Prof.Wirsing) 22. Juni 2009 Inhaltsverzeichnis Methoden
Systeme 1. Kapitel 6. Nebenläufigkeit und wechselseitiger Ausschluss
Systeme 1 Kapitel 6 Nebenläufigkeit und wechselseitiger Ausschluss Threads Die Adressräume verschiedener Prozesse sind getrennt und geschützt gegen den Zugriff anderer Prozesse. Threads sind leichtgewichtige
Dynamische Speicherverwaltung
Dynamische Speicherverwaltung INE2 M. Thaler, [email protected] Office TG208 http://www.zhaw.ch/~tham 1 Um was geht es? Bisjetzt Beispiel Ranglistenprogramm für Sportveranstaltungen Besser - genaue Anzahl Teilnehmer
Einführung in die Programmiersprache C
Einführung in die Programmiersprache C Marcel Arndt [email protected] Institut für Numerische Simulation Universität Bonn Der Anfang Ein einfaches Programm, das Hello World! ausgibt: #include
Wichtig ist die Originalsatzung. Nur was in der Originalsatzung steht, gilt. Denn nur die Originalsatzung wurde vom Gericht geprüft.
Das ist ein Text in leichter Sprache. Hier finden Sie die wichtigsten Regeln für den Verein zur Förderung der Autonomie Behinderter e. V.. Das hier ist die Übersetzung der Originalsatzung. Es wurden nur
S7-Hantierungsbausteine für R355, R6000 und R2700
S7-Hantierungsbausteine für R355, R6000 und R2700 1. FB90, Zyklus_R/W Dieser Baustein dient zur zentralen Kommunikation zwischen Anwenderprogramm und dem Modul R355 sowie den Geräten R6000 und R2700 über
Programmierung in C. Grundlagen. Stefan Kallerhoff
Programmierung in C Grundlagen Stefan Kallerhoff Vorstellungsrunde Name Hobby/Beruf Schon mal was programmiert? Erwartungen an den Kurs Lieblingstier Für zu Hause C-Buch online: http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/
192.168.0.1. Wenn wir also versuchen auf einen anderen PC zuzugreifen, dann können wir sowohl per Name als auch mit der Adresse suchen.
Windows Netzwerk Sie haben einen oder mehrere PC mit einander verbunden? Dann sollte man das auch nutzen. Generelles: Ein PC hat in der Regel IMMER eine feste Nummer / Adresse (egal ob wechselnd oder immer
Objektorientierte Programmierung für Anfänger am Beispiel PHP
Objektorientierte Programmierung für Anfänger am Beispiel PHP Johannes Mittendorfer http://jmittendorfer.hostingsociety.com 19. August 2012 Abstract Dieses Dokument soll die Vorteile der objektorientierten
Software Engineering Klassendiagramme Assoziationen
Software Engineering Klassendiagramme Assoziationen Prof. Adrian A. Müller, PMP, PSM 1, CSM Fachbereich Informatik und Mikrosystemtechnik 1 Lesen von Multiplizitäten (1) Multiplizitäten werden folgendermaßen
Die Programmiersprache C99: Zusammenfassung
Die Programmiersprache C99: Zusammenfassung Jörn Loviscach Versionsstand: 7. Dezember 2010, 19:30 Die nummerierten Felder sind absichtlich leer, zum Ausfüllen in der Vorlesung. Videos dazu: http://www.youtube.com/joernloviscach
infach Geld FBV Ihr Weg zum finanzellen Erfolg Florian Mock
infach Ihr Weg zum finanzellen Erfolg Geld Florian Mock FBV Die Grundlagen für finanziellen Erfolg Denn Sie müssten anschließend wieder vom Gehaltskonto Rückzahlungen in Höhe der Entnahmen vornehmen, um
Ordner Berechtigung vergeben Zugriffsrechte unter Windows einrichten
Ordner Berechtigung vergeben Zugriffsrechte unter Windows einrichten Was sind Berechtigungen? Unter Berechtigungen werden ganz allgemein die Zugriffsrechte auf Dateien und Verzeichnisse (Ordner) verstanden.
Austausch- bzw. Übergangsprozesse und Gleichgewichtsverteilungen
Austausch- bzw. Übergangsrozesse und Gleichgewichtsverteilungen Wir betrachten ein System mit verschiedenen Zuständen, zwischen denen ein Austausch stattfinden kann. Etwa soziale Schichten in einer Gesellschaft:
Einführung in die Programmierung
: Inhalt Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund - mit / ohne Parameter - mit / ohne Rückgabewerte
Objektbasierte Entwicklung
Embedded Software Objektbasierte Entwicklung Objektorientierung in C? Prof. Dr. Nikolaus Wulff Objektbasiert entwickeln Ohne C++ wird meist C im alten Stil programmiert. => Ein endlose while-schleife mit
Ziel, Inhalt. Programmieren in C++ Wir lernen wie man Funktionen oder Klassen einmal schreibt, so dass sie für verschiedene Datentypen verwendbar sind
Templates und Containerklassen Ziel, Inhalt Wir lernen wie man Funktionen oder Klassen einmal schreibt, so dass sie für verschiedene Datentypen verwendbar sind Templates und Containerklassen 1 Ziel, Inhalt
Die Post hat eine Umfrage gemacht
Die Post hat eine Umfrage gemacht Bei der Umfrage ging es um das Thema: Inklusion Die Post hat Menschen mit Behinderung und Menschen ohne Behinderung gefragt: Wie zufrieden sie in dieser Gesellschaft sind.
Urlaubsregel in David
Urlaubsregel in David Inhaltsverzeichnis KlickDown Beitrag von Tobit...3 Präambel...3 Benachrichtigung externer Absender...3 Erstellen oder Anpassen des Anworttextes...3 Erstellen oder Anpassen der Auto-Reply-Regel...5
4 Aufzählungen und Listen erstellen
4 4 Aufzählungen und Listen erstellen Beim Strukturieren von Dokumenten und Inhalten stellen Listen und Aufzählungen wichtige Werkzeuge dar. Mit ihnen lässt sich so ziemlich alles sortieren, was auf einer
Zahlensysteme: Oktal- und Hexadezimalsystem
20 Brückenkurs Die gebräuchlichste Bitfolge umfasst 8 Bits, sie deckt also 2 8 =256 Möglichkeiten ab, und wird ein Byte genannt. Zwei Bytes, also 16 Bits, bilden ein Wort, und 4 Bytes, also 32 Bits, formen
Anleitung über den Umgang mit Schildern
Anleitung über den Umgang mit Schildern -Vorwort -Wo bekommt man Schilder? -Wo und wie speichert man die Schilder? -Wie füge ich die Schilder in meinen Track ein? -Welche Bauteile kann man noch für Schilder
Primzahlen und RSA-Verschlüsselung
Primzahlen und RSA-Verschlüsselung Michael Fütterer und Jonathan Zachhuber 1 Einiges zu Primzahlen Ein paar Definitionen: Wir bezeichnen mit Z die Menge der positiven und negativen ganzen Zahlen, also
Eva Douma: Die Vorteile und Nachteile der Ökonomisierung in der Sozialen Arbeit
Eva Douma: Die Vorteile und Nachteile der Ökonomisierung in der Sozialen Arbeit Frau Dr. Eva Douma ist Organisations-Beraterin in Frankfurt am Main Das ist eine Zusammen-Fassung des Vortrages: Busines
Was ist Sozial-Raum-Orientierung?
Was ist Sozial-Raum-Orientierung? Dr. Wolfgang Hinte Universität Duisburg-Essen Institut für Stadt-Entwicklung und Sozial-Raum-Orientierte Arbeit Das ist eine Zusammen-Fassung des Vortrages: Sozialräume
L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016
L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016 Referentin: Dr. Kelly Neudorfer Universität Hohenheim Was wir jetzt besprechen werden ist eine Frage, mit denen viele
Anwendungsbeispiele Buchhaltung
Rechnungen erstellen mit Webling Webling ist ein Produkt der Firma: Inhaltsverzeichnis 1 Rechnungen erstellen mit Webling 1.1 Rechnung erstellen und ausdrucken 1.2 Rechnung mit Einzahlungsschein erstellen
Zwischenablage (Bilder, Texte,...)
Zwischenablage was ist das? Informationen über. die Bedeutung der Windows-Zwischenablage Kopieren und Einfügen mit der Zwischenablage Vermeiden von Fehlern beim Arbeiten mit der Zwischenablage Bei diesen
Das Leitbild vom Verein WIR
Das Leitbild vom Verein WIR Dieses Zeichen ist ein Gütesiegel. Texte mit diesem Gütesiegel sind leicht verständlich. Leicht Lesen gibt es in drei Stufen. B1: leicht verständlich A2: noch leichter verständlich
Leichte-Sprache-Bilder
Leichte-Sprache-Bilder Reinhild Kassing Information - So geht es 1. Bilder gucken 2. anmelden für Probe-Bilder 3. Bilder bestellen 4. Rechnung bezahlen 5. Bilder runterladen 6. neue Bilder vorschlagen
Java Virtual Machine (JVM) Bytecode
Java Virtual Machine (JVM) durch Java-Interpreter (java) realisiert abstrakte Maschine = Softwareschicht zwischen Anwendung und Betriebssystem verantwortlich für Laden von Klassen, Ausführen des Bytecodes,
FuxMedia Programm im Netzwerk einrichten am Beispiel von Windows 7
FuxMedia Programm im Netzwerk einrichten am Beispiel von Windows 7 Die Installation der FuxMedia Software erfolgt erst NACH Einrichtung des Netzlaufwerks! Menüleiste einblenden, falls nicht vorhanden Die
Zahlen auf einen Blick
Zahlen auf einen Blick Nicht ohne Grund heißt es: Ein Bild sagt mehr als 1000 Worte. Die meisten Menschen nehmen Informationen schneller auf und behalten diese eher, wenn sie als Schaubild dargeboten werden.
5.2 Neue Projekte erstellen
5.2 Neue Projekte erstellen Das Bearbeiten von bestehenden Projekten und Objekten ist ja nicht schlecht wie aber können Sie neue Objekte hinzufügen oder gar völlig neue Projekte erstellen? Die Antwort
Anleitung für das Content Management System
Homepage der Pfarre Maria Treu Anleitung für das Content Management System Teil 6 Wochenspiegel und Begegnung Einleitung Die Veröffentlichung einer Begegnung oder eines Wochenspiegels erfolgt (so wie auch
Mathematik: Mag. Schmid Wolfgang Arbeitsblatt 3 1. Semester ARBEITSBLATT 3 RECHNEN MIT GANZEN ZAHLEN
ARBEITSBLATT 3 RECHNEN MIT GANZEN ZAHLEN Wir wollen nun die Rechengesetze der natürlichen Zahlen auf die Zahlenmenge der ganzen Zahlen erweitern und zwar so, dass sie zu keinem Widerspruch mit bisher geltenden
Zur drittletzten Zeile scrollen
1 Fragen und Antworten zur Computerbedienung Thema : Zur drittletzten Zeile scrollen Thema Stichwort Programm Letzte Anpassung Zur drittletzten Zeile scrollen Scrollen VBA Excel 1.02.2014 Kurzbeschreibung:
VisualBasic - Variablen
Typisch für alle Basic-Dialekte ist die Eigenschaft, dass Variablen eigentlich nicht deklariert werden müssen. Sobald Sie einen Bezeichner schreiben, der bisher nicht bekannt war, wird er automatisch angelegt
Excel Funktionen durch eigene Funktionen erweitern.
Excel Funktionen durch eigene Funktionen erweitern. Excel bietet eine große Anzahl an Funktionen für viele Anwendungsbereiche an. Doch es kommt hin und wieder vor, dass man die eine oder andere Funktion
Datensicherung. Beschreibung der Datensicherung
Datensicherung Mit dem Datensicherungsprogramm können Sie Ihre persönlichen Daten problemlos Sichern. Es ist möglich eine komplette Datensicherung durchzuführen, aber auch nur die neuen und geänderten
Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf http://informatik.swoke.de. Seite 1 von 16
Kapitel 5 Arithmetische Operatoren Seite 1 von 16 Arithmetische Operatoren - Man unterscheidet unäre und binäre Operatoren. - Je nachdem, ob sie auf einen Operanden wirken, oder eine Verknüpfung zweier
Klausur in Programmieren
Studiengang Sensorik/Sensorsystemtechnik Note / normierte Punkte Klausur in Programmieren Wintersemester 2010/11, 17. Februar 2011 Dauer: 1,5h Hilfsmittel: Keine (Wörterbücher sind auf Nachfrage erlaubt)
Handbuch Fischertechnik-Einzelteiltabelle V3.7.3
Handbuch Fischertechnik-Einzelteiltabelle V3.7.3 von Markus Mack Stand: Samstag, 17. April 2004 Inhaltsverzeichnis 1. Systemvorraussetzungen...3 2. Installation und Start...3 3. Anpassen der Tabelle...3
Erstellen einer Collage. Zuerst ein leeres Dokument erzeugen, auf dem alle anderen Bilder zusammengefügt werden sollen (über [Datei] > [Neu])
3.7 Erstellen einer Collage Zuerst ein leeres Dokument erzeugen, auf dem alle anderen Bilder zusammengefügt werden sollen (über [Datei] > [Neu]) Dann Größe des Dokuments festlegen beispielsweise A4 (weitere
geben. Die Wahrscheinlichkeit von 100% ist hier demnach nur der Gehen wir einmal davon aus, dass die von uns angenommenen
geben. Die Wahrscheinlichkeit von 100% ist hier demnach nur der Vollständigkeit halber aufgeführt. Gehen wir einmal davon aus, dass die von uns angenommenen 70% im Beispiel exakt berechnet sind. Was würde
Berechnungen in Access Teil I
in Access Teil I Viele Daten müssen in eine Datenbank nicht eingetragen werden, weil sie sich aus anderen Daten berechnen lassen. Zum Beispiel lässt sich die Mehrwertsteuer oder der Bruttopreis in einer
Dokumentation von Ük Modul 302
Dokumentation von Ük Modul 302 Von Nicolas Kull Seite 1/ Inhaltsverzeichnis Dokumentation von Ük Modul 302... 1 Inhaltsverzeichnis... 2 Abbildungsverzeichnis... 3 Typographie (Layout)... 4 Schrift... 4
0. Einführung. C und C++ (CPP)
C und C++ (CPP) 0. Einführung Prof. Dr. Marc Rennhard Institut für angewandte Informationstechnologie InIT ZHAW Zürcher Hochschule für Angewandte Wissenschaften [email protected] Marc Rennhard, 05.01.2010,
INE1 Speicherverwaltung und zweidimensionale Arrays. Speicherorganisation Dynamischer Speicher in C Zweidimensionale Arrays
INE1 Speicherverwaltung und zweidimensionale Arrays Speicherorganisation Dynamischer Speicher in C Zweidimensionale Arrays 1 Speicherorganisation in C 2 von 48 Speicherorganisation Anlegen eines Arrays:
4. Jeder Knoten hat höchstens zwei Kinder, ein linkes und ein rechtes.
Binäre Bäume Definition: Ein binärer Baum T besteht aus einer Menge von Knoten, die durch eine Vater-Kind-Beziehung wie folgt strukturiert ist: 1. Es gibt genau einen hervorgehobenen Knoten r T, die Wurzel
Ingenieurinformatik Diplom-FA (Teil 2, C-Programmierung)
Hochschule München, FK 03 SS 2014 Ingenieurinformatik Diplom-FA (Teil 2, C-Programmierung) Zulassung geprüft: (Grundlagenteil) Die Prüfung ist nur dann gültig, wenn Sie die erforderliche Zulassungsvoraussetzung
Übungen zu C++ Kapitel 1
Übungen zu C++ Kapitel 1 Aufgabe 1 Ergänze den Text. a) Die sechs logischen Einheiten eines Computers sind Eingabe-Einheit, Ausgabe-Einheit, RAM, ALU, CPU, Plattenspeicher. b) Die Programme, welche Hochsprachenprogramme
Folge 19 - Bäume. 19.1 Binärbäume - Allgemeines. Grundlagen: Ulrich Helmich: Informatik 2 mit BlueJ - Ein Kurs für die Stufe 12
Grundlagen: Folge 19 - Bäume 19.1 Binärbäume - Allgemeines Unter Bäumen versteht man in der Informatik Datenstrukturen, bei denen jedes Element mindestens zwei Nachfolger hat. Bereits in der Folge 17 haben
Repetitionsaufgaben Wurzelgleichungen
Repetitionsaufgaben Wurzelgleichungen Inhaltsverzeichnis A) Vorbemerkungen B) Lernziele C) Theorie mit Aufgaben D) Aufgaben mit Musterlösungen 4 A) Vorbemerkungen Bitte beachten Sie: Bei Wurzelgleichungen
INE1 Arrays, Zeiger, Datenstrukturen
INE1 Arrays, Zeiger, Datenstrukturen Arrays Felder von Elementen gleichen Typs Verwenden von Adressen: Zeiger Datenstrukturen mit struct Zeiger auf Datenstrukturen Spezielle Zeiger und komplexe Deklarationen
EINFACHES HAUSHALT- KASSABUCH
EINFACHES HAUSHALT- KASSABUCH Arbeiten mit Excel Wir erstellen ein einfaches Kassabuch zur Führung einer Haushalts- oder Portokasse Roland Liebing, im November 2012 Eine einfache Haushalt-Buchhaltung (Kassabuch)
