Jean-Jacques BOURDIN
A variable is a set of three things: a name, a type and a
location.
It is in this location that one can find the value of
the variable. The address is known by the operator &.
Une variable est un triplet < nom, type, emplacement>. C'est à cet emplacement que, selon le type, on trouve la valeur. On peut connaître l'emplacement, l'adresse, de la variable "a" en utilisant l'opérateur & :
void voirou1 () { int i, j; printf("i est en %u, j est en %u\n", (int)&i, (int)&j); } |
void voirou () { int *pi, *pj; int i, j; printf("i est en %d, j est en %u\n",(int) &i,(int) &j); pi = & i; pj = & j; i = 7; j = 9; printf("En %u il y a %d\n", (int) pi, * pi); printf("En %u il y a %d\n", (int) &j, j); } |
void iv (int * pa, int * pb) { * pa = * pa + * pb; * pb = * pa - * pb; * pa = * pa - * pb; } int main () { int a, v; a = 5; v = 8; voirou1(); voirou(); printf("a = %d\t v = %d\n",a,v); iv (&a, &v); printf("a = %d\t v = %d\n",a,v); } /* dhcp13.ai.univ-paris8.fr: a.out a = 5 v = 8 a = 8 v = 5 */ |
nom adresse contenus main a 400 5 puis 13 puis 8 main v 404 8 puis 5 iv pa 408 400 iv pb 416 404Amusant, non ?
/* une autre version */ #include <stdio.h> void nrut (int * px, int * py) { * px = * px + * py; * py = * px - * py; * px = * px - * py; } void lookatit (int n) { int x, y; int * px, * py; /* adresses de int */ x = n; y = 3; px = & x; py = & y; printf("adresses de x %p et y %p\n",px, py); printf("Avant : valeurs de x %d et y %d\n",x, y); nrut(px,py); printf("Avant : valeurs de x %d et y %d\n",x, y); } int main () { lookatit(5); } /* adresses de x 0x7ff7b32b7768 et y 0x7ff7b32b7764 Avant : valeurs de x 5 et y 3 Apres : valeurs de x 3 et y 5 */ |
![]() |
/* Fait par JJ B en 2010 */ typedef int * pint; void fct (int nb, int rg, pint a, pint b) { if (nb > rg) { *a = *a + *b; *b = *a - *b; fct (nb, rg + 1, a, b); } } main () { int i, n, a, b; n = 10; for (i = 0; i <= n; i++) { a = 1; b = 1; fct (i, 0, &a, &b); printf("%d => %d\n", i, b); } } |
/* Fait par JJ B */ #include <stdio.h> #include <stdlib.h> typedef struct vecteur { int nbe; float tab [100]; } vecteur_t; typedef float * pfloat; float somv (vecteur_t v) { int i; float som; pfloat p; p = v.tab; som = 0; for (i = 0; i < v.nbe; i++) { som = som + *p; p ++; } return som; } |
![]() |
vecteur_t remplir (int nb) { float x, eps; vecteur_t vec; int i; vec.nbe = 0; if (nb >= 100) return vec; vec.nbe = nb; x = 1.5; eps = 0.173; for (i = 0; i < nb; i = i + 1) { vec.tab [i] = x; x = x + eps; if (x > 2.0) eps = 0.01 - eps; if (x < 0.5) eps = 0.015 - eps; } } void voirvec (vecteur_t v) { int i; if (v.nbe >= 100) return; for (i = 0; i < v.nbe; i = i + 1) { printf("vec[%3d] == %f\n",i, v.tab [i]); } } |
void voirvec2 (vecteur_t v) { int i; float * pf; if (v.nbe >= 100) return; pf = v.tab; for (i = 0; i < v.nbe; i = i + 1) { printf("vec[%3d] == %f\n",i, *pf); pf++; } } |
Il vous reste à reprendre quelques exercices faits avec des vecteurs, mais cette fois, en utilisant les pointeurs.
En-tête#include<stdio.h> #include<stdlib.h> #include<assert.h> #define MAXB 30 #define MAXD 30 typedef unsigned char uchar; typedef struct binaire { int nbent; int nbfrac; /* nombre de chiffres entiers et post virgule */ // uchar ent [MAXB]; // uchar frac [MAXB]; uchar *ent; uchar *frac; } binaire_t; typedef struct decimal { int nbent; int nbfrac; /* nombre de chiffres entiers et post virgule */ uchar *ent; uchar *frac; } decimal_t; |
int main () { binaire_t b; decimal_t d; float deci, bina; deci = 134.125; d = nb2dec(deci); printf("Pour %f le code est :\n", deci); aff_dec(d); bina = 110011.11001; b = nb2bin(bina); printf("Pour %f le code est :\n", bina); aff_bin(b); } |
decimal_t nb2dec (double xx) { /* prend un nombre et le met dans les cases*/ decimal_t dd; int i, nbc, chiffre, nbchif, nbfrac, p10; float frac; int partieent; partieent = (int) xx; frac = xx - partieent; /* combien de chiffres */ nbchif = 0; i = 1; while (i <= partieent) { i *= 10; nbchif++; } p10 = 10; dd.nbent = nbchif; dd.ent = malloc(nbchif * sizeof(uchar)); assert(dd.ent); for (i=0; i < nbchif; i++) { dd.ent[i] = (uchar) (partieent % 10); // printf("partiee %d val %d\n", partieent, dd.ent[i]); partieent /= 10; } dd.nbfrac = 10; nbfrac = 10; /* 10 chiffres max*/ dd.frac = malloc(nbfrac * sizeof(uchar)); assert(dd.ent); for (i = 0; i < nbfrac; i++) { frac *= 10; chiffre = (int) frac; frac -= chiffre; dd.frac[i] = (uchar) chiffre; } return dd; } |
La suite
void aff_bin (binaire_t bb) { int i; uchar *ptr; printf(" voici votre binaire\n"); ptr = bb.ent + bb.nbent - 1; for (i= 0; i < bb.nbent; i++) { printf("%2u ", (unsigned int) *ptr--); } printf(" . "); ptr = bb.frac; for (i = 0; i < bb.nbfrac; i++) { printf("%2u ", (unsigned int) *ptr++); } printf("\n"); } void aff_dec (decimal_t bb) { int i; uchar *ptr; // printf("nb chiffres %d . %d\n", bb.nbent, bb.nbfrac); ptr = bb.ent + bb.nbent - 1; for (i = 0; i < bb.nbent ; i++) { printf("%2u ", (unsigned int) *ptr--); } printf(" . "); ptr = bb.frac; for (i = 0; i < bb.nbfrac; i++) { printf("%2u ", (unsigned int) *ptr++); } printf("\n"); } |
decimal_t bin2dec(binaire_t bb) { int p2, i,j; double res, neg; printf("conversion du binaire au décimal\n"); aff_bin(bb); p2 = 1; res = 0.0; // bzero(tmp, (size_t) MAXD, (size_t) 1); for (i = 0; i < bb.nbent; i++) { res += p2 * bb.ent[i]; p2 *= 2; // printf("i %d res %f\n", i, res); } neg = 1.0/ 2.0; for (i = 0; i < bb.nbfrac; i++) { res += neg * bb.frac[i]; neg /= 2.0; } printf("et en float %f\n", res); return nb2dec(res); } |
Hereafter is a function building a list of n numbers. It's written in Scheme, you'll have to translate it.
Voici une fonction qui construit une liste de n nombres entiers. Elle est en Lisp, il faut donc la transcrire.
(define (creerl n) (if (< n 1) ‘(0) (cons n (creerl (- n 1))))) |
typedef struct cell * liste_t; typedef struct cell { float obj; struct cell * suiv; } cell_t; |
Here you see that a list is only the address of a structure.
Où on voit que la liste est en fait uniquement l'adresse d'une structure qui contient une valeur et une liste.
int estvide (liste_t l) { if (l == (liste_t) 0) { return 1; } return 0; } int estnonvide (liste_t l) { if (l == (liste_t) 0) { return 0; } return 1; } |
float soml (liste_t l) { if (estvide(l)) { return 0.0; } return (*l).obj + soml((*l).suiv); } |
int howmany (liste_t l) { if (estvide(l)) { return 0; } return 1 + howmany ((*l).suiv); } |
liste_t cons (float nb, liste_t l) { liste_t new; new = (liste_t) malloc (sizeof(cell_t)); assert(new); (*new).obj = nb; (*new).suiv = l; return new; } liste_t creercours (int nb) { liste_t l; int i; float x; x = 0.1; l = (liste_t) 0;; while (nb--) { l = cons (x, l); x += 0.15; if (x > 0.5) x -= 0.45; } return l; } liste_t creeriter (int nb) { liste_t debut; int i, j, k, t; j = 13; k = 21; debut = (liste_t) 0; for (i = 0; i < nb; i++) { debut = cons ((float) j, debut); t = (j + k) % 31; k = j; j = t; } return debut; } |
void affl (liste_t l) { if (estvide (l)) { printf("\n"); } else { printf("%5.2f ", (*l).obj); affl ((*l).suiv); } } |
void affll (liste_t l) { if (estvide (l)) { printf("\n"); } else { printf("%5.2f ", l->obj); affll (l->suiv); } } void affw (liste_t l) { while (estnonvide (l)) { printf("%5.2f ", l->obj); l = l->suiv; } printf("\n"); } |
#include<stdio.h> #include<stdlib.h> #include<assert.h> |
int main () { liste_t l; int nb, s; nb = 10; l = creer(nb); affw(l); s = soml(l); printf("Total : %d\n", s); s = howmany(l); printf("Il y a %d elements\n", s); } |
Exemple de solution
float plusgrandliste (liste_t l, float candidat) { if (l) { if (l->nb > candidat) return plusgrandliste (l->suiv, l->obj); return plusgrandliste (l->suiv, candidat); } return candidat; /* il n‘y a plus d‘autre possible*/ } float plusgrandl (liste_t l) { if (l) return plusgrandliste (l->suiv, l->obj); return - FLT_MAX; /* impose d‘avoir inclus float.h */ } |
float plusgrandliter (liste_t l) { float plgd; liste_t crt, ptrplgd; if (! l) return - FLT_MAX; /* il faut avoir inclus limits.h */ ptrplgd = l; plgd = ptrplgd->nb; crt = l->nxt; while (crt) { if (crt->nb > plgd) { plgd = crt->nb; ptrplgd = crt; } crt = crt->nxt; } return plgd; } |
Insérer dans l'odre croissant.
void insere2 (liste_t * ele, liste_t * lt) { liste_t ptr, nxt; if (! (*lt)) { (* ele)->suiv = (liste_t) 0; *lt = *ele; return ; } if ((*lt)->obj > (*ele)->obj) { (*ele)->suiv = *lt; *lt = *ele; return ; } ptr = *lt; nxt = (*lt)->suiv; while (nxt) { if (nxt->obj > (*ele)->obj) { /* ele doit etre place avant nxt*/ ptr->suiv = *ele; (*ele)->suiv = nxt; return ; } ptr = nxt; nxt = nxt->suiv; } ptr->suiv = *ele; (*ele)->suiv = (liste_t) 0; return; } |
(define (re l) (ifn (cdr l) l (cons (car (re (cdr l))) (re (cons (car l) (re (cdr (re (cdr l))))))))) |
"La beauté des arbres est de croître." (qui ?)
Nous présentons une structure pour des arbres binaires.
We start by defining some structures.
/* Arbres binaires tout simplement */ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <assert.h> struct noeud { int num; float val; struct noeud * sg; struct noeud * sd; } noeud_t; typedef struct noeud * arbre_t; |
void ajout (arbre_t * a, int v, float x) { arbre_t new; int rande; if (! (*a)) { new = (arbre_t) malloc (sizeof (noeud_t)); new->num = v; new->val = x; new->sg = (arbre_t) 0; new->sd = (arbre_t) 0; *a = new; return; } rande = rand (); if (rande & 0x01) { /* on le met à gauche*/ if (! ((*a)->sg)) { /* s'il ny a pas de fils gauche */ (*a)->sg = (arbre_t) malloc (sizeof (noeud_t)); (*a)->sg->num = v; (*a)->sg->val = x; (*a)->sg->sg = (arbre_t) 0; (*a)->sg->sd = (arbre_t) 0; return; } ajout(&((*a)->sg), v, x); return; } /* on le met donc a droite*/ if (! ((*a)->sd)) { /* s'il ny a pas de fils droit */ (*a)->sd = (arbre_t) malloc (sizeof (noeud_t)); (*a)->sd->num = v; (*a)->sd->val = x; (*a)->sd->sg = (arbre_t) 0; (*a)->sd->sd = (arbre_t) 0; return; } ajout(&((*a)->sd), v, x); return; } /* To create the tree, you add, one after the other, the values in the tree.*/ arbre_t creation (int n) { arbre_t a; float x, y; x = 1.5; y = 0.21; a = (arbre_t) 0; srand(time(NULL)); while (n--) { ajout (&a, n, x); x += y; y += 0.06; if (x > 3.0 || x < -2.0) { y = - y; } } return a; } |
void afficharbre (arbre_t a) { if (a) { afficharbre (a->sg); printf("%d %3.2f ", a->num, a->val); afficharbre (a->sd); } } |
int appartient (int nu, arbre_t a) { if (! a) return 0; if (a->num == nu) return 1; if (appartient (nu, a->sd)) return 1; return appartient (nu, a->sg); } |
int main () { int n; arbre_t a, b; float x; /* srand(time(NULL)); */ n = 20; a = creation (n); printf("\n Vois \n"); afficharbre (a); printf("\n\n"); x = 0.72; printf("%f dedans %s\n", x, appartient(x,a) ? "Oui" : "Non"); } |
0.720000 dedans Non |
int fappartient (arbre_t a, float x) { if (! a) return 0; if (fabs(a->val - x) < 0.0001) return 1; return fappartient(a->sg, x) || fappartient (a->sd, x); } |
int main () { int n; arbre_t a, b; float x; /* srand(time(NULL)); */ n = 20; a = creation (n); printf("\n Vois \n"); afficharbre (a); x = 0.72; printf("methode 1\t %f dedans %s\n", x, appartient(a,x) ? "Oui" : "Non"); printf("methode 2\t%f dedans %s\n", x, fappartient(a,x) ? "OUI" : "NON"); } |
methode 1 0.720000 dedans Non methode 2 0.720000 dedans OUI |
arbre ajout (arbre a, int v, float x) { arbre new; if (! a) { new = (arbre) malloc (sizeof (noeud_t)); new->num = v; new->val = x; new->fg = (arbre) 0; new->fd = (arbre) 0; return new; } if (x < a->val) { /* on le met à gauche*/ if (! (a->fg)) { /* s‘il ny a pas de fils gauche */ a->fg = (arbre) malloc (sizeof (noeud_t)); a->fg->num = v; a->fg->val = x; a->fg->fg = (arbre) 0; a->fg->fd = (arbre) 0; return a; } a->fg = ajout(a->fg, v, x); return a; } /* on le met donc a droite*/ if (! (a->fd)) { /* s‘il ny a pas de fils droit */ a->fd = (arbre) malloc (sizeof (noeud_t)); a->fd->num = v; a->fd->val = x; a->fd->fg = (arbre) 0; a->fd->fd = (arbre) 0; return a; } a->fd = ajout(a->fd, v, x); return a; } arbre creation (int n) { arbre a; float x, y; x = 1.5; y = 0.21; a = (arbre) 0; while (n--) { a = ajout (a, n, x); x += y; y += 0.06; if (x > 3.0 || x < -2.0) { y = - y; } } return a; } |
int appartient (arbre a, float x) { if (! a) return 0; if (a->val == x) return 1; if (a->val > x) return appartient (a->sg, x); return appartient (a->sd, x); } int appartientf (arbre a, float x) { if (! a) return 0; if (fabsf(a->val - x) < 0.0001) return 1; if (a->val > x) return appartientf (a->sg, x); return appartientf (a->sd, x); } |
typedef void (* ptrfct) (); |
void fcta () { printf(" a "); } void fctb () { printf(" b "); } |
void g (void (* fct) ()) { printf("g appelle :"); fct(); printf("\n"); } void gg (ptrfct f) { printf("gg appelle :"); f(); printf("\n"); } void fcttest () { g(fcta); g(fctb); gg(fcta); gg(fctb); } |
int menu () { int n; n = 0; while (!n) { printf("Choisissez entre la fonction a (tapez 1)\n"); printf("et la fonction b (tapez 2) :\n"); scanf("%d",&n); if (n==1 || n==2) break; n = 0; } return n-1; /* Notons le n - 1 */ } |
void main () { int n; ptrfct tf [] = {fcta, fctb}; fcttest (); n = menu(); tf[n](); for (n=0; n < 2; n++) gg(tf[n]); } |
typedef void (* ptrfct) (int); void fcta (int a) { printf("Fonction 1: "); printf("%d\n",a); } void fctb (int a) { printf("Fonction 2: "); printf("%d\n",a); } void g (void (* fct) (), int n) { printf("g appelle :"); fct(n); printf("\n"); } void gg (ptrfct f, int n) { printf("gg appelle :"); f(n); printf("\n"); } int menu () { int n; n = 0; while (!n) { printf("Choisissez entre la fonction a (tapez 1)\n"); printf("et la fonction b (tapez 2) :\n"); scanf("%d",&n); if (n==1 || n==2) break; n = 0; } return n-1; } int main () { int n, m; ptrfct tf [] = {fcta, fctb}; m = 10; n = menu(); g(tf[n], m); gg(tf[n], m); } |