• [^] # Re: compteur ?

    Posté par (site web personnel) . En réponse au journal Parlons C, parlons pipe !. Évalué à 2.

    Bon c'est plus pour (削除) le fun (削除ここまで) la rigolade qu'autre chose, mais je l'ai fait avec un tableau circulaire.

    Je ne suis pas sur que ça sois plus performant …

    #include <string.h>
    #define readMask 0b00110000
    #define readOverflowMask 0b10111111
    #define writeMask 0b00000011
    #define writeOverflowMask 0b11110011
    #define dataPresentMask 0b10000000
    #define GET_READ(X) (((X)&readMask)>>4)
    #define INC_READ(X) (((X)+(1<<4))&readOverflowMask)
    #define GET_WRITE(X) ((X)&writeMask)
    #define INC_WRITE(X) (((X)+1)&writeOverflowMask)
    /* Pas taper, c'est pas moi qui ai choisi le nom */
    typedef struct s_small_dick { /* /o\ */
     unsigned char index;
     char data[4];
    } SmallFifo;
    void sf_init(SmallFifo * f)
    {
     if (f == NULL) return;
     f->index=0;
     memset(f->data, 0, 4);
     return;
    }
    void sf_push(SmallFifo * f, unsigned char b)
    {
     if(f==NULL) return;
     /* C'est une FIFO qui, si elle est pleine, éliminent les valeurs les plus
     * anciennes (pas conseillé pour la retraite ^^).
     * On increment avant. C'est utile au moment du read, on incremente avant et on a pas besoin de stoker la valeur de retour dans une variable temporaire.
     */
     if ( f->index&dataPresentMask && (f->index&writeMask)==((f->index&readMask)>>4) )
     {
     /* On est en train de boucler en écriture et on efface les anciennes valeures.
     * On avance aussi le readIndex
     */
     f->index = INC_READ(f->index);
     }
     f->index = INC_WRITE(f->index)|dataPresentMask;
     f->data[GET_WRITE(f->index)] = b;
    }
    unsigned char sf_pop(SmallFifo * f)
    {
     if(f==NULL) return 0x00;
     f->index = INC_READ(f->index);
     if ( GET_WRITE(f->index) == GET_READ(f->index) )
     /* si on a "ratraper" le writeIndex, il n'y a plus de donnée */
     f->index &= ~dataPresentMask;
     return f->data[GET_READ(f->index)];
    }
    unsigned char sf_has_data(SmallFifo * f)
    {
     if(f==NULL) return 0x00;
     if( f->index&dataPresentMask ) return 0xEB;
     return 0x00;
    }
    int main(int argc, char ** argv)
    {
     SmallFifo ma_fifo;
     char des_valeurs[]="abcdefghijklmnopqrstuvwxyz";
     int i=0; /* un compteur */
     sf_init(&ma_fifo);
     for(i=0;i<4;i++) {
     sf_push(&ma_fifo, des_valeurs[i]);
     }
     while(sf_has_data(&ma_fifo)) {
     printf("%c ", sf_pop(&ma_fifo));
     }
     printf("\n");
     for(i=0;i<26;i++) {
     sf_push(&ma_fifo, des_valeurs[i]);
     }
     while(sf_has_data(&ma_fifo)) {
     printf("%c ", sf_pop(&ma_fifo));
     }
     printf("\n");
     return 0;
    }
    
    

    Matthieu Gautier|irc:starmad