Ich habe Grundlagen von Makros gemacht. Ich definiere ein Makro wie folgt:
um Integer in String zu konvertieren.
Konvertiert dieses Makro die ganze Zahl perfekt in eine Zeichenkette? Ich meine, gibt es Situationen, in denen dieses Makro fehlschlagen kann?
Kann ich dieses Makro verwenden, um Standardbibliotheksfunktionen wie itoa()
?
zum Beispiel:
%Vor% Das obige Programm funktioniert wie erwartet.
Interessanterweise kann dieses Makro sogar float
value in string konvertieren.
zum Beispiel:
%Vor%funktioniert gut.
Bis jetzt habe ich itoa
function benutzt, um int in alle meine Projekte zu konvertieren. Kann ich itoa
in allen Projekten sicher ersetzen? Weil ich weiß, dass es weniger Overhead bei der Verwendung von Makro als Funktionsaufruf gibt.
In C können Sie itoa verwenden oder wenn Sie verzweifelt sind und es vermeiden möchten, verwenden Sie zum Beispiel snprintf :
%Vor%Das Problem mit Ihrem Makro ist, dass Sie über Konstanten nachdenken, aber natürlich wird Ihr Makro gebrochen, wenn Sie eine Variable verwenden müssen, die eine Ganzzahl enthält. Ihr Makro würde versuchen, den Makronamen im Gegensatz zu dem Wert, den er halten würde, zu stringieren.
Wenn Sie mit Konstanten zufrieden sind, ist Ihr Makro "gut", sonst ist es b0rked.
Makros werden während der (vor genauem) Kompilierzeit ausgeführt, so dass Sie eine Literalnummer in Ihrem Quellcode in eine Zeichenkette umwandeln können, aber nicht eine Zahl, die in einer Variablen gespeichert ist
In Ihrem Beispiel verwendet INTTOSTR(56)
den Stringification-Operator des Präprozessors, der schließlich in "56"
resultiert. Wenn Sie es für eine Variable aufrufen, erhalten Sie den Namen der Variablen, nicht aber ihren Inhalt.
Ihr Makro konvertiert keine Ganzzahlen in Zeichenfolgen, es konvertiert ein Literal in ein Zeichenfolgenliteral, was etwas ganz anderes ist.
Literale sind beliebige Zahlen oder Definitionen von Werten in Ihrem Code. Wenn Sie int x = 10;
die Zahl 10
in einem Ganzzahl-Literal eingeben, ist x
eine Variable und int
ist der Typ. const char* ten = "10";
definiert auch ein Literal, in diesem Fall ein Stringliteral , mit dem Wert "10"
und einer Variablen namens ten
, die auf die Adresse zeigt, wo dieses Literal definiert ist. Was Ihr Makro tatsächlich tut, ist die Art und Weise, wie das Literal dargestellt wird, bevor eine tatsächliche Kompilierung von einem Integer-Literal in ein String-Literal fortgesetzt wird.
Die eigentliche Änderung wird also vor jeder Kompilierung vorgenommen, nur auf Quellcodeebene. Makros sind keine Funktionen und können Speicher nicht untersuchen, und Ihre Konvertierung würde nicht mit Variablen funktionieren. Wenn Sie versuchen:
%Vor% Sie wären sehr erstaunt, wenn Sie feststellen würden, dass Ihre Variable ten
tatsächlich den Wert "x" enthält. Das liegt daran, dass x als Literal und nicht als Variable behandelt wird.
Wenn Sie sehen wollen, was passiert, empfehle ich Ihrem Compiler, bei der Vorverarbeitung anzuhalten und die Ausgabe zu sehen, bevor Ihr Code tatsächlich kompiliert wird. Sie können dies in GCC tun, wenn Sie das -E-Kennzeichen übergeben.
PS. Was den scheinbaren "Erfolg" bei der Konvertierung von Float-Werten betrifft, so zeigt es nur die Gefahr von Makros: Sie sind nicht typsicher. Es betrachtet 53.5 nicht als Float, sondern als Token, dargestellt durch die Zeichen 5, 3,. und 5 im Quellcode.