Ich frage mich, was wirklich der & a zurückkommt?

7

Angenommen

Erster Fall

%Vor%

Zweiter Fall

%Vor%

Die meisten von uns sagen, dass b eine Variable und kein Zeiger ist. Aber siehe unten.

Die Frage ist also, ob die &a die Adresse zurückgibt, die eine vorzeichenlose ganze Zahl ist, warum können wir sie dann nicht einer normalen Variablen zuordnen? Aber warum nur zu Zeigern? Siehe unten

%Vor%

Wenn die Adresse ein Integer-Format ist, warum speichern dann nicht die Ganzzahlen ohne Vorzeichen oder lange Ganzzahlen? Ich dachte, es muss ein verborgenes Geheimnis dahinter stehen. Könnte jemand es offenbaren? Was ich dachte ist, Zeiger müssen etwas im Inneren tun, aber ich frage mich, was es wäre und warum eine normale Variable nicht sein kann.

Danke für all eure Antworten, aber die eigentliche Frage, was wirklich &a zurückgibt? Ganzzahliger Wert oder nicht? Wenn es eine ganze Zahl ist, warum kann eine Variable es nicht halten? long int a = 65535 \ valide warum nicht int a = & amp; b wenn der Wert der Adresse b 65535 ist

Ich bin nicht besorgt, es als Zeiger zu verwenden, bitte geht es darum, nur den Wert zu speichern. Die Adresse nicht abstufen. Leute sagen 32 oder 64 Bit, darüber mache ich mir keine Sorgen. Warum kann die Adresse nicht gespeichert werden, wenn die Adresse eine Ganzzahl ist?

Ich meine, warum können wir den Wert nicht zuweisen, ich sage nicht, die Eigenschaften von Zeigern zu Variable zuweisen, sondern nur den Wert, der es ist

%Vor%

nimm das 16 Bit als Beispiel normalen Zeiger (die Adresse) Größe ist 2 Bytes und variable Größe ist 2 Bytes Warum können wir nicht die Adresse in andere Variable speichern, wenn die Adresse ist Integer-Wert, das ist meine Frage Ich finde viele Antworten wie ++ es erhöht um 4 auf Zeiger und Wert 1 auf Variable, nicht besorgt darüber, nur die Zuweisung des Wertes ist wichtiger Frage.

%Vor%     
niko 09.09.2011, 11:30
quelle

9 Antworten

22

Ganzzahlen, auch long int , haben nicht immer die gleiche Größe wie ein Zeiger. Manchmal werden sie (zum Beispiel die meisten 32-Bit-Architekturen haben sizeof(int) == sizeof(void *) ), manchmal werden sie anders sein (zum Beispiel, einige 64-Bit-Architekturen haben sizeof(long) == sizeof(void *) , aber einige nicht - Visual C ++ unter Windows ist ein Prime Beispiel für einen Compiler wo sizeof(long) != sizeof(void *) ).

Es gibt auch die Tatsache, dass void * einfach nicht derselbe Typ wie long int ist.

Stellen Sie sich eine Klasse Foo und eine Klasse Bar vor, die wie folgt definiert sind:

%Vor%

Es ist so, als würde man fragen, warum man nicht einer Instanz vom Typ Foo eine Instanz der Klasse Bar zuweisen kann - sie sind nicht dasselbe, obwohl in diesem Fall sowohl Foo als auch Bar haben das gleiche zugrunde liegende Bitmuster.

    
Dean Harding 09.09.2011, 11:53
quelle
7
  

gibt die Adresse zurück, die eine Ganzzahl ohne Vorzeichen ist

Nein, ist es nicht. Ein Zeiger (Adresse) ist ein Zeiger. Zeitraum.

    
Ingo 09.09.2011 11:52
quelle
6

Sie können und es war sehr häufig, es ist jetzt ein relevantes Portabilitätsproblem, da es nicht auf x64-Plattformen mit einem 64-Bit-Zeiger und einer 32-Bit-Ganzzahl verwendet werden kann.

Es kann von der Assembler-Verwendung herrühren, wo ein Register leicht sowohl als Ganzzahl als auch als Zeiger interpretiert werden kann.

Es ist im modernen Gebrauch nicht übermäßig vernünftig, da es leicht zu Fehlern und Verwirrung führen kann. Typsicherheitsverbesserungen im Compilerdesign verbieten solche Verwendung, aber C99 führt einige ähnliche Unterstützung mit uintptr_t und intptr_t wieder ein, die "Ganzzahl-Typen sind, die Objektzeiger halten können".

Um Ihre Frage zu paraphrasieren:

  

Warum können wir [Zeiger] keiner Variablen [einer ganzen Zahl] zuweisen?

Die Antwort lautet: Da es sich nicht um Assembler handelt, sind C und C ++ stark typisierte Sprachen.

    
Steve-o 09.09.2011 11:50
quelle
3

Es ist nicht spezifisch für C oder C ++. Dies ist in allen stark typisierten Sprachen gleich. Es ist bis zu einem gewissen Grad sogar wahr in Englisch. Wir können sagen, dass "die Farbe des Buches blau ist", aber nicht "die Farbe des Buches ist hölzern". Ein -Typ beschränkt die möglichen Werte , die eine Variable haben kann.

Eine Variable int* type kann nur Werte enthalten, die Adressen von int's sind, und eine Variable vom Typ long int kann nur Werte zwischen LONG_MIN und LONG_MAX inklusive enthalten. Das sind nur zwei völlig unterschiedliche Werte.

