Können Sie printf Wert von einem void * in C
Ok, ich bin versucht, dies zu tun, aber es funktioniert nicht denn ich bin nicht dereferenzieren Sie den Zeiger... gibt es einen Weg, es zu tun, ohne dass eine switch-Anweisung für den Typ?
typedef struct
{
char *ascii_fmtstr;
int len;
int (*deserializer)(void *in, const char *ascii);
int (*serializer)(const void *in, char *ascii);
} FORMAT;
const FORMAT formats[]=
{
{"%d\n", 2/2} //Int
,{"%s\n", STRSIZE/2} //String
,{"%.4f\n", 4/2} //Float
,{"%lld", 4/2} //Long-Long
,{"%s\n", STRSIZE/2} //Time
};
typedef struct {
int fmtindex;
void * vp;
} JUNK;
float f = 5.0f;
int i=1;
char foo[]="bar";
JUNK j[] = {
{2, &f}
,{0, &i}
,{1, foo}};
void dump(void)
{
int i;
for(i=0;i<2;i++)
printf(formats[j[i].fmtindex].ascii_fmtstr, j[i].vp);
}
InformationsquelleAutor ThorMJ | 2013-04-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie es scheint, bist du mit
void *
als Billigunion
. Das ist eine ziemlich schlechte Idee. Ich glaube, Sie findenunion
s in Verbindung mitenum
s undswitch
es diese Aussehen so viel ordentlicher, in C. finden Sie dieswitch
unter den#ifdef SWITCH
...#else
, und die switchlose version unter den#else
...#endif
.Haben Sie irgendwelche Hinweise darauf, dass dieser code ist zu groß oder zu langsam? In welcher form hast du es erhalten?
Es ist "zu groß" in source code der Größe ;)... es ist wirklich verbessert meine code-Größe viel, da ich in der Lage war, Sie zu verwerfen, die printf...
Die alternative ist viel größere in source code der Größe, und sicherlich nicht mehr klar. Vielleicht, wenn Sie wollen, zu entwickeln, klarer code, es könnte eine gute Idee sein, sich auf Ihre Bezeichner mehr aussagekräftig und konsistent. Kann man es rechtfertigen, mit
ascii
in Ihre Kennungen auch, wenn Sie diesen code kompilieren auf einem IBM-mainframe, die mit einem EBCDIC-Zeichensatz?InformationsquelleAutor autistic
Drucken können Sie die Zeiger selbst mit so etwas wie
%p
aber, wenn Sie drucken möchten, was es Punkte , Sie brauchen, um zu sagen, was es ist:Darf man nicht dereferenzieren eine
void *
einfach, weil der compiler nicht weiß, was es Punkte zu.InformationsquelleAutor paxdiablo
Denken Sie an es auf diese Weise :
Any
Zeiger einfach Punkte auf eine single Speicher.Aber dietype
des Zeigers bestimmthow many
bytes nach, dass zu interpretieren/zu betrachten.Wenn eschar*
dann (je nach system) 1 byte interpretiert wird,wenn es sich um eineint*
4 bytes interpretiert werden, und so weiter.Aber einvoid*
hatteno type
.So kann man nicht dereferenzieren einevoid
Zeiger in C aufgrund dieses einfachen Grund.Aber drucken Sie sich die Adresse es Punkte, über die%p
Formatbezeichner inprintf()
und nebenbei, dassvoid
- Zeiger als argument.vorausgesetzt
int_ptr
ist ein integer-Zeiger,zu sagen und zuvoid_ptr
ist ein void-Zeiger.printf
hat alle notwendigen Informationen zu dereferenzieren Sie den Zeiger selbst, wenn solch ein format existiert. (Dies ist in der Tat genau wiescanf
, deren sämtliche Argumente sind Zeiger funktioniert.) Es muss nicht, aber es ist ein interface-problem, nicht ein grundlegender Mangel seines Konzepts.InformationsquelleAutor Rüppell's Vulture
Es ist nicht klar, was dein eigentliches Ziel ist. Ja, es gibt Möglichkeiten zum drucken Datentyp abhängig. Im Grunde die Idee ist, erstellen Sie Ihre eigenen drucken-Funktion.
Aber nur die Versorgung der Zeiger wird nicht genug sein. In jedem Fall benötigen Sie zur Versorgung Zeiger und die Art von es.
Nehmen wir an, wir haben eine Funktion
myprint
:wäre eine mögliche nennen.
myprint
ist eine varargs-Funktion dann, das zu rekonstruieren, den Formatstring und Argumente und dann können call realprintf
.Wenn Sie die heap-Variablen der Typ der Variablen gespeichert werden können, zusammen mit den Daten mit ein paar tricks (Hinweis: prüfen Sie, wie
malloc
speichert die block-Größe). Dies würde die weiteren Argumente überflüssig wurde.Gibt es andere Lösungen, aber eine gute Anregung ist nicht möglich, ohne wissen über Ihr eigentliches Ziel und die genauen Bedingungen.
Können Sie erklären, wie man "prüfen, wie
malloc
speichert die block size" in der standard-C? Auch, wie würde die Unterscheidung zwischen einem array vonchar
die gleiche Größe wie eineint
, und einint
, nicht zu erwähnen, irgendwelche anderen Typen, vielleicht haben die gleiche Breite?Entweder Lesen Sie die Implementierung von malloc oder finden Sie einige Unterlagen, wie mallocs memory layout funktioniert. Im wesentlichen die Idee ist, dass ein Zeiger müssen nicht unbedingt auf den Anfang des allokierten Speicherblocks. Wenn Sie eigene Funktionen für die allocation/deallocation, dann können Sie die negativen offsets für eigene Daten. Trotzdem gibt es einige Einschränkungen, wie die richtige Ausrichtung, keine Vermischung von Allokation, ...
InformationsquelleAutor Dirk Stöcker
Ich denke, die
printf
und seine Freunde (fprintf, etc.) kann dereferenzieren nurchar*
die wird interpretiert als c-string.Eigentlich kann man schreiben, wie die Funktion selbst, denn Sie sagen, Ihre Funktion, wie zum dereferenzieren
void*
mit format-flags.Außerdem können Sie die
formats
als Dritten Wert einen Zeiger auf erforderliche Dereferenzierung Funktion, die als argument einevoid*
und wird wieder der Wert anstelle der Zeiger.So müssen Sie eine Funktion schreiben, die für jeden der Typen, die Sie verwenden, in Ihren Formaten und weisen Sie jede Funktion auf jedes format richtig.
I don't thinks the printf and its friends can dereference from pointer except char* which will be interpreted as a sting
Ich Verstand nicht, was Sie damit meinen. Bitte erläuternGeändert meine seltsamen Satz verständlicher sein.
Eigentlich habe ich noch immer nicht verstehe, ich meine, warum kann printf dereferenzieren nur
char*
? Es kann dereferenzierenint*
etc auch ?Sie können nicht übergeben Sie den Zeiger auf int als argument von printf () und drucken Sie den Wert der int. Sie müssen übergeben Sie den Wert von int zu printf. Wenn Sie einen Zeiger übergeben drucken können Sie die Adresse wo der pointer verweist. Aber Sie können übergeben Sie einen Zeiger auf char, und drucken Sie den Wert, char und der nächste char und die nächste ... bis '\0' gefunden wird.
Ok, i get it. Wenn wir
char*
von einem C-stringprintf
können drucken, bis\0
iff es verwendet%s
. Incaseint*
etc müssen Sie explizit dereferenzieren, um den WertInformationsquelleAutor JustAnotherCurious