zeiger.inc
25.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
<TABLE width="595" border="0" cellspacing="0" cellpadding="0">
<TR>
<TD>
<h1><u>Eine kurze Einfuehrung in die Geheimnisse des Speichers und
der Zeigerprogrammierung (Pointer) in C/C++</u></h1><br>
<br>
Autor: <i>Georg Steffers (georg@steffers.org)</i><br>
Copyright (c)2001 Georg Steffers<br>
<br>
Ueber mich: Zur Zeit bin ich in einer Web-Agentur als Programmierer
beschaeftigt.
Ich programmiere seit meinem 16. Lebensjahr in C was mittlerweile satte
11 Jahre macht und ich denke ich kann mich durchaus als fortgeschritten
bezeichnen. Trotzdem koennen sich natuerlich in diesen Text Fehler
eingeschlichen haben. Wenn irgend jemandem einer auffallen sollte bitte
einfach eine Mail an obige mail-Adresse schicken, danke :-)<br>
<br>
Sollte dieser Text als Lehrstoff genutzt werde bitte ich darum ihn wie
er ist abzudrucken und an die Lernenden weiterzugeben. Bei Zitaten oder
Teilausdrucken bitte ich darum das ich weiterhin als Autor erkennbar
bin. Danke.<br>
<br>
Ich habe versucht diesen Text so einfach wie moeglich zu halten um
Anfaengern eine verstaendliche Einfuehrung in die Problematik von
Pointern unter C zu geben. Dazu werde ich zunaechst eine einfache
Schematische Darstellung des Speichers erklaeren um dann darauf
einzugehen, wie man in einem Programm auf diesen zugreift (Variablen)
und darauf aufbauend Zeiger erklaeren.<br>
Dieses Wissen ist leider elementar und man kann nicht darauf verzichten,
wenn man in C programmieren moechte. Auch nicht wenn man VisualC oder
aehnliches verwendet. Denn leider bleibt es immer am Programmierer
haengen wenn irgendetwas nicht funktioniert und um ein Programm debuggen
(Fehler beseitigen) zu koennen muss man leider verstehen, wie es
funktioniert.<br>
<br>
Ich rate dazu jedes Kapitel das einem noch nicht bekannt ist mehrfach
zu lesen und dazwischen ein paar Pausen einzulegen um das gelesene zu
verarbeiten. Wenn nach mehrfachem lesen Dinge immer noch nicht klar
sind, habe ich sie nicht ausreichend erklaert und ich bitte darum mir
die entsprechende Frage zu mailen. Ich werde dann mein bestes tun um
das Problem zu loesen.<br>
<br>
Ich versuche in diesem Text kein Vorwissen vorauszusetzen. Sollte das
irgendwo nicht geklappt haben schicken Sie mir bitte eine Mail und ich
versuche den Fehler zu korrigieren.<br>
<br>
<br>
<br>
<b><u>Zu Bits und Bytes:</u></b><br>
<br>
Ein Rechner ist eine elektronische Maschine und auch die Daten in einem
Rechner werden elektronisch gespeichert und verarbeitet. Genau wie jedes
Elektronisches Geraet kennt der Rechner und somit ein einzelnes
Speicherelement zwei Grundlegende zustaende (an/aus). Das ist
vergleichbar mit einer Gluehbirne. Man kann sie einschalten oder
ausschalten.<br>
Wenn man jetzt dem ausgeschalteten Zustand des Speichers den Wert 0
zuweist und dem eingeschalteten den Wert 1 koennen wir schon mal zwei
Werte speichern. Voila, das waere ein Bit.<br>
Nu hat man in modernen (und auch in den aelteren) Programmen aber meist
mehr Werte zu verarbeiten als 0 und 1. Leider gibt es keinen Schalter
der mehr als ein oder ausschalten kann (mal abgesehen von Dimmern
vielleicht, aber Dimmer haben wir leider nicht in einem Rechner).<br>
<br>
Hier hilft uns wie so oft bei Rechnern die Mathematik. Wenn sie sich mit
verschiedenen Zahlensystemen (Dual oder Binaer, Oktal, Dezimal,
Hexadezimal) auskennen koennen Sie die folgenden Zeilen zum goessten
Teils ueberfliegen und zum naechsten Absatz weitergehen. Fuer alle
anderen hier eine kurze Einfuehrung in Zahlensysteme.<br>
Wie ihnen vielleicht bekannt ist rechnen wir normalerweise im
dezimalsystem. Das bedeute unsere Zahlen bilden sich auch Ziffern zur
basis 10 oder anders ausgedrueckt, jede Stelle einer Zahl kann Werte von
0 bis 9 annehmen. Fuer einen Rechner ist das wie ich oben schon
festgestellt habe eher bloed, weil unsere kleinste Speichereinheit das
Bit nur entweder 0 oder 1 darstellen kann. Es gibt aber ein Zahlsystem,
das genau diese anforderung Erfuellt. Das Dual oder Binaersystem. In
diesem Zahlensystem werden Zahlen nur aus folgen von 0 und 1 gebildet.
Dabei werden Zahlen zu einem grossen Teil genauso behandelt wie im
Dezimalsystem. Wenn wir im Dezimalsystem mit einer Stelle nicht mehr
auskommen, so erhoehen wir den Wert in der naechsten Stellen.
Wir gehen von 9 nach 10 und von 49 nach 50. Genau dasselbe tun wir im
Binaersystem auch, mit dem unterschied das wir halt nicht erst bei 9
eine neue Stellen bekommen sondern bereits nach 1. <br>
<br>
Im Rechner werden die Daten binaer abgebildet. im Binaersystem sehen
die Zahlen dann folgendermassen aus:<br>
<br>
<pre>
dez -> bin
0 -> 0
1 -> 1
2 -> 10
3 -> 11
4 -> 100
5 -> 101
6 -> 110
7 -> 111
8 -> 1000
9 -> 1001
10 -> 1010
11 -> 1011
12 -> 1100
13 -> 1101
14 -> 1110
15 -> 1111
16 -> 10000
</pre><br>
Wir haben also fuer jede Ziffer im Binaersystem immer nur den Wert 0
oder 1 und diese koenne wir in unserem Bit darstellen.<br>
Um jetzt Werte zu verarbeiten, die groesser als 0 oder 1 sind fasst man
eine bestimmte Menge Speicherelement zusammen und betrachtet diese dann
als eine Zahl. Bei dieser Zusammenfassung hat man sich auf bestimmte
Mengen geeinigt. Die kleinste dieser Mengen fasst 8 Bits zusammen und
nennt sich Byte. In einem Byte kann man also Werte von 00000000 bis
11111111 binaer darstellen. Das mach Dezimal 0 - 255. Fuer groessere
Zahlen wurden dann groessere <<Datentypen>> eingefuehrt,
die alle ein vielfaches von 8 Bits bilden:<br>
<br><pre>
Byte -> 8 Bit
Word -> 16 Bit
double word -> 32 Bit
</pre><br>
<br>
<br>
<b><u>Der Speicher (und wie der Rechner (das Programm) ihn sieht):
</u></b><br>
<br>
Da es hoechst selten vorkommt, das man wirklich nur 0 oder 1 benoetigt
organisieren Rechner ihren Speicher nicht Bitweise sonder in groesseren
Einheiten. <br>
Hier sei nur kurz erwaehnt, das es vom Rechner abhaengt, was
als kleinst moegliche Datenmenge angesehen wird, in diesem Text gehe ich
davon aus , das der Rechner den Speicher Byteweise organisiert. Das soll
fuer diesen Text reichen. Die Erkenntnisse aus diesem Text lassen sich
aber auch problemlos auf Speicherorganisationen anwenden.
Trotzdem moechte ich darauf hinweisen, da dieser Umstand in Programmen
manchmal zu auf den ersten Blick nicht leicht zu findenden Fehlern
fuehren kann.<br>
Also, unser Rechner organisiert den Speicher Byteweise. Dabei wird
intern jedem Byte eine <<Adresse>> zugewiesen.
Diese Adresse ist einfach eine Zahl, die vom ersten Byte des Speichers
bis zu seinem letzten Byte hochgezaehlt
wird. Haben wir also nur 16 Byte Speicher in unserem Rechner so erreicht
der Rechner das erste Byte ueber die Adresse 0 und das letzte ueber die
Adresse 15. Jedes dieser Bytes kann dann einen anderen Wert haben.<br>
Das kann man sehr schoen auf folgenden Art darstellen:<br>
<br><pre>
Speicher Adresse
---------
| 32 | 0
|---------|
| 0 | 1
|---------|
| 12 | 2
|---------|
| 0 | 3
|---------|
| 0 | 4
|---------|
| 0 | 5
|---------|
| 0 | 6
|---------|
| 0 | 7
|---------|
| 48 | 8
|---------|
| 0 | 9
|---------|
| 156 | 10
|---------|
| 0 | 11
|---------|
| 0 | 12
|---------|
| 0 | 13
|---------|
| 0 | 14
|---------|
| 0 | 15
---------
</pre><br>
Nun ist es fuer ein Programm nich besonders praktisch wenn man sich fuer
alle Daten, die man speichern moechte die Adresse merken muesste. Bei 16
Bytes mag das noch gehen aber moderne Computer habe haeufig 64 Millionen
oder sogar noch mehr Bytes an Arbeitsspeicher (die bekannte MByte Zahl
fuer den Hauptspeicher.) Das wuerde dann doch ein wenig
unuebersichtlich. <br>
Deshalb kann man in einem C/C++ Programm einer Speicherstelle einen
Namen geben. Das tut man wenn man Variablen deklariert:<br>
<br><pre>
int main(void) {
char erste; /* Deklariert die Variable <<erste>> als char */
char zweite; /* Deklariert die Variable <<zweite>> als char */
.
.
.
.
return 0;
}
</pre><br>
C/C++ kennt intern unterschiedliche Datentypen. Diese Datentypen nehmen
vielfaches von einem Byte an Speicher in Anspruch. Bei einem char ist
das immer 1 Byte. Bei einer deklaration wird einem Namen in dem Programm
eine Adresse im Speicher zugewiesen, hinter der genuegend Bytes fuer
diese Variable frei sind. Wenn es geht werden Variablen wenn sie direkt
hintereinander
deklariert wurden auch direkt hintereinander im Speicher abgelegt.<br>
Die obige deklaration koennte in unserem Beispielspeicher also
folgendermassen aussehen.<br>
<br><pre>
Speicher Adresse Variable
---------
| 32 | 0
|---------|
| 0 | 1
|---------|
| 12 | 2
|---------|
| 0 | 3
|---------|
| 0 | 4
|---------|
| 0 | 5 erste
|---------|
| 0 | 6 zweite
|---------|
| 0 | 7
|---------|
| 48 | 8
|---------|
| 0 | 9
|---------|
| 156 | 10
|---------|
| 0 | 11
|---------|
| 0 | 12
|---------|
| 0 | 13
|---------|
| 0 | 14
|---------|
| 0 | 15
---------
</pre><br>
Dann waehre <<erste>> ein Synonym fuer Adresse 5 im
Speicher und <<zweite>> ein Synonym fuer adresse 6. Um jetzt
Werte im Speicher abzulegen kann man einfach folgendes machen:<br>
<br><pre>
int main(void) {
char erste;
char zweite;
erste=7; /* Zuweisung */
zweite=10; /* Zuweisung */
.
.
.
.
return 0;
}
</pre><br>
Das nennt man einer Variable einen Wert zuweisen. Diese Zuweisung kann
auch aus einer Arithmetischen Operation bestehen z.B. erste=7+4. Dann
wuerde zuerst die berechnung durchgefuehrt und das Ergebnis der Variable
zugewiesen. Nach obigem Beispiel saehe unser Speicher so aus:<br>
<br><pre>
Speicher Adresse Variable
---------
| 32 | 0
|---------|
| 0 | 1
|---------|
| 12 | 2
|---------|
| 0 | 3
|---------|
| 0 | 4
|---------|
| 7 | 5 erste
|---------|
| 10 | 6 zweite
|---------|
| 0 | 7
|---------|
| 48 | 8
|---------|
| 0 | 9
|---------|
| 156 | 10
|---------|
| 0 | 11
|---------|
| 0 | 12
|---------|
| 0 | 13
|---------|
| 0 | 14
|---------|
| 0 | 15
---------
</pre><br>
an die Stelle im Speicher mit der Adresse 5 wurde eine 7 geschrieben und
an die folgende mit der Adresse 6 wurde eine 10 geschrieben. Wenn man
seine Variable jetzt irgendwoanders als in einer Zuweisung verwendet so
wird dar Name der Variable durch den Inhalt des Bytes im Speicher
ersetzt auf das er verweist. Wir koennen zum Beispiel mit unseren
Variablen rechnen:<br>
<br><pre>
int main(void) {
char erste;
char zweite;
char ergebnis;
erste=7; /* Zuweisung */
zweite=10; /* Zuweisung */
ergebnis=erste+zweite; /* hier werden zunaechst die Variablen durch
den Speicherinhalt (also 7 und 10) ersetzt,
dann eine addition mit ihnen durchgefuehrt
und anschliessend das Ergebnis einer weiteren
Variable zugewiesen. */
.
.
return 0;
}
</pre><br>
Unser Speicher saehe danach also folgendermassen aus:<br>
<br><pre>
Speicher Adresse Variable
---------
| 32 | 0
|---------|
| 0 | 1
|---------|
| 12 | 2
|---------|
| 0 | 3
|---------|
| 0 | 4
|---------|
| 7 | 5 erste
|---------|
| 10 | 6 zweite
|---------|
| 17 | 7 ergebnis
|---------|
| 48 | 8
|---------|
| 0 | 9
|---------|
| 156 | 10
|---------|
| 0 | 11
|---------|
| 0 | 12
|---------|
| 0 | 13
|---------|
| 0 | 14
|---------|
| 0 | 15
---------
</pre><br>
Das ist soweit alles was mir zu Variablen einfaellt, obwohl bestimmt
noch hunderte von Fragen offen bleiben. Wie gesagt bitte mailen... :-)
Jetzt kommen wir dann zu:<br>
<br>
<br>
<b><u>Zeiger oder (ja wo stehen sie denn?)<br>
oder (warum C Programmierer dauernd fluchen):</u></b><br>
<br>
Ein Zeiger (Pointer) ist eine spezielle Form einer Variable.
Anstatt einen Wert zu enthalten enthaelt dies Variable eine
Speicheradresse Der Inhalt eines Zeigers zeigt also sozusagen auf eine
andere Stelle im Speicher.<br>
Einer meiner Dozenten hat mal eine passende Analogie gebracht:<br>
<br>
Ein Zeiger ist wie ein Vorwegweiser an einer Strasse.<br>
<ul>
<li>Der Vorwegweiser zeigt auf den Ort wo man hinfahren moechte.
<li>Ein Zeiger zeigt auf die Stelle im Speicher an die man moechte.
</ul><br>
Im Moment ist es sicher schwierig den Sinn einer solchen Variable zu
verstehen, aber Sie koennen mir glauben, wenn ich ihnen sage, das man
in C/C++ dauernd Zeiger braucht. Machen Sie sich im Moment keine
Gedanken darueber wann und warum sondern konzentrieren Sie sich voll
auf das wie. Das wann und warum kommt beim programmieren und im Laufe
des folgenden Textes von ganz alleine (hoffe ich).<br>
<br>
C/C++ hat eine besonder Syntax (Schreibweise) um mit Zeigern umzugehen:
<br><br>
Ich hoffe folgendes Programm/Diagramm mach deutlich was gemeint ist.<br>
<br><pre>
int main(void) {
char erste; /* Deklariert die Variable <<erste>> als char */
char zweite; /* Deklariert die Variable <<zweite>> als char */
char* zeiger; /* Deklariert einen Zeiger, der auf eine Speicherbereich
zeigt, der die groesse eines char habe soll.
Kling kompliziert ich weiss...ich versuche es unten
in einem weiten Speicherdiagramm zu verdeutlichen. */
/* Man kann Zeigern wie jeder anderen Variable auch Werte zuweisen. */
zeiger=0;
.
return 0;
}
</pre><br>
das ganze sieht dann im Speicher bildlich so aus:<br>
<br><pre>
Speicher Adresse Variable
---------
-->| 32 | 0
| |---------|
| | 0 | 1
| |---------|
| | 12 | 2
| |---------|
| | 0 | 3
| |---------|
| | 0 | 4
| |---------|
| | 7 | 5 erste
| |---------|
| | 10 | 6 zweite
| |---------|
---| 0 | 7 zeiger
|---------|
| 48 | 8
|---------|
| 0 | 9
|---------|
| 156 | 10
|---------|
| 0 | 11
|---------|
| 0 | 12
|---------|
| 0 | 13
|---------|
| 0 | 14
|---------|
| 0 | 15
---------
</pre><br>
Gut...wenn also ein Wert in einer Zeigervariable steht soll dieser fuer
die Adresse einer Speicher stelle stehen. Das hat allerdings nur einen
Sinn wenn ich auch an den Inhalt dieser Speicheradresse kommen kann auf
die der Zeiger zeigt.<br>
Benutzt man den Zeiger wie die normalen Variablen, so wird er immer
durch die Adresse ersetzt und nicht durch den Wert der Speicherstelle an
dieser Adresse. Folgendes kleine Programm soll das erleutern. In diesem
Programm tauchen ein paar neue Dinge auf, die ich aber versuche direkt
an dem Programm zu erklaeren. Dies wird das erste Programm in diesem
Text was sie compilieren und ausfuhren koennen:<br>
<br><pre>
int main(void) {
char erste; /* Variable deklarieren */
char zweite; /* Variable deklarieren */
char* zeiger; /* Zeiger deklarieren */
erste = 7; /* 7 zuweisen */
zweite = 10; /* 10 zuweisen */
zeiger = &erste; /* Das & vor erste hat eine spezielle Bedeutung.
Normalerweise wird ja eine Variable durch ihren
Wert ersetzt. Schreibt man in C/C++ aber ein &
vor die Variable so wird diese durch die
Speicheradresse an der sie steht ersetzt. Da
der Inhalt eines Zeigers eine Adresse ist kann man
ihm diese dann zuweisen. */
/* Jetzt folgen ein paar Ausgaben, die Zeigen sollen an welcher Adresse
welcher Wert steht. Es ist sehr wichtig zu verstehen, was hier
passiert. Das setzt voraus das man die printf Funktion von C
kennt und versteht */
printf("Variable: erste - Adresse: %lu - Wert: %lu\n", &erste, erste);
printf("Variable: zweite - Adresse: %lu - Wert: %lu\n", &zweite, zweite);
printf("Zeiger: zeiger - Adresse: %lu - Wert: %lu\n", &zeiger, zeiger);
return 0;
}
</pre><br>
Nachdem diese Programm uebersetzt und ausgefuehrt wurde sollte man in
etwa folgende Ausgabe erhalten (die Werte weden unterschiedlich sein):
<br>
<br><pre>
Variable: erste - Adresse: 3221223243 - Wert: 7
Variable: zweite - Adresse: 3221223242 - Wert: 10
Zeiger: zeiger - Adresse: 3221223236 - Wert: 3221223243
</pre><br>
Hier ist wichtig zu erkennen, das der Wert von <<zeiger>>
der Adresse von <<erste>> entspricht.<br>
Wie oben bereits erwaehnt waere es jetzt sinnvoll, wenn man ueber
<<zeiger>> auch irgendwie an den Wert von
<<erste>> kommen koennte. Tatsaechlich dienen Zeiger
eigentlich nur diesem Zweck.<br>
Dafuer gibt es in C wieder eine spezielle Syntax. Um an den Wert von
<<erste>> zu kommen kann man <<*zeiger>>
schreiben. Das nennt man dereferenzieren. Das Wort kommt daher, das
<<zeiger>> eine Referenz auf <<erste>> ist und
man diese Referenz jetzt aufloest (dereferenzieren) (klingt furchtbar
kompliziert ich weiss).<br>
<br>
Diese Syntax verwirrt gerade Anfaenger haeufig, da man den * auch schon
bei der deklaration des Zeigers benutzt hat.<br>
Hier muss man
strikt zwischen der deklaration eines Zeigers und dem dereferenzieren
unterscheiden. Ich mache es mir dadurch leichter, das ich bei der
deklaration den * immer an den Datentyp schreibe und beim
dereferenzieren an den Variablennamen. Beispiel:<br>
<br><pre>
- char* zeiger; /* deklaration eines Zeiger */
- erste = *zeiger; /* dereferenzieren von Zeiger */
</pre><br>
Wie sich das auswirkt soll folgendes Programm zeigen. Es ist im
wesentlichen dasselbe Programm wie vorhin mit einer zusaetzlichen
Ausgabe:<br>
<br><pre>
int main(void) {
char erste; /* Variable deklarieren */
char zweite; /* Variable deklarieren */
char* zeiger; /* Zeiger deklarieren */
erste = 7; /* 7 zuweisen */
zweite = 10; /* 10 zuweisen */
zeiger = &erste; /* Das & vor erste hat eine spezielle bedeutung.
Normalerweise wird ja eine Variable durch ihren
Wert ersetzt. Schreibt man in C/C++ aber ein &
vor die Variable so wird diese durch die
Speicheradresse an der sie streht ersetzt. Da
der Inhalt eines Zeigers eine Adresse ist kann man
ihm diese dann zuweisen. */
/* Jetzt folgen ein paar Ausgaben, die Zeigen sollen an welcher Adresse
welcher Wert steht. Es ist sehr wichtig zu verstehen, was hier
passiert. Das setzt voraus das man die printf Funktion von C
kennt und versteht */
printf("Variable: erste - Adresse: %lu - Wert: %lu\n", &erste, erste);
printf("Variable: zweite - Adresse: %lu - Wert: %lu\n", &zweite, zweite);
printf("Zeiger: zeiger - Adresse: %lu - Wert: %lu\n", &zeiger, zeiger);
printf("dereferenziert: zeiger - %lu\n", *zeiger);
return 0;
}
</pre><br>
Das Programm sollte folgende Ausgabe machen:<br>
<br><pre>
Variable: erste - Adresse: 3221223243 - Wert: 7
Variable: zweite - Adresse: 3221223242 - Wert: 10
Zeiger: zeiger - Adresse: 3221223236 - Wert: 3221223243
dereferenziert: zeiger - 7
</pre><br>
Man sieht, das <<*zeiger>> identisch mit
<<erste>> ist.<br>
So, das solls fuers erste mal sein...ich wuerde vorschlagen mit den
Programmen ein bisschen herumzuexperimentieren.<br>
Noch ein Wort: Es kann Ihnen beim experimentieren durchaus passieren,
das das Programm nachdem sie es ausfuehren ein Fehlermeldung der art
<<segmentation fault>> oder <<overflow error>>
oder aehnlches (je nach dem mit welchem System sie arbeiten) ausgibt.
Das sind Fehler, die darauf hinwiesen, das der Pointer keine gueltige
Adresse enthaelt. Dadurch greift dann naemlich das
<<*zeiger>> auf eine ungueltige (nicht dem eigenen Programm
zugeordnete Adresse) zu.<br>
<br>
Viel Spass und bei Fragen bitte mail an mich...ich bin fuer
Verbesserungsvorschlaege und Fragen immer offen.
</TD>
</TR>
</TABLE>