Wie funktioniert die bestimmte C-Funktion arbeiten?
Ich versuche, C zu lernen und bin sehr verwirrt bereits.
In der OOP-Sprachen, die ich haben verwendet es gibt die Fähigkeit zum ausführen einer Methode überladen, wo die gleiche Funktion könnten unterschiedliche parameter-Typen und call-welcher war am besten geeignet.
Nun in C weiß ich, dass dies nicht der Fall, so dass ich kann nicht herausfinden, Folgendes problem, Wie printf() funktioniert.
Beispiel:
char chVar = 'A';
int intVar = 123;
float flVar = 99.999;
printf("%c - %i - %f \n",chVar, intVar, flVar);
printf("%i - %f - %c \n",intVar, flVar, chVar);
printf("%f - %c - %i \n",flVar, chVar, intVar);
Nun als C does ' NT support-Funktion überladen, Wie funktioniert printf verwalten beliebige Anzahl Argumente beliebigen Typs, und arbeiten Sie sich dann richtig mit Ihnen?
Habe ich versucht zu finden, die printf () - arbeiten durch das herunterladen der glibc-source-Paket kann aber ganz scheinen, um es zu finden, aber ich werde weiter suchen.
Könnte jemand hier erklären, wie C führt die oben angegebene Aufgabe?
- Wenn Sie mehr wissen wollen, Lesen Sie auf den Aufruf-Konventionen und der stack
- Deine Frage über C, aber Sie sagen, "ich bin versucht zu lernen, C++." Wenn Sie versuchen zu lernen, C++, ist es am besten zu beginnen durch die Vermeidung von C-teilen, die die Sprache (und bleiben auf den höheren Ebenen der Abstraktion, die C++ bietet), dann, sobald Sie sind komfortabel mit, dass, zu Graben, in anderen teilen der Sprache.
- Wenn Sie nicht wollen, zu kümmern, dann pass
-Wformat
als argument zu g++. Andere Compiler sollten, ich denke/hoffe/erwarte, haben ähnliche Warnungen. Dies bewirkt, dass der compiler überprüfen, dass die Typen übereinstimmen. - Mögliche Duplikate von C/C++ - Funktion-Definitionen ohne Montage
Du musst angemeldet sein, um einen Kommentar abzugeben.
C unterstützt eine Art von Funktion mit der Signatur genannten "varargs" bedeutet "variable (Anzahl) Argumente". Eine solche Funktion muss mindestens ein erforderliches argument. Im Fall von
printf
den format-string ist ein erforderliches argument.In der Regel, auf eine stack-basierte Maschine, wenn Sie rufen Sie eine C-Funktion, die Argumente auf dem Stapel von rechts nach Links. Auf diese Weise kann das erste argument der Funktion ist, die auf die "oben" auf dem stack, nur nach der Rückkehr-Adresse.
Gibt es C-Makros definiert, die es erlauben das abrufen der Variablen Argumente.
Die wichtigsten Punkte sind:
printf()
, wenn der format-string ist falsch, der code wird gelesen ungültige Ergebnisse aus dem Speicher, eventuell abzustürzen.va_start
, erhöht, mitva_arg
, und veröffentlicht mitva_end
.Ich habe eine Tonne von code, den Sie interessant finden, Sie auf die Verwandte Frage:
Beste Weg, um eine va_list, die für die Spätere Verwendung in C/C++
Hier ist ein Skelett einer
printf()
denen nur die Formate Integer ("%d"):Intern
printf
wird (zumindest in der Regel) verwenden einige Makros stdarg.h. Die Allgemeine Idee ist (eine erweiterte version von) so etwas wie dieses:Entfleischen es aus erfordert einiges an Arbeit-Umgang mit Feldbreite, Präzision, mehr Konvertierungen, etc. Dies ist genug, aber zumindest geben Sie einen Geschmack, wie Sie das abrufen unterschiedlicher Argumente unterschiedlicher Typen innerhalb Ihrer Funktion.
my_printf
undmy_fprintf
, die die Anrufe derva_start
undva_end
.(Vergessen Sie nicht, dass, wenn Sie mit gcc (g++?), Sie können pass
-Wformat
in den compiler-Optionen, um dem compiler zu prüfen, dass die Typen der Argumente passen Sie die Formatierung an. Ich hoffe, andere Compiler bieten ähnliche Möglichkeiten.)Blind glauben. Es wird davon ausgegangen, dass Sie sichergestellt haben, dass die Typen der Argumente passen perfekt mit den entsprechenden Buchstaben in das format string. Wenn
printf
heißt, alle Argumente sind vertreten im Binär -, kurzerhand miteinander verkettet, und übergeben effektiv wie ein einziges großes argumentprintf
. Wenn Sie nicht übereinstimmen, werden Sie Probleme haben. Alsprintf
durchläuft der format-string, jedes mal, wenn Sie sehen%d
es werden 4 bytes aus den Argumenten (vorausgesetzt, 32-bit, es wäre 8 bytes für 64-bit-ints natürlich) und er interpretiert Sie als eine ganze Zahl.Nun, vielleicht Sie tatsächlich bestanden
double
(in der Regel die Aufnahme doppelt so viel Speicher wie eineint
), in welchem Fallprintf
dauert nur 32 der bits und vertreten Sie als eine ganze Zahl. Dann das nächste Feld format (vielleicht ein%d
) wird den rest der Doppel.Also im Grunde, wenn die Typen nicht übereinstimmen perfekt erhalten Sie arg verstümmelt Daten. Und wenn du Pech hast, haben Sie ein Undefiniertes Verhalten.