Programmes en C



next up previous contents index
Next: Bibliographie Up: Modularité Previous: Tri topologique

Programmes en C

 

Ici, il est intéressant d'examiner la différence entre Pascal et C. Les noms de fonctions sont différents de ceux donnés dans le programme Pascal pour les files de caractères, car nous avons copié textuellement ce code directement du noyau du système Unix. C'est l'occasion de constater comment la programmation en C permet certaines acrobaties, peu recommandables car on aurait pu suivre la technique d'adressage des caractères dans les blocs de Pascal. La structure des files est légèrement différente car on adresse directement les caractères dans un bloc au lieu du système base et déplacement de Pascal. Le débordement de bloc est testé en regardant si on est sur un multiple de la taille d'un bloc, car on suppose le tableau des blocs aligné sur un multiple de cette taille. Le fichier interface files-de-caracteres.h est

#define	NCLIST	80    /* - */
#define	CBSIZE	12    /* - */
#define	CROUND	0xf   /* -*/

/*
 * -
 * -
 * -
 * -
 * -
 * -
 */
struct clist
{
    int    c_cc;              /* - */
    char   *c_cf;             /* - */
    char   *c_cl;             /* - */
};

struct cblock {
    struct cblock *c_next;
    char          c_info[CBSIZE];
};

typedef struct clist *FCtype;

int  FCput(char c, FCtype p);
int  FCget(FCtype p);
void FCinit(void);

Dans la partie implémentation qui suit, on remarque l'emploi de la directive static qui permet de cacher à l'édition de liens des variables, procédures ou fonctions privées qui ne seront pas considérées comme externes. Contrairement à Pascal, il est possible en C de cacher la représentation des files, en ne déclarant le type FCtype que comme un pointeur vers une structure clist non définie. Les fonctions retournent un résultat entier qui permet de retourner des valeurs erronées comme . Le fichier files-de-caracteres.c est

#include <stdlib.h>
#include <files-de-caracteres.h>

static struct cblock    cfree[NCLIST];
static struct cblock    *cfreelist;

int FCput(char c, FCtype p)
{
    struct cblock *bp;
    char *cp;
    register s;

    if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
        if ((bp = cfreelist) == NULL) 
            return(-1);
        cfreelist = bp->c_next;
        bp->c_next = NULL;
        p->c_cf = cp = bp->c_info;
    } else if (((int)cp & CROUND) == 0) {
        bp = (struct cblock *)cp - 1;
        if ((bp->c_next = cfreelist) == NULL)
            return(-1);
        bp = bp->c_next;
        cfreelist = bp->c_next;
        bp->c_next = NULL;
        cp = bp->c_info;
    }
    *cp++ = c;
    p->c_cc++;
    p->c_cl = cp;
    return(0);
}

int FCget(FCtype p)
{
    struct cblock *bp;
    int c, s;

    if (p->c_cc <= 0) {
        c = -1;
        p->c_cc = 0;
        p->c_cf = p->c_cl = NULL;
    } else {
        c = *p->c_cf++ & 0xff;
        if (--p->c_cc<=0) {
            bp = (struct cblock *)(p->c_cf-1);
            bp = (struct cblock *) ((int)bp & ~CROUND);
            p->c_cf = p->c_cl = NULL;
            bp->c_next = cfreelist;
            cfreelist = bp;
        } else if (((int)p->c_cf & CROUND) == 0){
            bp = (struct cblock *)(p->c_cf-1);
            p->c_cf = bp->c_next->c_info;
            bp->c_next = cfreelist;
            cfreelist = bp;
        }
    }
    return(c);
}

void FCinit()
{
    int ccp;
    struct cblock *cp;

    ccp = (int)cfree;
    ccp = (ccp+CROUND) & ~CROUND;
    for(cp=(struct cblock *)ccp; cp <= &cfree[NCLIST-1]; cp++) {
        cp->c_next = cfreelist;
        cfreelist = cp;
    }
}