Geben Sie einen Zeiger auf Element a in einer Struktur ein, und schreiben Sie eine Routine, die einen Zeiger auf die Struktur zurückgibt

8

Hier ist eine Interviewfrage, die ich in einem Forum gesehen habe. Ich habe versucht herauszufinden, wie es funktioniert, aber ich verstehe es nicht ganz. Könnte jemand erklären, wie es funktioniert?

F: Geben Sie einen Zeiger auf Element a innerhalb einer Struktur ein, schreiben Sie eine Routine, die einen Zeiger auf die Struktur zurückgibt.

%Vor%

Die Antwort ist:

%Vor%     
Steve 20.06.2010, 02:24
quelle

4 Antworten

12
  

Wie funktioniert es?

Die Grundgleichung hier (alle Arithmetik in Bytes) ist

%Vor%

Gegeben der Typ von s , ein einzelner Compiler und eine einzelne Zielmaschine, haben sie den Byte-Offset von a bestimmt - er ist für jede Struktur vom Typ s gleich.

Sie erhalten die linke Seite und Ihr Interviewer hat Sie gebeten, s wiederherzustellen. Sie können dies tun, indem Sie eine neue Gleichung erhalten; subtrahiere den Byte-Offset von beiden Seiten:

%Vor%

In dem Problem ist die Adresse von s->a , aber Sie müssen den Byte-Offset herausfinden. Dazu verwenden Sie die ursprüngliche Gleichung erneut mit s auf Null gesetzt:

%Vor%

Die linke Seite in C ist wie folgt aufgebaut:

%Vor%

Letzte Schritte:

  1. Um die arithmetische Legal C zu machen, wird dieser Byte-Offset in eine Ganzzahl umgewandelt.
  2. Um sicherzustellen, dass die Subtraktion in Einheiten von Bytes erfolgt, wird a_ptr in char * umgewandelt.
  3. Um dem Ergebnis den richtigen Typ zu geben, wird der Unterschied in struct s * umgewandelt.

Nachtrag: Wie Eli Bendersky betont, sollten Sie versuchen, Situationen zu vermeiden, in denen dieser Code notwendig wäre. Es gibt fast immer einen besseren Weg.

    
Norman Ramsey 20.06.2010, 04:14
quelle
5

Die Antwort ist: es tut es nicht. Es funktioniert nicht, auch wenn es auf den ersten Blick zu "funktionieren" scheint. Die "Antwort" versucht, einen Null-Zeiger zu dereferenzieren, was zu undefiniertem Verhalten führt. Also, es sei denn, Ihre Idee von "arbeiten" umfasst undefiniertes Verhalten, funktioniert diese Antwort nicht.

Es gibt mehr Probleme mit dieser Lösung, außer dem Versuch, den Nullpunkt zu ignorieren (obwohl das alleine vollkommen ausreicht, um diese "Antwort" auf den Mülleimer zu werfen). Ein weiteres Problem ist, dass das Ergebnis von (struct s*) 0 ein Nullzeiger von struct s * type ist. Die Sprache gibt keine Garantien über den tatsächlichen physikalischen Wert eines Nullzeigers. Es könnte leicht etwas wie 0xBAADFOOD sein, was die beabsichtigte Funktionalität der "Antwort" sofort zunichte machen würde.

Die richtige Implementierung der implizierten Technik würde das Standard-Makro offsetof beinhalten (bereits vorgeschlagen in Nyan's Antwort, aber ich werde es noch einmal wiederholen)

%Vor%     
AnT 20.06.2010 05:01
quelle
4

Sie können Offset von Makro verwenden.

%Vor%

Ich bin spät dran. Meine Internetverbindung ist langsam.

    
Nyan 20.06.2010 03:39
quelle
1

Dachte, das wäre hilfreich,

%Vor%

Ausgabe:

%Vor%

Also in deinem Fall,

%Vor%
  • Wirf aptr auf char *
  • subtrahiere den Offset von a wrt zu struct s
  • wird in struct s* umgewandelt
  • gib die resultant ptr zurück
joshu 05.08.2010 23:43
quelle

Tags und Links