Mise en œuvre d'un generical 'map', de la fonction des tableaux en C
Je vais avoir des difficultés pour mettre en œuvre un générique de 'map', de la fonction des tableaux.
J'ai commencé avec le projet:
void MapArray(void * src, void * dest, void * (f)(void *), size_t n, size_t elem)
{
unsigned int i = 0, j = 0;
void * temp = malloc(elem);
for(i = 0; i<n, i++)
{
temp = (f)((char *) src) + i));
for(j = 0; j < elem; j++)
{
*(((char *) dest) + i) = *(((char *) temp) + i);
}
}
free(temp);
}
Je comprends pourquoi il n'est pas correct - je suis un casting pour (char *) avant de la donner à " f " - mais maintenant, je suis démotivé et ne peut pas venir avec une solution. (Je le fais ce dans le processus d'apprentissage C)
Mon raisonnement était d'obtenir le résultat de " f " et, octet par octet, copiez dest[i].
Pouvez vous me donner un indice?
pour ce que vous avez besoin de ce pointeur de fonction et de ce que la carte que vous souhaitez mettre en œuvre, je ne pense pas que vous voulez un peu de par exemple la carte conteneur de sig?
C'est le cas typique de "carte" de l'application, vous pouvez trouver pratiquement dans chaque langage fonctionnel. Vous envoyer une liste, une fonction et elle renvoie la liste composé comme tel: (f(l[1]), ..., f(l[n])).
C'est le cas typique de "carte" de l'application, vous pouvez trouver pratiquement dans chaque langage fonctionnel. Vous envoyer une liste, une fonction et elle renvoie la liste composé comme tel: (f(l[1]), ..., f(l[n])).
OriginalL'auteur Lasirc | 2010-10-28
Vous devez vous connecter pour publier un commentaire.
Votre premier problème, c'est que vous êtes en train de faire de trop dans quelques expressions. Vous avez besoin de le décomposer.
Maintenant votre deuxième problème. Vous malloc un tampon, puis vous .. affecter à ce pointeur? À plusieurs reprises? Alors que le dernier f appel du résultat? C'est totalement inutile.
Votre troisième problème. Vous passez un pointeur - mais seulement à char. Vous ne passez pas dans un void*. Cela signifie que votre fonction ne peut pas être générique - f ne peut pas être appliquée à n'importe quoi. Nous avons besoin d'un tableau de void*s, de sorte que la fonction peut prendre n'importe quel type d'argument. Nous avons également besoin de prendre la taille du type d'argument, donc nous savons comment bien loin pour se déplacer le long de dest.
Nous avons encore un autre problème - la mémoire de temp. Nous n'avons pas gratuit, il est. Nous ne partageons un utilisateur des données de l'argument dans f, ce qui permettrait le retour de segment de mémoire allouée que nous n'avons pas besoin gratuit. La seule façon de f peut fonctionner que lorsqu'il est retourné statique de la mémoire tampon.
Maintenant f peut fonctionner sur à peu près ce qu'il veut et maintenez quel que soit l'état dont il a besoin. Mais nous n'avons toujours pas libérer le tampon. Maintenant, f retourne une simple structure qui nous dit que si nous avons besoin de libérer de la mémoire tampon. Cela nous permet également de libre ou pas libre de le tampon sur les différents appels de f.
Cependant, je ne comprends toujours pas le but de cette fonction. Tout cela pour remplacer une simple boucle for? Le code que vous essayez de les remplacer est plus simple que le code d'appel de votre fonction, et probablement plus efficace, et certainement de plus en plus puissants (ils peuvent continuer à utiliser/pause, par exemple).
Plus que cela, C est vraiment nulle pour ce genre de travail. C++ est beaucoup mieux. C'est assez trivial, il y appliquer une fonction à chaque membre d'un groupe, par exemple.
OriginalL'auteur Puppy
Il ya une raison pour rien comme c'est dans la bibliothèque standard C -- c'est à peu près impossible de le faire bien dans C. on ne peut pas copier le résultat, "octet par octet" pour
dest[i]
-- puisque vous l'avez faitdest
à unchar *
, il souligne que l'unchar
(byte).Sans doute,
elem
est destiné à être la taille de ce type def
retourne, etn
est le nombre d'éléments danssrc
etdest
. Dans ce cas, votre code n'est pas trop loin, mais (comme vous l'avez apparemment supposé) de la façon dont vous manipulez les pointeurs (surtout le casting dechar *
) ne va pas le couper.Même si vous remédier à cela, cependant, vous aurez un autre problème: assigner le type de retour de
f
sans connaître le type va être (très) difficile. En fait, la seule façon que je peux penser à est de les envelopper ce code dans une macro:Vous souhaitez utiliser ce quelque chose comme ceci:
Prenez note: je suis pas de recommander cette. Cette est un moyen de faire ce que vous avez demandé, mais comme je l'ai dit au début, c'est presque impossible de bien faire en C. Ce code fonctionne pour un certain degré, mais IMO il n'est pas admissible à titre de bien faire son travail.
OriginalL'auteur Jerry Coffin
j
est censé faireVous utilisez
i
l'intérieur de la boucle siMais au moment où la boucle est simplement de copier le même octet à la même place
elem
fois. Vous avez besoin*(((char *) dest) + i * elem + j) = *(((char *) temp) + i * elem + j);
à l'intérieur de la place.J'allais ajouter que vous devriez index séparément, puis jeté à
void*
avant d'appelerf
, plutôt que def( ((char *)src) + i )
. Mais @DeadMg de répondre, en fait tout ce que redondant. @ j_random_hacker merci pour communicationg mes pensées de façon plus explicite.OriginalL'auteur srean