Tableau de POINTEURS vers Plusieurs Types de C
Est-il possible d'avoir un tableau de plusieurs types en utilisant malloc
?
EDIT:
Actuellement, j'ai:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define int(x) *((int *) x)
int main() {
void *a[10];
a[0] = malloc(sizeof(int));
int(a[0]) = 4;
char *b = "yola.";
a[1] = malloc(strlen(b)*sizeof(char));
a[1] = b;
printf("%d\n", int(a[0]));
printf("%s\n", a[1]);
}
Mais c'est salissant. D'autres moyens?
EDIT: à la Nettoyer un peu.
Beaucoup de choses sont possibles, mais beaucoup ne sont pas une bonne idée. Utilisation
En plus d'être une mauvaise idée, comment peut-il être fait?
Qu'entendez-vous par "balisé avec un enum"?
Il y a une notion de tagged union, dans lequel une valeur externe (le tag) vous indique quelle partie de l'union est actuellement en cours d'utilisation. Si vous n'avez ni qui ni un autre moyen fiable pour dire que la partie est en cours d'utilisation, vous êtes dirigé à un comportement indéterminé (ou tout ce que dit la norme peut se produire lorsque vous écrivez à Un champ, mais le lire comme si le champ B a été défini).
struct
s et union
s (le dernier idéalement balisé avec un enum
de sorte que vous savez quel est le champ où l'accès).En plus d'être une mauvaise idée, comment peut-il être fait?
Qu'entendez-vous par "balisé avec un enum"?
Il y a une notion de tagged union, dans lequel une valeur externe (le tag) vous indique quelle partie de l'union est actuellement en cours d'utilisation. Si vous n'avez ni qui ni un autre moyen fiable pour dire que la partie est en cours d'utilisation, vous êtes dirigé à un comportement indéterminé (ou tout ce que dit la norme peut se produire lorsque vous écrivez à Un champ, mais le lire comme si le champ B a été défini).
OriginalL'auteur tekknolagi | 2011-10-17
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas avoir un éventail de différents types, exactement. Mais vous pouvez obtenir un effet similaire (pour certaines fins, au moins) dans un certain nombre de façons différentes.
Si vous voulez juste un peu de valeurs de types différents, assemblés, mais le nombre et les types de valeurs ne changent pas, vous avez juste besoin d'un
struct
et peuvent y accéder par le nom:Si vous savez quels sont les types que vous pourriez utiliser, vous pouvez créer un syndicat ou d'une structure contenant une union de sorte que vous pouvez marquer avec le type. Vous pouvez ensuite créer un tableau de ceux-ci. Le
type
membre vous permet de vérifier pour voir ce que vous avez stocké dans chaque élément du tableau plus tard.Cette approche peut faire perdre de l'espace parce que:
Si vous avez un autre moyen de savoir quel type vous avez stockées dans chaque élément, vous pouvez utiliser juste le strict de l'union sans la structure d'emballage. C'est un peu plus compact, mais chaque élément sera toujours au moins aussi grand que le plus grand type dans l'union.
Vous pouvez également créer un tableau de
void *
valeurs. Si vous faites cela, vous aurez à répartir les éléments d'une certaine manière et de leur assigner des adresses pour les éléments du tableau. Ensuite, vous aurez besoin de les jeter à la appropriée de type pointeur pour accéder aux articles. C ne propose pas de runtime type d'information, donc il n'y a aucun moyen de savoir quel type de données de chaque élément de points à partir du pointeur de lui-même-vous devez garder une trace de ce sur votre propre. Cette approche est beaucoup plus compact que les autres quand les types que vous stockez sont grandes et leurs tailles varient beaucoup, puisque chacun est attribué séparément à partir du tableau et ne peut être donnée que l'espace nécessaire pour ce type. Pour les types simples, vous n'avez pas vraiment le gain de quelque chose de plus à l'aide d'un syndicat.Si vous avez besoin de garder une trace du type dans le tableau, vous pouvez également utiliser une structure pour stocker le type avec le pointeur, similaire à l'exemple précédent avec l'union. Une fois encore, ce n'est vraiment utile lorsque les types conservées sont grandes et varient beaucoup en taille.
lorsque j'essaie d'imprimer les valeurs qu'ils sont...bizarre
Si c'est le
char *
, il faut juste la fonte sans le déréférencer. Je vais éditer pour ajouter des exemples de l'impression des valeurs.c'est le
int
et ladouble
qui ont des problèmes. la chaîne était beau!peut-être il y avait un manque de déréférencement pour ceux qui,alors, quel que soit l', la mise à jour doit montrer comment y accéder.
OriginalL'auteur Dmitri
Non, tous les éléments doivent être du même type. Vous pourriez sortir avec un tableau de structures.
J'ai moi-même ne ferait jamais une telle chose (il semble en désordre). Mais votre tableau de void* approche est la même: vous avez à stocker l'information sur le type quelque part.
malloc
?En raison de la façon tableau d'indexation des œuvres.
Le code de démonstration de l'union pourrait vous obtenir un +1.
Quand vous dites[6] le compilateur va à l'adresse
a + sizeof(*a) * 6
. C'est pourquoi tous les éléments doivent être de la même taille.lorsque vous faites référence à un élément dans un tableau, il calcule la position en fonction de la taille des éléments.
a[1]
esta+1*sizeof(void)
.sizeof(void)
n'est pas autorisé, donc il ne peut pas calculer oùa[1]
ou de tout autre indice.OriginalL'auteur cnicutar
Vous pouvez facilement avoir un tableau de pointeurs qui pointent vers différents types. Bien sûr que cela soit très utile, vous devez avoir un moyen de l'enregistrement ou de la détermination de ce type est actuellement référencé par chaque élément.
difftypes.c:10: warning: incompatible implicit declaration of built-in function ‘strncpy’
Mais il fonctionne...
pourquoi est -
strncpy
nécessaire?oh, vous avez oublié d'inclure
string.h
J'ai utilisé
strncpy
pour mettre la chaîne de données dans le bloc de mémoire qui est allouée par lemalloc
appel. Dans le code modifié dans votre question, vous allouez de la mémoire, mais alors d'écraser le pointeur de la valeur, de sorte que vous avez une fuite de mémoire. Vous devez le faire de la manière que j'ai, ou tout simplement nea[1] = "..."
. J'ai choisi d'utiliser la mémoire allouée dynamiquement pour chaque élément de la cohérence. En tout cas, jamais faire quelque chose commeptr = malloc(...);
et puis affecter une nouvelle valeur àptr
sans d'abordfree
ing, ainsi que la mémoire.OriginalL'auteur Dave Costa
Je ne suis pas sûr de ce que vous voulez atteindre, mais il y a deux possibilités:
1 - Vous ne veulent en fait pas un tableau mais une structure (struct):
Dans ce cas, vous pouvez accéder au numéro de
a.number
et la chaîne commea.string
.2 - Vous souhaitez un tableau de type variant. En C, vous pouvez utiliser des syndicats (de préférence balisé) pour les types de variantes:
Ensuite, vous pouvez encoder votre type avec le numéro 0 et 1 pour la chaîne. À l'aide d'un enum au lieu d'un entier pour le type serait une meilleure façon, bien sûr.
OriginalL'auteur cyco130
C'est parce que vous essayez de stocker une valeur dans une fente qui attend un pointeur. Essayez les solutions suivantes (vérification des erreurs omis par souci de concision)
*pIntTemp = 4
.oui, en effet. Bonne prise. Fixe
OriginalL'auteur JaredPar
Les grandes question est d'obtenir le compilateur C pour traiter chaque élément du tableau de manière différente.
Pourrais-je vous suggérer une approche hybride.
Mis de côté plusieurs pointeurs, chacun avec leurs définitions de structure.
Lorsque vous décidez quel type d'élément que vous souhaitez, utilisez le pointeur à la fonction malloc et le programme d'installation, puis de les utiliser plus tard.
Puis copier la valeur de ce pointeur dans le tableau de pointeurs.
Plus tard, lorsque vous souhaitez utiliser cet élément, copie de l'élément du tableau, en aproprate pointeur pour faire le bonheur du compilateur.
Veuillez garder à l'esprit, ce n'est qu'un exemple, il a quelques commings comme la difficulté de tri ou de l'insertion d'un nœud dans le milieu, mais...
Par exemple:
il résout le ulgyness de choses comme d'avoir à en fonte *((double *)(arr[2].de données)) = et contribue également à la lisibilité.
Cela pourrait briser le bas si vous avez beaucoup de différents nœud structures.
C'est un peu la force brute, mais (à mon humble avis) c'est un peu plus facile sur le cerveau. Le tableau est un tableau simple et chaque nœud est simple. Les noeuds n'ont pas besoin d'un "à côté" pointeur comme une liste chaînée.
Marque.
OriginalL'auteur Cool Javelin