URL: https://linuxfr.org/users/tchetch/journaux/parlons-c-parlons-pipe Title: Parlons C, parlons pipe ! Authors: Etienne Bagnoud Date: 2012年08月21日T14:08:40+02:00 License: CC By-SA Tags: c, fifo, pipe, tube, sexiste, sexisme et programmation Score: 27 Mon livre de chevet, [Unleashed C](http://users.powernet.co.uk/eton/unleashed/) (non je mens, mon livre de chevet reste [Playboy](http://en.wikipedia.org/wiki/Playboy), mais ça fait moins sérieux), propose d'implémenter une [FIFO](http://fr.wikipedia.org/wiki/Fifo) (ou "pipe", pour tube en anglais) de la façon suivante (approximativement, j'ai simplifié la représentation (surtout il y avait `QUEUE` écrit et je veux pas de problèmes)) : ``` +----------+ | taille | +----------+ | debut |-------+ +----------+ | | fin | | +----------+ V | +---+---------+ | | s | donnes | | +---+---------+ | | | V | +---+---------+ +------------->| s | donnes | +---+---------+ | V NULL ``` Avec, bien entendu, plein de code C manipulant des pointeurs (que [j'aime](https://linuxfr.org/users/tchetch/journaux/et-dieu-inventa-le-soutien-gorge) :D). Moi je veux une petite FIFO. Une pouvant contenir 4 caractères (voir 8) ; la version du livre est un peu gore dans ce cas. Une FIFO, on pousse à droite, ça sort à gauche. On pousse à droite ... ça me rappelle un opérateur : `<<`. Je prends une variable, pouvant contenir des valeurs de 4 ou 8 octets, une variable pour compter et j'ai une FIFO. Rudimentaire mais suffisante ! Donc ma FIFO commence sa vie avec une structure : ```c /* Ne pas déraper, ne pas déraper, ... */ typedef struct s_small_dick { /* /o\ */ unsigned char count; uint32_t data; /* uint64_t pour 8 caracteres */ } SmallFifo; ``` Ensuite il faut quelques fonctions pour la faire vivre. D'abord l'initialisation (pour la forme) : ```c void sf_init(SmallFifo * f) { if(f==NULL) return; f->count=0; f->data=0; return; } ``` Ensuite je veux pouvoir ajouter des valeurs. Cette opération est d'une simplicité déconcertante. ```c 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 ^^). */ f->data=(f->data<<8)|b; if(f->countdata)) f->count++; } ``` Pour récupérer les valeurs, nous allons, très simplement, appliquer la méthode suivante : ```c unsigned char sf_pop(SmallFifo * f) { if(f==NULL) return 0x00; /* Pas tomber trop bas */ if(f->count>0) f->count--; return (unsigned char)(f->data>>(8 * f->count)) & 0xFF; } ``` Et, pour la forme, une fonction qui retourne une valeur différente de 0 s'il y a encore des données dans notre FIFO : ```c unsigned char sf_has_data(SmallFifo * f) { if(f==NULL) return 0x00; if(f->count>0) return 0xEB; /* mes initiales \o/ */ return 0x00; } ``` Bien entendu, ce code n'a été que brièvement testé et contient, peut-être, des erreurs. ```c 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; } ``` Pour tester ce code, n'oubliez pas d'inclure `stdint.h` ou alors changer le type en `unsigned long int`, ça devrait faire 4 octets même sur un [AVR](http://en.wikipedia.org/wiki/Atmel_AVR) ou un [PIC](http://en.wikipedia.org/wiki/PIC_microcontroller). PS: Si, par mégarde, j'ai choqué une femme dans ce journal, j'en suis désolé. Pour me faire pardonner, j'accepterais jusqu'aux châtiments corporels, y compris être tuer et violer tant que ça reste dans cet ordre là (sauf ma copine, `halle_berry.jpeg`, qui peut le faire dans l'ordre inverse).

AltStyle によって変換されたページ (->オリジナル) /