← algo
Programmation C2 · Pointeurs · Structures · Récursivité

Pointeurs & mémoire

Le saut vers le C, où l'on manipule directement la mémoire. Une variable contient une valeur ; un pointeur contient une adresse. Tout le reste — passage par adresse, malloc, structures — en découle.

Notion 1
★★

Qu'est-ce qu'un pointeur ?

Une case qui contient une adresse

Idée

Une variable est une maison qui contient quelque chose ; un pointeur est un papier où est écrite l'adresse de cette maison.

Mémoire
0x1000a10
a = 10&a = 0x1000
01 / 04
Une variable a : une case mémoire (adresse 0x1000) contenant la valeur 10.
int a = 10;
int *p;
p = &a;
*p = 20;
& = opérateur d'adresse · * = accès à la valeur pointée.
&a et p valent la même adresse ; a et *p la même valeur.
Notion 2
★★

Pointeurs & fonctions

Passage par valeur contre passage par adresse

Idée

En C, une fonction reçoit par défaut une copie de ses arguments. Pour modifier l'original, il faut passer son adresse.

Passage par valeur
void modifier(int x){
  x = 20;
}
main: a
10
modifier: x

 

Passage par adresse
void modifier(int *x){
  *x = 20;
}
main: a
10
modifier: x

 

01 / 04
Avant l'appel : a = 10 dans les deux cas.
À retenir

C'est le vrai intérêt des pointeurs : swap, retours multiples, gros tableaux qu'on ne veut pas copier — tout repose sur le passage par adresse.

Notion 3
★★

L'allocation dynamique

Réserver de la mémoire à l'exécution

Idée

La taille d'un tableau statique est fixée à la compilation. Avec malloc, on réserve la mémoire pendant l'exécution, sur le tas.

Pile (stack) & Tas (heap)
pile
tab
?
tas — vide
01 / 04
Un pointeur sur la pile, rien dans le tas encore.
int *tab;
tab = malloc(n * sizeof(int));
for (i…) tab[i] = i*i;
free(tab); tab = NULL;

Règle d'or : un free pour chaque malloc. Oublier free = fuite de mémoire.

À retenir

malloc réserve, calloc réserve et met à zéro, realloc redimensionne, free libère. Toujours vérifier NULL et libérer.

Notion 4
★★

Les structures

Regrouper des données sous un même nom

Idée

Comment représenter un étudiant (nom, âge, note) ? Aucun type unique ne convient : on crée une structure qui regroupe ces champs.

struct Etudiant
struct Etudiant e1
char nom[50]"Ali"
int age20
float note14.5

Une structure regroupe des champs de types différents sous un seul nom.

Accès :
struct Etudiant e1;
e1.age  = 20;     // opérateur point
e1.note = 14.5;
printf("%d", e1.age);
. via la variable, -> via un pointeur. p->age est juste un raccourci plus lisible pour (*p).age.
typedef struct {
  char nom[50];
  int  age;
} Etudiant;   // alias : plus besoin de "struct"
Notion 5
★★

La récursivité en C

Le cas de base et la pile d'appels

Idée

Une fonction qui s'appelle elle-même, avec un cas de base obligatoire et un appel qui s'en rapproche.

Pile d'appels de fact(n)
fact(4)
01 / 10
fact(4) = 4 × fact(3) — on descend
int factorielle(int n){
  if (n == 0)
    return 1;              // cas de base
  return n * factorielle(n-1); // appel récursif
}

Sans cas de base, la pile déborde (Stack Overflow). La descente décompose, la remontée assemble.

Partie 6
★★

Exercices pratiques

Les cinq exercices du guide

Au programme

À taper, compiler et exécuter — la théorie seule ne suffit pas en C.

1 · Structure Livre
struct Livre {
  char  titre[100];
  char  auteur[50];
  float prix;
};
2 · Puissance récursive
int puissance(int x, int n){
  if (n == 0) return 1;        // x^0 = 1
  return x * puissance(x, n-1); // x^n = x · x^(n-1)
}
3 · Tableau d'étudiants
Etudiant tab[5];
for (int i=0; i<5; i++)
  scanf("%f", &tab[i].note);
for (int i=0; i<5; i++)
  printf("%f\n", tab[i].note);
4 · Tableau dynamique + somme
int n, somme = 0, *tab;
scanf("%d", &n);
tab = malloc(n * sizeof(int));
if (tab == NULL) return 1;
for (int i=0; i<n; i++){
  scanf("%d", &tab[i]);
  somme += tab[i];
}
printf("Somme = %d\n", somme);
free(tab); tab = NULL;
5 · swap par pointeurs
void swap(int *a, int *b){
  int temp = *a;
  *a = *b;
  *b = temp;
}
// appel : swap(&x, &y);