TD7 - Les structures et les tableaux

Les structures et les tableaux

Durée : 4h30

Objectifs :

  • Manipuler des structures dans un algorithme
  • Définir ses propres structures de données
  • Stocker des données dans un tableau
  • Comprendre la différence entre des fonctions, des procédures, des structures et un programme principal

Attention :

À chaque étape de programmation, vous devez vérifier si le programme :

  • Compile sans warning
  • Obtient les résultats attendus
  • Avant de coder, il faut écrire un algo avec un papier et un stylo !

Exercice 0 : Avant de commencer

  1. Depuis le terminal, ajouter l’arborescence suivante :

  1. Déplacer vous dans le répertoire précédement créé
cd TD-Structures-Tableaux

Rappels

Pour compiler un programme, on utilise l’instruction suivante :

gcc -Wall exo.c -o nomExecutable

Pour executer un programme, on utilise l’instruction suivante :

./nomExecutable

Exercice 1 : Etudiants

  1. Créer un répertoire exo1 dans lequel on ajoutera le fichier exo1.c contenant le code suivant :

#include <stdio.h>
#include <stdlib.h>

/* exo 1 :  les étudiants */
int main(){
    return 0;
}
  1. Écrire une structure qui permet de créer un étudiant, possédant un numéro étudiant, un nom, un prénom, et un age.

Tips : - Modéliser la structure sur un brouillon avant de la coder directement - Regarder le cours pour savoir comment on représente une structure en C

  1. Ecrire une fonction permettant de créer un Etudiant comme suit :
/* Auteur : ... */
/* Date :  ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
Etudiant creerEtudiant (int numeroEtudiant, char nom[N], char prenom[N], int age);

tips En C, pour mettre une chaine de caractères dans une autre on ne peut pas utiliser l’opérateur =

char maChaine1[N];
char maChaine2[N];

printf("Entrez une chaine 1 \n");
scanf("%s",maChaine1);


/*---------------------*/
maChaine2=maChaine1;
/* ------------------ */
/* FAUX ------------- */
/* ------------------ */

Pour que ça marche, il faut utiliser la bibliothéque string.h


    char maChaine1[N];
    char maChaine2[N];

    printf("Entrez une chaine 1 \n");
    scanf("%s",maChaine1);

    /* ici, on met le contenu de la chaine 1 dans la chaine 2 */
    strcpy(maChaine2, maChaine1);
  1. Écrire le programme principal qui demande à l’utilisateur de saisir les informations d’un étudiant à l’utilisateur.
  1. Écrire une nouvelle procédure qui permet d’afficher une structure étudiant.
/* Auteur : ... */
/* Date :  ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
void afficherEtudiant (Etudiant e);
  1. Ajouter dans votre programme principal, l’appel à cette nouvelle procédure.

Exercice 2 : Un tableau

  1. Créer un répertoire exo2 dans lequel on ajoutera le fichier exo2.c contenant le code suivant :
#include <stdio.h>
#include <stdlib.h>

/* exo 2 : un tableau */
int main(){
    return 0;
}

  1. Écrire une procédure permettant de créer un tableau d’entiers de manière aléatoire. La procédure prendra en paramètre le tableau, et le nombre de case aléatoire que l’on souhaite créer. Les entiers devront être compris entre 0 et 100.
/* Auteur : ... */
/* Date :  ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
void aleaTableau(int tab[50], int taille);

(rappel) Comment faire de l’aléatoire en C ?

  • Il faut importer la bibliothèque time.h
#include <stdio.h>
#include <stdlib.h>

#include <time.h>
  • Il faut initialiser la “GRAINE” et le faire UNE SEULE ET UNIQUE FOIS dans le programme principal.

L’instruction est la suivante : srand(time(NULL));. Si on ne met pas cette instruction, une fois, alors le nombre aléatoire généré sera toujours le même.

/* exo 6 :  Approximation de PI */
int main(){

    srand(time(NULL));

    return 0;
}
  • Pour générer un nombre aléatoire, l’instruction est la suivante :
    int a = rand() % 5; /* génération d'un entier aléatoire entre 0 et 5 */
  1. Écrire une procédure permettant d’afficher le tableau.
/* Auteur : ... */
/* Date :  ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
void afficherTableau(int tab[50], int taille);
  1. Ecrire le programme principal permettant d’utiliser ces 2 procédures précédements créées. Le programme demandera à l’utilisateur la taille du tableau qu’il souhaite créer.
  1. Écrire une fonction permettant de rechercher un nombre dans un tableau d’entier. Cette fonction renvoie la première position de la valeur recherchée. Si la valeur n’est pas dans le tableau, la fonction renvoie -1.
/* Auteur : ... */
/* Date :  ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
int rechercherTableau(int tab[MAX], int taille, int valRechercher);
  1. Écrire le programme principal qui demande à l’utilisateur de saisir la taille du tableau, un nombre qui souhaite et qui, via le prédicat précédement créé, vérifie si c’est un nombre est présent dans le tableau.

Exercice 3 : Le carré magique

Un carré magique d’ordre n est un tableau n x n tel que la somme des entiers de chaque ligne, chaque colonne et des deux diagonales est identique.

Exemple : Tableau carré magique d’ordre 3

  1. Créer un répertoire exo3 dans lequel on ajoutera le fichier exo3.c contenant le code suivant :
#include <stdio.h>
#include <stdlib.h>

/* exo 3 : le carré magique */
int main(){
    return 0;
}
  1. Ajouter dans le programme principal la définition d’une matrice avec un tableau déjà rempli

TIPS : comment remplir directement un tableau en C ?

Un tableau 1D
int tab[3]={8, 1, 6};

Attention Il faut le faire la déclaration et l’affectation en même temps, sinon ça ne marche pas.

Un tableau 2D
int carre[3][3]=
{
    {8, 1, 6},
    {3, 5, 7},
    {4, 9, 2}
};

Attention Il faut le faire la déclaration l’affectation en même temps, sinon ça ne marche pas.

  1. Ecrire une procédure permettant d’afficher une matrice carré
  1. Écrire une fonction permettant de faire la somme d’une ligne passée en paramètre.
  2. Écrire une fonction permettant de faire la somme d’une colonne passée en paramètre.
  3. Écrire une fonction permettant de faire la somme de la diagonale du carré en partant d’en bas à gauche.
  4. Écrire une fonction permettant de faire la somme de la diagonale du carré en partant d’en haut à gauche.
  5. Écrire un prédicat permettant de dire si un carré passé en paramètre est magique. Vous utiliserez les fonctions précédement créées.
  6. Compléter le programme principal afin de faire appel au prédicat permettant de vérifier si un carré est magique.

Exercice 4 : Le morpion

  1. Créer un répertoire exo3 dans lequel on ajoutera le fichier exo3.c contenant le code suivant :
#include <stdio.h>
#include <stdlib.h>

/* exo 4 : Le morpion */
int main(){
    return 0;
}

Le morpion se joue dans une grille à deux dimensions 3x3. Une case de la grille peut contenir 3 valeurs possibles : vide, croix ou rond.

Chaque joueur joue alternativement sur une case vide. Le premier qui a 3 symboles alignés horizontalement, verticalement ou en diagonale a gagné. Nous allons définir les algorithmes permettant de coder ce jeu dans sa version deux joueurs.

  1. Créer une procédure initGrille qui permet d’initialiser la grille, lorsqu’aucun joueur n’a joué. Elle contiendra uniquement la valeur -1
/* Auteur : ... */
/* Date : ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
void initTableau(int grille[N][N], int taille);
  1. Créer une procédure affGrille qui permet d’afficher la grille, selon les valeurs contenues dans chaque case :
  • Si la case contient un -1, alors j’affiche un espace
  • Si la case contient un 1, alors j’affiche un ‘X’
  • Si la case contient un 2, alors j’affiche un ‘O’
/* Auteur : ... */
/* Date : ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
void afficherGrille(int grille[N][N], int taille);
  1. Créer une procédure tour2jeu qui prend en paramètre la grille de jeu, le joueur à jouer, qui demande au joueur de choisir une case vide (ligne+colonne, à vérifier), et si la case est bien vide qui joue le coup.
/* Auteur : ... */
/* Date : ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
void tour2jeu(int grille[N][N],int joueur);
  1. Écrire un prédicat aGagne qui prend en paramètre un joueur, la grille et qui vérifie si le joueur a gagné
/* Auteur : ... */
/* Date : ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
int aGagne (int grille[N][N], int joueur,int taille);
  1. Créer le programme principal qui affiche la grille puis alterne les tours de jeu jusqu’à ce qu’un joueur gagne ou que toutes les cases soient remplies, sans vainqueur. Vous afficherez alors le nom du vainqueur ou bien “match nul”

Exercice 5 : Les nombres Mayas

La numération maya est une numération de position de base 20 (à une irrégularité près dans la notation des grandes durées).” Le système est simple (cf figure 1), basé sur deux symboles : le point désigne une unité, le trait pour 5 points

  1. Créer un type structuré “maya”, composé d’un champ trait et d’un champ point.

  2. Créer un constructeur (une fonction) creerMaya pour ce type (on considérera seulement les nombres de 0 à 19 !). Si les paramètres d’entrée sont invalides, le constructeur devra déclencher une erreur.

/* Auteur : ... */
/* Date : ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
Maya creerMaya(int n);
  1. Créer la procédure afficherMaya qui permet d’afficher un maya passé en paramètre.
/* Auteur : ... */
/* Date : ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
void afficher(Maya m);
  1. Réaliser l’opération plus entre nombres maya (sans passer par notre numérotation…). Attention : si le résultat du calcul atteint les 20aines ou 30aines, le résultat sera une valeur non conforme et une erreur devra se déclencher.
/* Auteur : ... */
/* Date : ... */
/* Résumé : ... */
/* Entrée(s) : ... */
/* Sortie(s) : ... */
Maya addition(Maya m1, Maya m2);

TIPS : soulever une erreur et quitter le programme

En algo : on a vu
ERREUR("out of range")
En C : on le traduit
printf("out of range");
exit(EXIT_FAILURE);