Concept de vide pointeur dans la programmation en C
Est-il possible de déréférencer un pointeur void sans conversion de type dans le langage de programmation C?
Aussi, est-il possible de généraliser une fonction qui permet de recevoir un pointeur et de le stocker dans un vide pointeur et en utilisant ce vide pointeur, nous pouvons faire une fonction généralisée?
par exemple:
void abc(void *a, int b)
{
if(b==1)
printf("%d",*(int*)a); //If integer pointer is received
else if(b==2)
printf("%c",*(char*)a); //If character pointer is received
else if(b==3)
printf("%f",*(float*)a); //If float pointer is received
}
Je veux faire de cette fonction générique sans l'aide de if-else - est-ce possible?
Aussi si il y a de bons articles sur internet qui expliquent le concept de vide pointeur, alors il serait utile si vous pouviez fournir l'Url.
Aussi, est de l'arithmétique des pointeurs avec le vide pointeurs possible?
Vous devez vous connecter pour publier un commentaire.
Non,
void
indique l'absence de type, il n'est pas quelque chose que vous pouvez déréférencement ou de l'attribuer.Vous ne pouvez pas simplement déréférencement d'elle de façon portable, car il ne peut pas être correctement alignées. Il peut être un problème sur certaines architectures comme le BRAS, où pointeur vers un type de données doit être aligné à la limite de la taille du type de données (par exemple, le pointeur d'entier de 32 bits doivent être alignés à la limite de 4 octets pour être déréférencés).
Par exemple, la lecture
uint16_t
devoid*
:De l'arithmétique des pointeurs n'est pas possible sur les pointeurs de
void
en raison du manque de valeur concrète sous le pointeur et donc la taille.void *
pointeurs de même quechar *
, mais ce n'est pas standard et vous ne devriez pas compter sur elle.void*
, le compilateur ne pas se plaindre).En C, un
void *
peut être converti en un pointeur vers un objet d'un type différent sans un cast explicite:Cela n'a pas d'aide à la rédaction de votre fonction plus générique, bien.
Vous ne pouvez pas déréférencer un
void *
avec la conversion à un autre type de pointeur comme un déréférencement d'un pointeur est l'obtention de la valeur de la pointe-de objet. Un nuvoid
n'est pas un type valide donc derefencing unvoid *
n'est pas possible.De l'arithmétique des pointeurs est sur la modification des valeurs de pointeur par des multiples de la
sizeof
de la pointe-aux objets. Encore une fois, parce quevoid
n'est pas un vrai type,sizeof(void)
n'a pas de sens si l'arithmétique des pointeurs n'est pas valide survoid *
. (Certaines implémentations permettent, à l'aide de l'équivalent de l'arithmétique des pointeurs pourchar *
.)void **
est ok, bien, droit?void*
type.void abc(void *a, int b)
. Mais pourquoi ne pas utiliservoid abc(int *a, int b)
, puisque dans votre fonction, vous finirez par définirint *test = a;
, il permettrait de sauver une variable, et je ne vois pas d'autres avantages par la définition d'une autre variable. Je vois beaucoup de codes de l'écrit dans l'aide de cette manièrevoid *
en tant que paramètres, et la coulée de variables plus tard en la fonction. Mais puisque cette fonction est écrite par l'auteur, donc il doit savoir l'utilisation de la variable, donc, pourquoi utiliservoid *
? MerciVous devez être conscient que, dans C, contrairement à Java ou C#, il n'y a absolument aucune possibilité de réussir à "deviner" le type de l'objet d'un pointeur void* points à. Quelque chose de semblable à "getClass()" n'existe tout simplement pas, puisque cette information est nulle part pour être trouvée. Pour cette raison, le genre de "générique" vous cherchez toujours explicite de la métainformation, comme le "int b" dans votre exemple, ou la chaîne de format dans le printf de la famille de fonctions.
Un vide pointeur est connu comme pointeur générique, qui peut se référer à des variables de tout type de données.
Jusqu'à présent, mon sous-estimer à vide pointeur est comme suit.
Lorsqu'un pointeur est une variable déclarée à l'aide de mot-clé void – il devient d'un usage général pointeur de variable. Adresse d'une variable de n'importe quel type de données (char, int, float, etc.)peut être attribué à un vide pointeur de variable.
Depuis d'autres pointeur de type de données peut être affectée à vide pointeur, je l'ai donc utilisé en absolut_value(code indiqué ci-dessous) de la fonction. D'une façon générale la fonction.
J'ai essayé d'écrire un simple code C qui prend en entier ou flottant comme un argument et tente de faire +ve, si le résultat est négatif. J'ai écrit le code suivant,
Mais j'obtenais l'erreur, donc je suis venu pour savoir que mon entente avec le vide pointeur n'est pas correct :(. Alors maintenant, je vais aller vers de collecter des points pourquoi est-ce si.
Les choses que j'ai besoin d'en savoir plus sur les pointeurs void est que.
Nous avons besoin de transtypage le vide pointeur de variable de déréférencement d'elle. C'est parce que le vide pointeur n'a pas de type de données associé. Il n'y a pas de chemin le compilateur ne peut pas savoir (ou de le deviner?) ce type de données est indiqué par le pointeur void. Donc, pour prendre les données pointé par un pointeur void nous avons catalogué avec le bon type de données repliée à l'intérieur du vide pointeurs emplacement.
Un vide pointeur peut être très utile si le programmeur n'est pas certain du type de données de données saisies par l'utilisateur final. Dans un tel cas, le programmeur peut utiliser un vide pointeur à l'emplacement de l'inconnu type de données. Le programme peut être configuré de manière à demander à l'utilisateur de déterminer le type de données et le type coulée peut être effectuée selon les informations saisies par l'utilisateur. Un extrait de code est donné ci-dessous.
Un autre point important que vous devez garder à l'esprit à propos de nulle pointeurs, c'est que – l'arithmétique des pointeurs ne peuvent pas être effectuées dans un vide pointeur.
Alors maintenant, j'ai compris quel était mon erreur. Je suis en train de corriger le même.
Références :
http://www.antoarts.com/void-pointers-in-c/
http://www.circuitstoday.com/void-pointers-in-c.
Le Nouveau code est comme indiqué ci-dessous.
Merci,
Non, il n'est pas possible. Ce type de la valeur déréférencée ont?
printf
. Cette réponse a un bon exemple pour cela.int b
avec un enum, mais de faire en toute modification ultérieure à celle enum serait briser cette fonction.%p
peut s'appliquer àvoid *
)La seule manière simple ce que je vois est d'utiliser la surcharge .. ce qui n'est pas disponible dans la programmation en C langage autant que je sache.
Avez-vous pensé à la programmation en C++ langage de votre programme ? Ou est-il une contrainte qui interdit son utilisation?
Vous pouvez facilement imprimer un vide imprimante
void
a la même taille queint
?void
pointeur, c'est l'impression de laint
à l'adresse de la mémoire que le pointeur contient (qui serait dans ce cas la valeur dep
).Parce que C est statiquement typé, fortement typé langue, vous devez décider du type de la variable avant de compiler. Lorsque vous essayez d'imiter les médicaments génériques en C, vous finirez tentative de réécrire en C++, donc il serait préférable d'utiliser le C++ à la place.
vide pointeur est un pointeur générique.. l'Adresse de tout type de données d'une variable peut être attribué à un pointeur void.
Voici une brève pointeur sur
void
pointeurs: https://www.learncpp.com/cpp-tutorial/613-void-pointers/En supposant que la mémoire de la machine est octets adressables et ne nécessite pas aligné les accès, le plus générique et atomique (le plus proche de la machine au niveau de la représentation) de l'interprétation d'un
void*
est comme un pointeur vers un octet,uint8_t*
. Le moulage d'unvoid*
à unuint8_t*
vous permettra, par exemple, pour imprimer la première 1/2/4/8/cependant-beaucoup-vous le désir d'octets à partir de cette adresse, mais vous ne pouvez pas faire grand chose d'autre.Vous ne pouvez pas déréférencer un pointeur sans en préciser le type, parce que les différents types de données ont des tailles différentes dans la mémoire, c'est à dire un int soit 4 octets, un char de 1 octet.
Fondamentalement, en C, les "types" sont une façon d'interpréter les octets en mémoire. Par exemple, ce que le code suivant
Dit "Quand je le lance en main, je veux allouer 4 (de la taille d'un entier) + 4 (de la taille d'un entier) = 8 (nombre total d'octets) de mémoire. Quand j'écris".x' comme une lvalue sur une valeur dont le type d'étiquette de Point au moment de la compilation, de récupérer des données à partir du pointeur de la mémoire de l'emplacement de plus de quatre octets. Donner la valeur de retour de la compilation label "int.""
À l'intérieur de l'ordinateur lors de l'exécution, votre "Point" de la structure ressemble à ceci:
Et voici ce que votre
void*
type de données pourrait ressembler à: (en supposant un ordinateur 32 bits)Cela ne fonctionne pas, pourtant, void * peut beaucoup vous aider dans la définition de pointeur générique de fonctions et de la passer en argument à une autre fonction (semblable à de rappel en Java) ou de définir une structure similaire à la programmation orientée objet.