2009-05-07 9 views
6

La instrucción "yield" en python permite la iteración simple de un procedimiento, y también significa que las secuencias no necesitan ser pre-calculadas Y almacenadas en una matriz de tamaño "arbitrario".iteradores de estilo de Python en C

¿Hay alguna manera similar de iterar (con rendimiento) de un procedimiento en C?

+0

Lo que el sentido pedir ¿esta pregunta? ¿Solo quería responderlo usted mismo para aumentar su calificación? Estaba en Reddit ayer, así que no creo que haya una coincidencia. Entonces obtienes -1 para la pregunta y -1 para la respuesta de mí. – qrdl

+0

Solo debe hacer preguntas en SO. Aprecio tu intención de compartir el conocimiento, pero lugares como Reddit y Digg son más apropiados para esto. Deshago mis votos bajos ya que tu error no fue intencional. – qrdl

+4

@qrdl Esto se manejó hace mucho tiempo (http://stackoverflow.com/questions/2572) El comportamiento de NevilleDNZ no solo es aceptable, sino que se recomienda. Incluso obtienes una insignia por obtener 3 votos en una respuesta a tu propia pregunta. Este es un lugar para preguntas y respuestas, el hecho de que una persona entregue ambos no es algo a despreciar. –

Respuesta

6

A continuación, se incluye una copia de la autocomplicación de la comunidad wiki, que se puede elegir como "la" respuesta. Por favor, dirija hacia arriba/downvotes a la actual auto-respuesta

Aquí es el método que he encontrado:

/* Example calculates the sum of the prime factors of the first 32 Fibonacci numbers */ 
#include <stdio.h> 

typedef enum{false=0, true=1}bool; 

/* the following line is the only time I have ever required "auto" */ 
#define FOR(i,iterator) auto bool lambda(i); yield_init = (void *)&lambda; iterator; bool lambda(i) 
#define DO { 
#define  YIELD(x) if(!yield(x))return 
#define  BREAK return false 
#define  CONTINUE return true 
#define OD CONTINUE; } 
/* Warning: _Most_ FOR(,){ } loops _must_ have a CONTINUE as the last statement. 
* * Otherwise the lambda will return random value from stack, and may terminate early */ 

typedef void iterator; /* hint at procedure purpose */ 
static volatile void *yield_init; 
#define YIELDS(type) bool (*yield)(type) = yield_init 

iterator fibonacci(int n){ 
    YIELDS(int); 
    int i; 
    int pair[2] = {0,1}; 
    YIELD(0); YIELD(1); 
    for(i=2; i<n; i++){ 
     pair[i%2] = pair[0] + pair[1]; 
     YIELD(pair[i%2]); 
    } 
} 

iterator factors(int n){ 
    YIELDS(int); 
    int i; 
    for(i=2; i*i<=n; i++){ 
    while(n%i == 0){ 
     YIELD(i); 
     n/=i; 
    } 
    } 
    YIELD(n); 
} 

main(){ 
    FOR(int i, fibonacci(32)){ 
     printf("%d:", i); 
     int sum = 0; 
     FOR(int factor, factors(i)){ 
      sum += factor; 
      printf(" %d",factor); 
      CONTINUE; 
     } 
     printf(" - sum of factors: %d\n", sum); 
     CONTINUE; 
    } 
} 

tomó la idea de http://rosettacode.org/wiki/Prime_decomposition#ALGOL_68 - pero lee mejor en C

+0

Esto parece bastante impresionante, pero ¿hay alguna explicación sobre cómo funciona? Me estoy confundiendo mucho con toda la afirmación de auto bool lambda. – parent5446

+0

OK, no importa. Creo que entiendo. Básicamente declara que el bucle real se itera con una función y luego llama a esa función dentro de la función del iterador. – parent5446

3

Extraigo esta URL como una broma de vez en cuando: Coroutines in C.

Creo que la respuesta correcta a su pregunta es la siguiente: no existe un equivalente directo, y los intentos de falsificación probablemente no serán tan claros ni fáciles de usar.

0

¡Bonito y breve!

Cuestiones relacionadas