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 404
Amusant, 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);
}
|