Comment fonctionnent les tableaux C : trier des nombres aléatoires avec du code

3

Vous devez stocker mille entiers. Voulez-vous vraiment déclarer « int a, b, c… » jusqu’à « z » et continuer ensuite ? Non, c’est fastidieux et sujet aux erreurs. Au lieu de cela, vous utilisez un tableau.

Un tableau est une collection de valeurs du même type. Il les regroupe dans un seul bloc de mémoire. En C, vous le déclarez comme ceci :

int a[5];

C’est tout. Cinq entiers. Prêt à partir.

Pourquoi les tableaux C commencent à zéro

Voici l’astuce qui fait trébucher les débutants. Les tableaux C sont indexés à zéro.

Si vous déclarez int a[5], vous disposez de cinq emplacements. Mais ils sont numérotés 0, 1, 2, 3 et 4. Il n’y a pas de « a[5] ». Si vous essayez d’accéder à « a[5] », vous lisez de la mémoire qui n’appartient pas à votre tableau. C ne vous arrêtera pas. Cela vous donnera simplement des déchets ou un crash. Il s’agit d’une fonctionnalité, pas d’un bug. C’est rapide. C’est aussi dangereux.

Vous accédez aux éléments à l’aide de crochets. a[0] est le premier élément. a[4] est le dernier.

Générer des nombres aléatoires en C

Construisons quelque chose d’utile. Nous allons créer un programme qui génère 10 nombres aléatoires et les trie.

Tout d’abord, vous avez besoin de chiffres. La bibliothèque standard de C a rand(), mais regardons une implémentation classique pour comprendre les mécanismes. Ce code utilise un générateur congruentiel linéaire, une méthode du livre K&R C.

Notez la ligne #define MAX 10. Cela crée une constante. Les constantes sont écrites en majuscules par convention. Cela les fait se démarquer. Vous déclarez le tableau int a[MAX] en dehors de la fonction main. Cela en fait une variable globale. Il existe partout dans le programme.

La variable rand_seed est également globale. Cela commence à 10. Comme la valeur de départ est fixe, les nombres “aléatoires” sont en fait les mêmes à chaque fois que vous exécutez le programme. Si vous voulez un véritable hasard, vous l’associeriez à l’heure du système. Pour l’instant, la cohérence est bonne pour le débogage.

Comprendre le tri à bulles

Vient maintenant la partie la plus difficile. Tri.

Nous utiliserons le tri à bulles. C’est l’algorithme de tri le plus simple. C’est aussi le plus lent. Mais il vous apprend comment les boucles et les tableaux interagissent.

Ajoutez ce code à votre fonction main, en remplaçant le commentaire sur “plus de choses” :

Que se passe-t-il ici ?

La boucle externe s’exécute « MAX-1 » fois. La boucle interne s’exécute moins de fois à chaque passage. Pourquoi? Parce que les plus grands nombres « bullent » jusqu’à la fin du tableau à chaque passage. Vous n’avez pas besoin de les vérifier à nouveau.

À l’intérieur de la boucle interne, nous comparons a[y] avec a[y+1]. Si celui de gauche est plus grand, on les échange. Nous utilisons une variable temporaire « t » pour conserver la valeur pendant que nous déplaçons les pièces.

“Le seul moyen simple de vraiment comprendre ce que fait ce code est de l’exécuter à la main.”

Prenez un morceau de papier. Dessinez cinq cases. Mettez-y des chiffres. Exécutez le code ligne par ligne. Déplacez les chiffres. Vous verrez les grands nombres couler vers le bas. Les petits flottent. C’est visuel. C’est mécanique.

Erreurs courantes dans les tableaux C

C ne vous tient pas la main. Vous tomberez du bord.

  • Aucune vérification de plage. Si vous accédez à a[10] dans un tableau de taille 10, C ne criera pas. Il lira la prochaine mémoire. Cela conduit à des bugs subtils difficiles à trouver.
  • Les appels de fonction nécessitent des parenthèses. Vous devez écrire x = rand();. Si vous écrivez « x = rand ; », vous attribuez l’adresse mémoire de la fonction à « x ». Pas le résultat. Il compile. Ça casse.

Essayez ceci

Ne vous contentez pas de lire. Code.

  • Changez la boucle qui remplit le tableau en une seule ligne. Pouvez-vous le faire ?
  • Déplacez la logique de tri à bulles dans sa propre fonction. Appelez-le « void bubble_sort() ». Déplacez les variables « x », « y » et « t » à l’intérieur de cette fonction. Ils deviennent locaux. Le tableau a est global, vous n’avez donc pas besoin de le transmettre.
  • Remplacez rand_seed par des valeurs différentes. Regardez le changement de sortie.

Les tableaux sont fondamentaux. Ce sont les éléments constitutifs des structures de données. Maîtrisez-les et le reste du C devient plus clair. Ignorez l’index zéro et vous passerez des heures à déboguer un crash survenu il y a trois étapes.