Est-ce que C d'avoir un “foreach” boucle de construire?
Presque toutes les langues ont un foreach
de la boucle ou quelque chose de similaire. Est-ce que C en avez un? Pouvez-vous poster un exemple de code?
- "
foreach
" de quoi? - Comment serait-il difficile ont été d'essayer d'écrire un
foreach
boucle dans un programme C?
Vous devez vous connecter pour publier un commentaire.
C ne dispose pas d'un foreach, mais les macros sont fréquemment utilisés pour imiter que:
Et peut être utilisé comme
Itération sur un tableau est également possible:
Et peut être utilisé comme
Edit: Dans le cas où vous sont également intéressés en C++ solutions, C++ dispose d'un natif pour chaque syntaxe appelé "basé sur la plage de"
#define foreach(item, array) int count=0, size=sizeof(array)/sizeof(*(array)); for(item = (array); count != size; count++, item = (array)+count)
Un problème que je peux voir, c'est que les variables de comte et de la taille de vivre en dehors de la boucle for, et pourrait provoquer un conflit. Est-ce la raison pour vous d'utiliser deux boucles for? [code collé ici(pastebin.com/immndpwS )]if(...) foreach(int *v, values) ...
. Si elles sont en dehors de la boucle, elle s'étend àif(...) int count = 0 ...; for(...) ...;
et de casser.keep
variable?keep
et les autres.int
-->size_t
dansfor(size_t keep = 1, \ ...
keep = !keep
consolidés. Je pense que la suite fonctionne tout aussi bien et est (à mon avis) un peu plus clair:#define array_elements(arr) ( sizeof(arr) / sizeof(arr[0]) )
#define array_for(item, array) for(unsigned int cont=1, i=0; i<array_elements(array); cont=1, i++) for(item=&(array)[i]; cont; cont=0)
#define array_for(item, array) for(typeof(array[0])* item=array; item < &array[sizeof(array) / sizeof(array[0])]; item++)
T*
est quoi exactement?typeof
. Il suffit de déclarer votre variable en dehors de la boucle for à la place:int *v; array_for(v, values) { ... }
for_each_item
macro ne fonctionne que comme ça intrusives de listes, où le pointeur est partie des éléments eux-mêmes.Voici une exemple de programme d'une pour chaque macro en C99:
list[]
définition? Ne pourriez-vous pas tout simplement écrirenext
au lieu de.next
?free()
) et de l'autre, il a une référence à la valeur à l'intérieur de sa définition. C'est vraiment un exemple de quelque chose qui est tout simplement trop intelligent; le code est assez complexe sans dessein, l'ajout de l'habileté pour elle. Kernighan de l'aphorisme (stackoverflow.com/questions/1103299/...) s'applique!Il n'y a pas de foreach dans C.
Vous pouvez utiliser une boucle for pour parcourir les données, mais la longueur doit être le savoir ou les données doit être terminée par une valeur (par exemple. null).
C'est une assez vieille question, mais je pensais que je devrais poster cela. C'est une boucle foreach pour GNU C99.
Ce code a été testé pour fonctionner avec gcc, la cour et le bruit sur GNU/Linux.
Comme vous le savez probablement déjà, il n'y a pas de "foreach"style boucle en C.
Bien qu'il existe déjà des tonnes de macros fournies ici pour contourner ce problème, peut-être que vous trouverez cette macro utile:
...qui peut être utilisé avec
for
(comme dansfor each (...)
).Avantages de cette approche:
item
est déclarée et incrémentée dans l'instruction for (tout commeen Python!).
p
,item
), ne sont pas visibles de l'extérieur de lala portée de la boucle (car elles sont déclarées dans la boucle for en-tête).
Inconvénients:
typeof()
, qui est un gcc extension, pas partie de la norme CJuste pour économiser un peu de temps, voici comment vous pouvez tester:
Il semble fonctionner sur gcc et clang; ce n'est pas sûr d'autres compilateurs.
Tandis que le C n'a pas une pour chaque construction, il a toujours eu un idiomatiques représentation pour un passé la fin d'un tableau
(&arr)[1]
. Cela permet d'écrire une simple idiomatiques pour chaque boucle comme suit:(&arr)[1]
ne signifie pas un élément de tableau passé à la fin du tableau, cela signifie que l'un tableau au-delà de la fin du tableau.(&arr)[1]
n'est pas le dernier élément de tableau [0], c'est le tableau [1], qui se décompose en un pointeur vers le premier élément du tableau [1]). Je crois qu'il serait bien meilleur, plus sûr et idiomatique neconst int* begin = arr; const int* end = arr + sizeof(arr)/sizeof(*arr);
et puisfor(const int* a = begin; a != end; a++)
.C a 'pour' et 'quand' des mots-clés. Si une instruction foreach dans un langage comme C# ressemble à ...
... alors l'équivalent de cette instruction foreach dans C pourrait être:
Voici ce que j'utilise quand je suis coincé avec C. Vous ne pouvez pas utiliser le même nom de l'élément deux fois dans la même portée, mais ce n'est pas vraiment un problème puisque ce ne sont pas tous d'entre nous ont gentiment de nouveaux compilateurs 🙁
Utilisation:
EDIT: Voici une alternative pour
FOREACH
à l'aide de la c99 syntaxe pour éviter de polluer l'espace de nom:VAR(i) < (size) && (item = array[VAR(i)])
allait s'arrêter une fois que l'élément du tableau ayant une valeur de 0. Donc, en utilisant cette avecdouble Array[]
ne peut itérer sur tous les éléments. Semble que le test de boucle doit être l'un ou de l'autre:i<n
ouA[i]
. Peut-être ajouter des exemples de cas d'utilisation pour plus de clarté.if ( bla ) FOREACH(....) { } else....
FOREACH
qui utilise du c99 syntaxe pour éviter de polluer l'espace de nom.Eric réponse ne fonctionne pas lorsque vous utilisez "briser" ou "continuer".
Cela peut être corrigé par une réécriture de la première ligne:
Ligne d'origine (restructuré):
Fixe:
Si vous le comparez à Johannes en boucle, vous verrez qu'il est en train de faire la même chose, juste un peu plus compliqué et de plus laid.
Ici est un simple, une seule boucle for:
Vous donne accès à l'index si vous le souhaitez (
i
) et de l'élément en cours, nous sommes à parcourir (it
). Note vous pouvez avoir nommer des problèmes lors de l'imbrication de boucles, vous pouvez faire le point et index des noms de paramètres de la macro.Edit: Voici une version modifiée de la accepté de répondre à
foreach
. Vous permet de spécifier lestart
index, lesize
afin qu'il fonctionne sur pourri tableaux (pointeurs), pas besoin deint*
et changécount != size
ài < size
juste au cas où l'utilisateur accidentellement modifie "je", pour être plus grand quesize
et coincé dans une boucle infinie.De sortie:
Si vous avez l'intention de travailler avec des pointeurs de fonction
Utilisation:
Mais je pense que cela fonctionnera uniquement sur gcc (pas sûr).
C n'a pas de mise en œuvre de
for-each
. Lors de l'analyse d'un tableau comme point le récepteur ne sais pas combien de temps le tableau, donc il n'y a aucun moyen de savoir quand vous avez atteint la fin du tableau.Rappelez-vous, en C
int*
est un point à une adresse mémoire contenant un int. Il n'y a pas d'en-tête de l'objet contenant des informations sur le nombre d'entiers qui sont placés dans l'ordre. Ainsi, le programmeur a besoin de garder une trace de ce.Toutefois, pour les listes, il est facile de mettre en place quelque chose qui ressemble à un
for-each
boucle.Pour obtenir quelque chose de similaire pour les tableaux que vous pouvez faire une des deux choses.
Ce qui suit est un exemple d'une telle structure: