2014-06-29 7 views
7

OK, ich habe gehört Dinge wie Sie sollten einen Zeiger auf eine generische, d. H. void * vor dem Drucken und muss die Verwendung von %p Platzhalter anstelle von %d in der printf Funktion zum Drucken sie üben.Warum wird empfohlen, vor dem Drucken einen Zeiger auf einen generischen Zeiger zu setzen?

Ich habe gerade das Gefühl, dass es gemacht werden könnte, um das Abschneiden großer Adressen während des Druckens zu verhindern, oder ist es etwas anderes? Aber der Punkt ist, dass, wenn Sie auf einer Maschine mit Bit-Zeiger und Bit-Ganzzahlen sind; Verwendung von %p anstelle von %d wird nur die Aufgabe erledigen.

Kennt jemand irgendwelche praktische Situationen, in denen diese Gießtechnik hilfreich ist?

+0

können Sie eine Referenz geben – CMPS

+0

@Amir, tut mir leid, ich habe keine Referenzen wie gesagt, ich habe gehört. – darxtrix

Antwort

10

Da die Spezifikation des %p Spezifizierer ist, dass es eine void * druckt. Es kann keine anderen Arten von Zeigern drucken.

Mit printf muss der Aufrufer das Argument in den richtigen Typ konvertieren; Die printf-Funktion kann keine Konvertierungen durchführen, da sie keinen Zugriff auf die Typinformationen zu den Argumenten hat, die Sie tatsächlich übergeben haben. Sie kann nur davon ausgehen, dass Sie die richtigen übergeben haben.

C99 7.19.6.1 # 7

p Das Argument ist ein Zeiger auf nichtig. Der Wert des Zeigers ist umgewandelt in eine Folge von Druckzeichen, in einer Implementierung definierten Art und Weise.

C99 7.19.6.1 # 9

Wenn ein Argument nicht der richtige Typ für die entsprechende Umwandlung Spezifikation ist, ist das Verhalten undefiniert.

"Undefiniertes Verhalten" bedeutet, dass alles passieren kann. In der Praxis kommt man wahrscheinlich davon durch, wenn der übergebene Zeiger die gleiche Größe und Darstellung wie void * hat. Aber Sie sollten sich nicht auf undefiniertes Verhalten verlassen.

Auf modernen Systemen haben alle Objektzeiger (d. H. Keine Funktionszeiger) dieselbe Größe und Darstellung. Wenn Sie wissen, dass Sie sich auf einem solchen System befinden, und es nicht wirklich wichtig ist, dass sich das Programm falsch verhält, dann kommen Sie wahrscheinlich mit dem falschen Zeigertyp durch.

Ein Ort, wo es wichtig wäre, wenn Sie versuchen, einen Funktionszeiger zu drucken; wie es moderne Systeme gibt, die Funktionszeiger eine andere Größe als Objektzeiger haben. Es ist nicht garantiert, dass der Compiler einen Funktionszeiger auf void * ausgibt, aber zumindest erhalten Sie eine Compiler-Fehlermeldung, wenn Sie es versuchen.

Verwandte Themen