Pouvez-vous printf valeur à partir d'un void * en C
Ok, je suis en train de faire cela, mais il ne fonctionne pas parce que je ne suis pas un déréférencement du pointeur... est-il un moyen de le faire sans faire une instruction switch pour le type?
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);
}
OriginalL'auteur ThorMJ | 2013-04-26
Vous devez vous connecter pour publier un commentaire.
Il semble que vous êtes en utilisant
void *
comme un bon marchéunion
. C'est une assez mauvaise idée. Je pense que vous trouverezunion
s en conjonction avecenum
s etswitch
es font de ce look tellement plus propre, en C. Vous trouverez lesswitch
parmi les#ifdef SWITCH
...#else
, et la switchless version parmi les#else
...#endif
.Avez-vous des preuves pour suggérer que ce code est trop grand ou trop lent? Sous quelle forme avez-vous l'obtenir?
C'est "trop grand" dans le code source de la taille ;)... c'est vraiment amélioré mon code taille beaucoup depuis que j'ai été en mesure de jeter le printf...
L'alternative est beaucoup plus grande dans le code source de la taille, et certainement pas plus clair. Peut-être, si vous souhaitez développer de plus en plus clair code, il pourrait être une bonne idée de se concentrer sur la réalisation de vos identifiants plus descriptif et cohérente. Pouvez-vous justifier l'utilisation de l'
ascii
dans vos identifiants lorsque vous compilez ce code sur un mainframe IBM, qui utilise un jeu de caractères EBCDIC?OriginalL'auteur autistic
Vous pouvez imprimer le pointeur lui-même avec quelque chose comme
%p
mais, si vous voulez imprimer ce qu'il désigne , vous avez besoin de lui dire ce qu'il est:Vous n'êtes pas autorisé à déréférencer un
void *
tout simplement parce que le compilateur ne sait pas ce qu'il indique.OriginalL'auteur paxdiablo
Pensez-y de cette façon :
Any
pointeur tout simplement des points pour un unique emplacement de mémoire.Mais letype
du pointeur de la souris déterminehow many
octets après que l'interprétation/envisager.Si c'estchar*
ensuite (selon le système) 1 octet est interprété,si c'est unint*
4 octets sont interprétés, et ainsi de suite.Mais unvoid*
avaitno type
.Donc vous ne pouvez pas déréférencer unvoid
pointeur en C, à cause de cette simple raison.Mais vous pouvez imprimer l'adresse des points à l'aide de la%p
spécificateur de format dansprintf()
et en passant quevoid
pointeur en argument.en supposant
int_ptr
est un pointeur entier,dire,etvoid_ptr
est un pointeur void.printf
a toutes les informations nécessaires à déréférencer le pointeur lui-même — si un tel format existé. (C'est en fait exactement commentscanf
, dont tous les arguments sont des pointeurs). Il n'a pas, mais c'est un problème d'interface, pas un fondamental de la carence de son approche.OriginalL'auteur Rüppell's Vulture
Il n'est pas clair ce que votre objectif réel est. Oui, il existe des moyens pour imprimer des données de type dépendant. L'idée de base est de créer votre propre fonction d'impression.
Mais seulement à alimenter le pointeur ne sera pas suffisant. Dans tous les cas, vous devez fournir le pointeur et le type de.
Permet de supposer que nous avons une fonction
myprint
:serait un appel possible.
myprint
est un varargs fonction qui a besoin de reconstituer la chaîne de format et les arguments, et puis peut appeler réelprintf
.Si vous utilisez des tas de variables, le type de la variable peuvent être stockées avec les données avec certains trucs (astuce: vérifiez comment
malloc
magasins de la taille de bloc). Cela rendrait les arguments supplémentaires superflu.Il y a d'autres solutions, mais une bonne suggestion n'est pas possible sans la connaissance de votre véritable objectif et les conditions exactes.
Pouvez-vous expliquer comment "vérifier comment
malloc
magasins de la taille de bloc" dans la norme C? Aussi, comment serait-elle la distinction entre un tableau dechar
la même taille que lesint
, et unint
, pour ne pas mentionner d'autres types qui pourraient avoir la même largeur?Lire la mise en œuvre de malloc ou trouver la documentation comment mallocs disposition de la mémoire des œuvres. Essentiellement, l'idée est qu'un pointeur n'est pas nécessairement le point de début du bloc de mémoire allouée. Si vous avez vos propres fonctions pour l'allocation/libération de la mémoire, vous pouvez utiliser les décalages négatifs pour les propres données. De toute façon il y a quelques contraintes, comme un bon alignement, pas de mélange de répartition, ...
OriginalL'auteur Dirk Stöcker
Je pense que le
printf
et ses amis (fprintf, etc.) peut déréférencer seulementchar*
qui sera interprété comme un c-string.En fait, vous pouvez écrire une telle fonction de vous-même, parce que vous allez dire à votre fonction de comment déréférencer
void*
avec format de drapeaux.Vous pouvez également ajouter à la
formats
que d'un tiers de la valeur d'un pointeur tenu de déréférencement de fonction qui prendra en argument unvoid*
et sera de retour la valeur à la place du pointeur.Ainsi, vous aurez besoin d'écrire une fonction pour chacun des types que vous utilisez dans votre formats et d'attribuer à chaque fonction pour chaque format correctement.
I don't thinks the printf and its friends can dereference from pointer except char* which will be interpreted as a sting
Je ne comprends pas ce que tu entends par là. Veuillez préciserChangé ma phrase bizarre pour être plus compréhensible.
En fait, je ne comprends toujours pas, je veux dire pourquoi printf déréférencement seulement
char*
? Il peut déréférencerint*
etc ?Vous ne pouvez pas passer le pointeur de int en argument de printf et imprimer la valeur de l'int. Vous avez besoin de passer la valeur de l'int à printf. Si vous passez un pointeur vous pouvez imprimer l'adresse de l'endroit où le pointeur de points. Mais vous pouvez passer un pointeur sur char et imprimer la valeur de ce char et le caractère suivant, et le suivant ... jusqu'à ce que '\0'.
Ok j'arrive. Si nous utilisons
char*
d'un C-stringprintf
pouvez imprimer jusqu'à ce que\0
forum il utilise%s
. En cas deint*
etc vous avez besoin pour déréférencer explicitement pour obtenir la valeurOriginalL'auteur JustAnotherCurious