Ich versuche C zu lernen und bin schon sehr verwirrt.
In den von mir verwendeten OOP-Sprachen gibt es die Möglichkeit, das Überladen von Methoden durchzuführen, wobei dieselbe Funktion verschiedene Parametertypen haben und den jeweils passenden aufrufen kann.
Nun in C weiß ich, dass dies nicht der Fall ist, also kann ich das folgende Problem nicht herausfinden, wie printf () funktioniert.
Zum Beispiel:
%Vor%Nun, da C das Überladen von Funktionen nicht unterstützt, wie kann printf eine beliebige Anzahl von Argumenten beliebiger Art verarbeiten und dann korrekt mit ihnen arbeiten?
Ich habe versucht, die Funktion printf () zu finden, indem ich das glibc-Quellpaket herunterlade, aber ich kann es anscheinend finden, obwohl ich weiter nachsehen werde.
Könnte jemand hier erklären, wie C die obige Aufgabe erfüllt?
C unterstützt eine Art von Funktionssignaturen mit dem Namen "varargs", die "variable (Anzahl von) Argumente" bedeuten. Eine solche Funktion muss mindestens ein erforderliches Argument haben. Im Fall von printf
ist die Formatzeichenfolge ein erforderliches Argument.
Wenn Sie eine C-Funktion aufrufen, werden die Argumente auf einer stackbasierten Maschine im Allgemeinen von rechts nach links auf den Stapel geschoben. Auf diese Weise ist das erste Argument für die Funktion das, das auf der "Spitze" des Stapels unmittelbar nach der Rückkehradresse gefunden wird.
Es sind C-Makros definiert, mit denen Sie die Variablenargumente abrufen können.
Die wichtigsten Punkte sind:
printf()
, wenn die Formatzeichenfolge falsch ist, liest der Code ungültige Ergebnisse aus dem Speicher und stürzt möglicherweise ab. va_start
initialisiert, mit va_arg
erhöht und mit va_end
. Ich habe eine Menge Code gepostet, den Sie vielleicht in der verwandten Frage interessant finden:
Beste Möglichkeit, eine va_list für die spätere Verwendung in C / C ++ zu speichern
Hier ist ein Skelett von printf()
, das nur ganze Zahlen formatiert ("% d"):
Intern wird printf
(zumindest normalerweise) einige Makros von stdarg.h verwenden. Die allgemeine Idee ist (eine stark erweiterte Version von) etwa so:
Das Ausarbeiten erfordert ziemlich viel Arbeit - es geht um Feldbreite, Genauigkeit, mehr Konvertierungen usw. Dies ist jedoch genug, um zumindest einen Eindruck davon zu vermitteln, wie Sie unterschiedliche Argumente unterschiedlicher Typen in Ihrem System abrufen Funktion.
(Vergessen Sie nicht, dass Sie, wenn Sie gcc (und g ++?) verwenden, -Wformat
in den Compileroptionen übergeben können, damit der Compiler überprüft, ob die Typen der Argumente mit der Formatierung übereinstimmen. Ich hoffe andere Compiler haben ähnliche Optionen.)
Könnte jemand hier erklären, wie C die obige Aufgabe erfüllt?
Blinder Glaube. Es setzt voraus, dass Sie sichergestellt haben, dass die Typen der Argumente perfekt mit den entsprechenden Buchstaben in Ihrer Formatzeichenfolge übereinstimmen. Wenn printf
aufgerufen wird, werden alle Argumente in binärer Form dargestellt, unzeremoniell verkettet und effektiv als einzelnes großes Argument an printf
übergeben. Wenn sie nicht übereinstimmen, haben Sie Probleme. Wenn printf
durch die Formatzeichenfolge iteriert, wird es jedes Mal, wenn es %d
sieht, 4 Bytes von den Argumenten nehmen (angenommen 32-Bit, es wären natürlich 8 Bytes für 64-Bit-Ints) und es wird sie als interpretieren eine Ganzzahl.
Vielleicht haben Sie nun tatsächlich double
übergeben (normalerweise doppelt so viel Speicher wie ein int
). In diesem Fall nimmt printf
nur 32 dieser Bits und stellt sie als Integer dar. Dann nimmt das nächste Formatfeld (vielleicht ein %d
) den Rest des Double.
Wenn also die Typen nicht perfekt zusammenpassen, werden Sie sehr unlesbare Daten erhalten. Und wenn Sie Pech haben, haben Sie undefiniertes Verhalten.
Tags und Links c printf overloading