10
votes

TYPE CASTING ENTREGER EN VOID *

#include <stdio.h>
void pass(void* );
int main()
{
    int x;
    x = 10;
    pass((void*)x);
    return 0;
}
void pass(void* x)
{
   int y = (int)x;
   printf("%d\n", y);
}


output: 10
my questions from the above code..
what happens when we typecast normal variable to void* or any pointer variable?
We have to pass address of the variable to the function because in function definition argument is pointer variable. But this code pass the normal variable ..
This format is followed in linux pthread programming... I am an entry level C programmer. I am compiling this program in linux gcc compiler..

3 commentaires

"Que se passe-t-il lors de la typcation de la variable normale à vide * ou à toute variable de pointeur?" Dépendant de la mise en œuvre. Notez qu'il n'est pas garanti que la coulée d'un int sur Void * et de retour donne la valeur d'origine (bien que généralement, elle le fait).


Qu'est-ce que tu essayes réellement d'atteindre?


Généralement, ce type de coulée de type ne présente aucune inquiétude tant que les adresses sont codées selon la même longueur que le "type de variable" ( int dans votre cas). Mais @danielelfischer a raison le risque est que vous perdriez des informations si la capacité de stockage de votre variable est inférieure à la longueur de l'adresse. Ainsi, quelque chose comme void * ptr1 = a_pointer (); Char PTR_C = (CHAR) PTR1; vide * ptr2 = (vide *) ptr_c; conduirait à l'assertion ptr1! = ptr2


3 Réponses :


11
votes

Je devine seulement ici, mais je pense que ce que vous êtes censé faire est de passer la adresse em> de la variable à la fonction. Vous utilisez l'adresse de l'opérateur & code> pour faire ce xxx pré>

et dans la fonction, vous obtenez la valeur du pointeur à l'aide de l'opérateur de déséroférence * : P>

int y = *((int *) pointer);


6 commentaires

«Je pense que ce que vous devriez faire est de transmettre l'adresse de la variable à la fonction" Pas nécessairement. S'il s'agit de données sur une procédure de thread, vous voulez très souvent passer par la valeur.


@DavidHeffernan j'ai reformulé cette phrase un peu.


Si vous allez transmettre l'adresse, vous devez généralement exercer un autre contrôle sur la durée de vie de l'objet. Habituellement, cela signifie que le pointeur est attribué avec MALLOC , puis détruit en appelant gratuit dans le procès thread. Le stockage automatique n'est pas ce dont vous avez besoin pour Thread Proc. Je sais que le code de Q n'est pas pour Thread Proc, mais il est clairement mentionné comme la motivation.


@DavidHeffernan, Sane thread API n'enverrait pas de données intégrales aux procédures de thread, elles enverraient des pointeurs. Même si ce que vous dites sur la durée de vie de l'objet est vrai, les types intégraux sont trop limités pour une API générique.


Et dans ce contexte, il est très très fréquent de voir les programmeurs de type paresseusement, lancez le Void * à quelque chose comme int . Quoi qu'il en soit, si l'OP veut un schéma paranoïaque, il peut toujours maloc la quantité appropriée de données pour réussir sa valeur à l'aide d'un pointeur!


Cela fonctionne également: int x = 10; Void * pointeur = & (int) {x};



0
votes

S'il vous plaît lire Pourquoi Glib fournir des macros pour cela Type de conversions, il n'est pas nécessaire de répéter le texte ici. Le point principal est: un pointeur a une taille dépendante de la plate-forme.


1 commentaires

Au contraire, il est un besoin de répéter le texte ici. Ce lien va tôt de pourrir plus tôt ou ultérieur, transformant votre réponse à un complètement inutile. Voir ici pour plus d'informations.



0
votes

Si vous envisagez d'utiliser Pthreads et que vous prévoyez de passer la fonction Pass à pthread_create , vous devez MALLOC / GRATUIT Les arguments que vous envisagez d'utiliser (même si la fonction filetée a besoin d'un seul int).

Utilisation d'une adresse entière (comme & x ) est probablement faux, en effet, chaque modification que vous allez exécuter sur x affectera le comportement Pass .


2 commentaires

Vous n'avez pas nécessairement avoir à. Vous pouvez également conserver les paramètres globaux, ou même sur la pile, si c'est la même fonction qui appelle pthread_create et pthread_join qui est assez souvent le cas ( principal < / code> crée des threads, puis les rejoint avant la sortie).


@Shahbaz Tu pourrais ... Mais je ne suggérerai pas à un débutant C pour utiliser les globaux. En ce qui concerne la pile, j'ai écrit quelques bibliothèques utilisant Pthreds, je ne suis donc pas d'accord sur ce que vous décrivez "est assez souvent le cas". Mais, bien sûr, dans ce cas particulier, vous pouvez passer une adresse de variable locale, si vous savez ce que vous faites .