C und C ++ sind nicht absolut. Mit Typecasting können Sie einige Einschränkungen umgehen. Z.B. (int) 3.5 teilt dem Compiler mit, dass Sie den nicht ganzzahligen Wert 3.5 in einen ungefähr gleichwertigen Ganzzahlwert umwandeln möchten. Dies funktioniert besser, wenn die beiden Typen ähnlicher sind. Andere Sprachen haben möglicherweise keine solche Typcasting; Dort müssen Sie möglicherweise stattdessen eine Funktion aufrufen. Z.B. ROUND(3.5, INT)

    
MSalters 09.09.2011 11:51
quelle
2

Niko, IMHO der Punkt der getippten Sprachen ist, dass Sie nicht nur eine Sache der anderen zuweisen können, obwohl sie alle nur ein Haufen von Bits auf der niedrigsten Ebene sind.

    
Raku 09.09.2011 11:52
quelle
2
  

Wenn die Adresse ein Integer-Format ist, dann warum nicht vorzeichenlos oder lang   Integer speichern es. Ich dachte, es muss ein verborgenes Geheimnis geben   dahinter.

Die Adresse ist keine ganze Zahl; es ist eine Adresse. Auf einem 64-Bit-System:

%Vor%

weist eine 64-Bit-Variable zu, während dies:

%Vor%

weist eine 32-Bit-Variable zu. Sie sind nicht gleich. Sie scheinen auf einigen Systemen die gleiche Größe zu haben, aber sie sind nicht gleich. Betrachten Sie als Beispiel nur den Operator ++. Auf einem 32-Bit-System erhöht ++ einen Zeiger um 4, während ++ bei einem Integer die Ganzzahl um 1 erhöht. Der Compiler versucht Ihnen zu helfen, indem er Ihnen sagt, dass Sie etwas falsch machen.

    
Scott C Wilson 09.09.2011 13:03
quelle
1

Zeiger werden normalerweise als Ganzzahlen implementiert, aber die C ++ - Spezifikation definiert nur ihr Verhalten (wobei zwei oder mehr Zeiger gleich oder verschieden sein müssen).

Das Umwandeln eines Zeigers in eine Uint ist wie das Transformieren einer Instanz einer anderen Klasse / eines anderen Typs.

Im Hinblick darauf, warum b = (uint) &a; funktioniert, ist es wahrscheinlich implementierungsabhängig. (Und bogenabhängig).

    
robermorales 09.09.2011 12:38
quelle
1

Von dem, was ich aus Ihrer Frage herausgehe, haben Sie den Eindruck, dass, weil eine Adresse als hex dargestellt wird, es eine ganze Zahl ist. Nun, sicher, aber das bedeutet nicht, dass Sie eine ganze Zahl in einen Zeiger setzen können, wie Sie denken.

Daten (die Variable) hat Informationen mit it..meta Daten. Die Größe davon, der Wert, der Datentyp ... die Adresse, an der es gespeichert ist. Ein Zeiger hält den letzten Teil der Metadaten, die Adresse, fest. Es ist ein spezieller Datentyp, dessen Hauptaufgabe darin besteht, Adressen zu halten. Der Wert des Zeigers ist unabhängig vom Wert der Daten, sie sind 2 getrennte Dinge. Der Wert des Zeigers gibt an, wo die gesuchten Daten zu finden sind. Aus diesem Grund können Sie keine Ganzzahl in einen Zeiger auf die Art einfügen, wie Sie es versuchen. Es ist, als würde man sagen, dass du an einer Straßenadresse lebst, und du bist auch diese Adresse. Stellen Sie sich vor, wenn Sie von Ihrer Adresse angerufen werden, wäre das albern!

Bedenken Sie Folgendes: Sie haben eine Klasse namens x, die einige Elemente enthält. Sie erstellen einen Zeiger auf diese Klasse. Der Zeiger enthält immer noch eine Adresse mit einem Hexadezimalformat..aber das Objekt kann nicht in 4 oder 8 Byte (32 Bit bzw. 64 Bit) aufgeteilt werden! Beachten Sie, dass das Format des Zeigers über alle Datentypen unabhängig von ihrem Wert gleich ist.

%Vor%

Nun ... der Grund, warum das funktionierte, ist, weil du die Adresse der Variablen a genommen und in einen Zeiger p gesetzt hast. Schlüsselwort ist ADDRESS, was ein Zeiger hält.

%Vor%

Das hat nicht funktioniert, weil Sie versucht haben, die ADRESSE (einen Zeiger) von a in b zu setzen, was nur eine Variable ist.

Um es einfach auszudrücken: Sie können eine Adresse nicht in eine normale Variable einfügen. Eine Adresse kann nur in einem Zeiger gespeichert werden.

    
MGZero 09.09.2011 18:30
quelle
0

Es gibt ein Missverständnis in Ihrem anfänglichen Denken: Es gibt "normale Variablen" und "poitners". Es gibt kein solches Konzept. Es gibt nur "Variablen" und "Typen".

  • int ist ein "Container für einen Integer-Wert"
  • class Person ist ein Container für eine Personenbeschreibung.
  • int * ist ein Container für die Adresse einer Ganzzahl
  • Person * ist ein Container für eine Adresse einer Person.

Der & amp; Der Operator gibt die Adresse einer Variablen zurück, und ihr Typ ist ein "Zeiger auf diesen Typ". Zuweisungen können nur von einem Ausdruck eines bestimmten Typs zu einer Variablen eines kompatiblen Typs gehen. int, int *, Person und Person * sind alle miteinander inkompatibel. Aus demselben Grund, aus dem Sie keine Person einem Int oder einem Int einer Person zuordnen können, können Sie Int nicht einem Int zuweisen. Es sei denn, Sie haben eine Funktion, mit der Sie einen Ausdruck schreiben können, der einen Typ von dem anderen zurückgibt. Genau wie operator & und der &a Ausdruck gibt Ihnen das.

    
Emilio Garavaglia 12.09.2011 08:18
quelle