Adresse eines Ints..
-
Hallo,
was bedeutet denn "int *b" genau!? Sorry für die blöden Fragen, aber ich bin neu in C++.
-
notebook schrieb:
Hallo,
was bedeutet denn "int *b" genau!? Sorry für die blöden Fragen, aber ich bin neu in C++.
int = int-Wert
int* = Zeiger (Adresse) auf int-Wert
int& = Referenz (Aliasname) eines int-Wertescu André
-
asc schrieb:
int& = Referenz (Aliasname) eines int-Wertes
verwirr ihn nicht

in seinem code ist & der address-of operator.
-
Warum MUSS man festlegen von welchem Typ der Wert ist auf den gezeigt wird? Ich meine, ... &foo gibt doch immer einen Int (die Adresse)... bloss warum reicht das nicht aus? Warum muss ich angeben, dass &foo die Adresse zu einem Int, String.. was auch immer ist? Danke schonmal..
-
notebook schrieb:
Warum MUSS man festlegen von welchem Typ der Wert ist auf den gezeigt wird?
muss man nicht, du kannst auch einen void* nehmen, um die adresse zu speichern.
notebook schrieb:
Ich meine, ... &foo gibt doch immer einen Int (die Adresse)
nö, eine adresse kann total anders aufgebaut sein, als ein 'int', z.b. eine andere bitrepresentation haben. deshalb kann man einem 'int' nicht einfach so eine adresse zuweisen.

-
Danke, so langsam taste ich mich ja ran.

Hier mal mein Code:
int a = 99; void *b = &a; cout << ( b );Habe ich jetzt also in meinem Code oben die Adresse im RAM ausgegeben wo 99 gespeichert ist?
Und..
Welche Vorteile/Nachteile hat es, wenn ich explizit angebe von welchem Typ der Wert ist auf den ich zeige? Verstehe Sinn da nicht so ganz, sorry.
Bitte klärt mich auf!! Gruß! :p :p :p
-
notebook schrieb:
Warum MUSS man festlegen von welchem Typ der Wert ist auf den gezeigt wird? Ich meine, ... &foo gibt doch immer einen Int (die Adresse)... bloss warum reicht das nicht aus? Warum muss ich angeben, dass &foo die Adresse zu einem Int, String.. was auch immer ist? Danke schonmal..
Das muss und kann man nicht explizit angeben (es gibt eine kleine (halbe) Ausnahme, auf die ich hier nicht eingehen will). Der Typ des Ausdrucks &foo steht unmittelbar fest und wird bedingt durch den Typ von foo. Das int* in deinem Fall hat nicht den Zweck, zu sagen, was &foo sein soll, sondern welchen Typ das Objekt b haben soll, dass mit dem Wert &foo initialisiert werden soll. Deine Frage käme dir sicherlich nicht dann in den Sinn, wenn man schreiben würde:
int a = 1; double b = 1;Offensichtlich ist es möglich Objekte verschiedenen Typs mit dem gleichen Ausdruck zu initialisieren - der Typ des Ausdrucks ist also nicht bestimmend für den Typ des zu initialisierenden Objektes, andererseits wirkt er aber durchaus begrenzend: Ein int kann nur Zahlen speichern, eine Adresse ist keine Zahl, mithin kann eine int keine Adressen speichern.
-
notebook schrieb:
Und..
Welche Vorteile/Nachteile hat es, wenn ich explizit angebe von welchem Typ der Wert ist auf den ich zeige?einen void* kann man nicht dereferenzieren, bei einem int* weiss der compiler, dass sich an der adresse ein wert vom typ 'int' befindet.
int a = 99; void *b = &a; int *c = &a; *b = 123; // error, compiled nicht, b ist ein void* *c = 123; // geht weil c ein int* ist. a hat jetzt den wert 123
-
Welche Vorteile/Nachteile hat es, wenn ich explizit angebe von welchem Typ der Wert ist auf den ich zeige?
Sicherheit.
- Du kannst ja einen Zeiger z.B. verwenden um einen neuen Wert in eine Variable oder ein Objekt zu schreiben.
- C++ ist statisch typisiert, d.h. es muss für jede Stelle im Programm schon während des compilierens bekannt sein um welche Typen es sich handelt.
Wenn du (1) und (2) zusammen nimmst, dann folgt daraus automatisch dass in C++ Zeiger typisiert sein müssen.
Beispiel:
int i; int* pi = &i; // ein Zeiger auf einen int char c; char* pc = &c; // ein Zeiger auf ein char double d; double* pd = &d; // ein Zeiger auf ein double std::string s; std::string* ps = &s; // ein Zeiger auf einen std::string *pi = 65; // schreibt 65 als int (=4 byte) nach i *pc = 65; // schreibt 65 als char (=1 byte) nach c *pd = 65; // schreibt 65.0 als double (=8 byte, nach IEEE so-und-so) nach d *ps = 65; // weist der string-variable s den wert "A" zu (65 ist der ASCII code für 'A') *pi = *pi + *pi; // addiert den wert von i zum wert von i, und weist das ergebnis wieder i zu (65+65 -> 130) *ps = *ps + *ps; // konkateniert s mit s ("A" + "A") und weist das ergebnis ("AA") wieder s zuDu siehst also, je nachdem welcher Zeigertyp verwendet wird ist die Operation die aus "*p = 65" oder "*p = *p + *p" entsteht eine ganz andere, da "andere Typen sich anders verhalten".
Es ist also wichtig zu wissen auf was ein Zeiger zeigt.
BTW: über einen Zeiger hast du vollen Zugriff auf das Objekt auf welches er zeigt. z.B. hat std::string eine Funktion "substr", welche einen Teil aus dem String "herauskopiert" und zurückliefert:
std::string s = "ABC"; std::string* ps = &s; // die folgenden 2 Zeilen tun dasselbe: std::cout << s.substr(1,1); // Zugriff direkt auf s, Aufruf der Funktion "substr" auf das Objekt s std::cout << ps->substr(1,1); // Zugriff über ps auf s, Aufruf der Funktion "substr" auf das Objekt s (weil ja ps auf s zeigt)Andere Klassen haben natürlich nicht notwändigerweise ein Funktion "substr", d.h. der Aufruf oben wäre über einen Zeiger der auf irgendwas zeigt nicht unbedingt möglich. Da der Compiler aber weiss dass der Zeiger auf einen std::string zeigt, geht es.
Ich würde das als "Vorteil" bezeichnen, anderenfalls könnte man mit Zeigern kaum was sinnvolles anstellen, oder würde immer Gefahr laufen an eine Funktion einen Zeiger des falschen Type zu übergeben, was dann zu undefiniertem Verhalten führen würde.
-
int i=x; int* ptrI= &i;ptrI Addresse von I aufm Stack
int *ptrI = new int(x);ptrI Addresse von I aufm Heap