Frage zu Pointer/Zeiger
-
Hallo zusammen,
ich hab mir schon ein Tutorial durchgelesen zu Pointern, aber trotzdem verstehe ich das nicht ganz.
Link dazu: http://www.tutorials.at/c/11-zeiger.html
Und hier das angegebene Bsp-Programm:
#include <stdio.h> int main() { int a=0; int b=0; int* pa; int* pb; /* zwei Variablen und zwei Zeiger deklarieren */ pa = &a; /* zeigt nun auf a */ pb = &b; /* zeigt nun auf b */ printf ("Geben Sie zwei Zahlen ein: "); scanf ("%d %d", pa, pb); /* kein &-Operator! */ printf ("Zahlen werden wieder ausgegeben:\n"); printf ("Zugriff über die Variablen ...\n"); printf ("a = %d, b = %d\n", a, b); /* altbekannt; einfach den Wert von a und b ausgeben */ printf ("Zugriff durch Dereferenzierung der Zeiger ...\n"); printf ("a = %d, b = %d\n", *pa, *pb); /* Wichtig: Verweisoperator * nötig! */ return 0; }
Kann mir einer dieses Programm genau/präzise erklären bitte?
Eine Integer-Variable hat ja 4 Byte... und durch das & wird auf die Startadresse, also auf das 1. Byte gezeigt?
Und was ist mit dem 2. Byte? kann den eine Integervariable 4 Zahlen haben , weil 4 Byte, ne oder?!
Danke im voraus!
mfg Floppy
-
Floppy123 schrieb:
Kann mir einer dieses Programm genau/präzise erklären bitte?
Nein, aber Fragen beantworte ich doch gerne.
Floppy123 schrieb:
Eine Integer-Variable hat ja 4 Byte... und durch das & wird auf die Startadresse, also auf das 1. Byte gezeigt?
Ein Integer hat zwar nicht zwangsläufig 4 Byte, aber der Zeiger zeigt auf das erste Byte der Variable, ja.
Floppy123 schrieb:
Und was ist mit dem 2. Byte? kann den eine Integervariable 4 Zahlen haben , weil 4 Byte, ne oder?!
Nein, die Zahl ist über alle 4 Byte verteilt. Das könnte dich vielleicht auch interessieren: http://de.wikipedia.org/wiki/Byte-Reihenfolge
Nun, warum das mit dem Zeiger funktioniert? Ganz einfach, die restlichen Byte liegen genau dahinter. Und da wir ja ein int* haben, wird einfach angenommen, dass hinter dem ersten noch 3 weitere Byte stehen. Du kannst das ja mal testen:
int i = 1447320157; char *p = (char*)&i; printf("%2X %2X %2X %2X", *p, *(p + 1), *(p + 2), *(p + 3));
Das gibt dir die ersten 4 Byte des Integers aus. Du siehst also, man kann auf Pointer auch Zahlen addieren. Man kann auch subtrahieren. Dividieren oder multiplizieren geht allerdings nicht (oder nur mit bösen Tricks), das macht ja auch keinen Sinn.
Wenn du einen Pointer inkrementierst wird die Adresse um die Größe der Variablen verschoben. Also
int i = 1447320157; int *p = &i; printf("%i", *(p + 1)); // Böse
Das würde schief gehen, da p + 1 gleich 4 Byte hinter p zeigt.
-
Ok, danke.
Bitte Comments lesen für Fragen.
#include <stdlib.h> #include <stdio.h> #include <math.h> #include <string.h> #define MAXSTRING 100 #define MAXPKT 5 struct punkt_struct { float x; float y; }; typedef struct punkt_struct punkt; void getPunkte(punkt* thePunkte, int len)// heißt das nun, dass die Struktur thePunkte ein Zeiger ist? Was bedeutet das jetzt? { double t=0; printf("getPunkte: sizeof(thePunkte)=%d\n",sizeof(thePunkte)); for( t = 0.0 ; t < len; t++) { thePunkte->x = (float)t;//struktur zeigt auf x und speichert t in x? thePunkte->y = (float)sin(t*0.1+1.4); //hier das selbe nur mit y, sin etc. thePunkte++;//was bringt das genau hier? Wenn ich mit Einzelschritt durchgehe, dann speichert es am Anfang in x und y werten z.B. 3 und 4, aber nachdem man thepunkte++ gemacht hat stehen irgendwelche hohen zahlen drinnen mit 1, 2 Buchstaben } } punkt getGreater(punkt p1, punkt* p2)// hiert ist die Struktur p2 ein pointer - gleiche frage wie ganz oben. { printf("getGreater: sizeof(p1)=%d : sizeof(p2)=%d\n",sizeof(p1),sizeof(p2)); if (p1.y >= p2->y) { return p1; } return *p2;//warum muss man hier einen stern machen? } punkt findMax(punkt* thePunkte, int len) { int t=0; punkt maxValue; maxValue= *thePunkte; for( t = 0 ; t < len; t++) { maxValue = getGreater(*thePunkte,&maxValue);// und hier warum einmal * und bei anderen &, wobei & auf die Startadresse oder so zeigt, aber bitte trotzdem erklären.. thePunkte++;// hier wieder selbe frage wie oben } return maxValue; } void main() { punkt allePunkte[MAXPKT]; punkt maxPunkt; getPunkte(allePunkte,MAXPKT); maxPunkt=findMax(allePunkte,MAXPKT); printf("Maximum an (%f,%f)\n",maxPunkt.x,maxPunkt.y); }
Sorry, erstmal für die vielen Fragen, aber ich bekomms einfach nicht gebacken diese Pointer^^.
Danke im voraus!
mfg Floppy
-
#include <stdlib.h> #include <stdio.h> #include <math.h> #include <string.h> #define MAXSTRING 100 #define MAXPKT 5 struct punkt_struct { float x; float y; }; typedef struct punkt_struct punkt; void getPunkte(punkt* thePunkte, int len)// thePunkte ist ein Zeiger auf punkt. Da punkt eine struct ist, zeigt thePunkte auf eine struct. { double t=0; printf("getPunkte: sizeof(thePunkte)=%d\n",sizeof(thePunkte)); for( t = 0.0 ; t < len; t++) { thePunkte->x = (float)t;//t wird in das Element x der struct geschrieben, auf die thePunkte zeigt thePunkte->y = (float)sin(t*0.1+1.4); //hier das selbe nur mit y, sin etc. thePunkte++; // Der Zeiger thePunkte zeigt jetzt auf den Speicherplatz hinter der struct. } punkt getGreater(punkt p1, punkt* p2)// hiert ist die p2 ein pointer auf die struct { printf("getGreater: sizeof(p1)=%d : sizeof(p2)=%d\n",sizeof(p1),sizeof(p2)); if (p1.y >= p2->y) { return p1; } return *p2;//Da p2 ein Zeiger ist und du aber den Inhalt zurück geben willst, musst du den Zeiger dereferenzieren (auf den Inhalt zugreifen) punkt findMax(punkt* thePunkte, int len) { int t=0; punkt maxValue; maxValue= *thePunkte; for( t = 0 ; t < len; t++) { maxValue = getGreater(*thePunkte,&maxValue);// Die Funktion getGreater erwartet eine Struct und einen Zeiger. Da thePunkte ein ZEiger ist, musst du ihn dereferenzieren. maxValue ist eine Struct, darum brauchst du die Adresse. thePunkte++;//die gleiche Antwort wie oben } return maxValue; } void main() { punkt allePunkte[MAXPKT]; // Das ist ein Array von der struct punkt punkt maxPunkt; // Das ist ein einzelner punkt getPunkte(allePunkte,MAXPKT); maxPunkt=findMax(allePunkte,MAXPKT); printf("Maximum an (%f,%f)\n",maxPunkt.x,maxPunkt.y); }
Du hast das Array allePunkte. Dies sind Speicherstellen die alle direkt hintereinander im Speicher liegen.
Du übergibst an deine Funktion die Adresse des ersten Elements
&allePunkte[0]
oder kurz:allePunkte
Deinen Funktionen haben jetzt den Zeiger auf eine struct bekommen.
MitthePunkte++;
wird der Zeiger jetzt weiter gesetzt und zwar auf das nächste Element: allePunkte[1] und dann allePunkte[2]Das ist nicht anders als bei den String-Funktionen.
-
Ok, danke.
Aber eins verstehe ich noch nicht ganz.
beim Unterprogramm getCreater isnd ja die Übergabeparamter punkt p1 und punkt* p2.
Beim Aufruf hat es halt andere Namen, was ja egal ist..., aber warum ist thePunkte, also an der STelle wo p1 im Unterprogramm steht ein Zeiger?
p1 ist doch auch keiner?mfg robin
-
Falls ich deine Frage mal in eine für mich Verständliche übersetzen darf:
Translat0r schrieb:
Warum wird bei der Funktion getGreater() ein Punkt per Value und der andere über einen Pointer übergeben?
Falls das deine Frage ist: Es hat keinen Sinn und soll vermutlich nur zeigen, dass hier beides Funktioniert.
PS: Das ist übrigens etwas unschön, man sollte lieber einen const Punkt* erwarten. Denn durch den Pointer könnte die Funktion die Variable dahinter ändern, das const verspricht aber, dass sie das nicht macht. (Und da sie das nicht macht, kann man das ja auch ruhig garantieren.)
Warum man bei so etwas überhaupt Pointer verwendet? Bei großen Strukturen kann das sehr viel schneller sein, weil eben nur ein Pointer und keine ganze Struktur kopiert werden muss.
-
p1 ist kein Zeiger.
thePunkte ist ein Zeiger und mit *thePunkte kommst du an den Wert (die struct) auf die thePunkte zeigt.
Bei
getGreater(*thePunkte,&maxValue);
wird bei thePunkte durch den * der Inhalt übergeben und bei maxValue durch das & die Adresse.Mach dir nicht den Kopf kaputt warum mal ein Zeiger und mal der Wert übergeben wird. Das ist ein reines Beispielprogramm.