Casi todos los idiomas tienen un foreach
bucle o algo similar. ¿C tiene uno? ¿Puedes publicar algún código de ejemplo?
109
Casi todos los idiomas tienen un foreach
bucle o algo similar. ¿C tiene uno? ¿Puedes publicar algún código de ejemplo?
foreach
" ¿de qué?foreach
bucle en un programa en C?Respuestas:
C no tiene un foreach, pero las macros se usan con frecuencia para emular eso:
Y se puede usar como
La iteración sobre una matriz también es posible:
Y se puede usar como
Editar: en caso de que también esté interesado en las soluciones de C ++, C ++ tiene una sintaxis nativa para cada llamada llamada "rango basado en"
fuente
#define foreach(item, array) int count=0, size=sizeof(array)/sizeof(*(array)); for(item = (array); count != size; count++, item = (array)+count)
Un problema que puedo ver es que las variables cuentan y tamaño viven fuera del ciclo for y pueden causar un conflicto. ¿Es esta la razón por la que usa dos bucles for? [código pegado aquí ( pastebin.com/immndpwS )]if(...) foreach(int *v, values) ...
. Si están fuera del bucle, se expandeif(...) int count = 0 ...; for(...) ...;
y se rompe.A continuación se muestra un ejemplo de programa completo de una macro para cada en C99:
fuente
list[]
definición? ¿No podrías simplemente escribir ennext
lugar de.next
?free()
) y por otro tiene una referencia al valor dentro de su definición. Es realmente un ejemplo de algo que es demasiado inteligente; el código es lo suficientemente complejo sin agregarle inteligencia a propósito. ¡Se aplica el aforismo de Kernighan ( stackoverflow.com/questions/1103299/… )!No hay foreach en C.
Puede usar un bucle for para recorrer los datos, pero se debe conocer la longitud o los datos deben terminarse con un valor conocido (por ejemplo, nulo).
fuente
Como probablemente ya sepa, no hay un bucle de estilo "foreach" en C.
Aunque ya hay toneladas de macros geniales proporcionadas aquí para solucionar esto, tal vez encuentre útil esta macro:
... que se puede usar con
for
(como enfor each (...)
).Ventajas de este enfoque:
item
se declara y se incrementa dentro de la declaración for (¡como en Python!).p
,item
) no son visibles fuera del alcance del bucle (ya que están declaradas en el encabezado del bucle for).Desventajas:
typeof()
, que es una extensión GNU, no parte del estándar CSolo para ahorrarle algo de tiempo, así es como puede probarlo:
Parece funcionar en gcc y clang de forma predeterminada; no he probado otros compiladores.
fuente
Esta es una pregunta bastante antigua, pero pensé que debería publicar esto. Es un bucle foreach para GNU C99.
Este código ha sido probado para funcionar con gcc, icc y clang en GNU / Linux.
fuente
Si bien C no tiene una para cada construcción, siempre ha tenido una representación idiomática para una más allá del final de una matriz
(&arr)[1]
. Esto le permite escribir un modismo simple para cada bucle de la siguiente manera:fuente
(&arr)[1]
no significa un elemento de la matriz más allá del final de la matriz, significa una matriz más allá del final de la matriz.(&arr)[1]
no es el último elemento de la matriz [0], es la matriz [1], que decae en un puntero al primer elemento (de la matriz [1]). Creo que sería mucho mejor, más seguro e idiomático hacerloconst int* begin = arr; const int* end = arr + sizeof(arr)/sizeof(*arr);
y luegofor(const int* a = begin; a != end; a++)
.C tiene palabras clave "para" y "mientras". Si una declaración foreach en un lenguaje como C # se ve así ...
... entonces el equivalente de esta declaración foreach en C podría ser como:
fuente
Esto es lo que uso cuando estoy atascado con C. No puede usar el mismo nombre de elemento dos veces en el mismo alcance, pero eso no es realmente un problema ya que no todos podemos usar compiladores nuevos y agradables :(
Uso:
EDITAR: Aquí hay una alternativa para
FOREACH
usar la sintaxis c99 para evitar la contaminación del espacio de nombres:fuente
VAR(i) < (size) && (item = array[VAR(i)])
se detendría una vez que el elemento de la matriz tuviera un valor de 0. Por lo tanto, usar esto condouble Array[]
puede no iterar a través de todos los elementos. Parece que la prueba de bucle debería ser una u otra:i<n
oA[i]
. Tal vez agregue casos de uso de muestra para mayor claridad.if ( bla ) FOREACH(....) { } else....
FOREACH
que usa la sintaxis c99 para evitar la contaminación del espacio de nombres.La respuesta de Eric no funciona cuando usa "romper" o "continuar".
Esto se puede solucionar reescribiendo la primera línea:
Línea original (reformateada):
Fijo:
Si lo comparas con el bucle de Johannes, verás que en realidad él está haciendo lo mismo, solo que un poco más complicado y feo.
fuente
Aquí hay uno simple, single for loop:
Le da acceso al índice si lo desea (
i
) y al elemento actual sobre el que estamos iterando (it
). Tenga en cuenta que puede tener problemas de nomenclatura al anidar bucles, puede hacer que los nombres de los elementos y los índices sean parámetros de la macro.Editar: aquí hay una versión modificada de la respuesta aceptada
foreach
. Le permite especificar elstart
índice,size
para que funcione en matrices deterioradas (punteros), sin necesidadint*
y cambiadocount != size
ai < size
solo en caso de que el usuario modifique accidentalmente 'i' para que sea más grande quesize
y se quede atascado en un bucle infinito.Salida:
fuente
Si planea trabajar con punteros de función
Uso:
Pero creo que esto solo funcionará en gcc (no estoy seguro).
fuente
C no tiene una implementación de
for-each
. Al analizar una matriz como un punto, el receptor no sabe cuánto dura la matriz, por lo que no hay forma de saber cuándo llega al final de la matriz. Recuerda, en Cint*
hay un punto a una dirección de memoria que contiene un int. No hay ningún objeto de encabezado que contenga información sobre cuántos enteros se colocan en secuencia. Por lo tanto, el programador debe realizar un seguimiento de esto.Sin embargo, para las listas, es fácil implementar algo que se parezca a un
for-each
bucle.Para lograr algo similar para las matrices, puede hacer una de dos cosas.
El siguiente es un ejemplo de tal estructura:
fuente