EXAMEN LANGAGE C ( PROGRAMMATION C ) TEST  06 /XX 2023

EXAMEN + CORRIGE EN LANGAGE C

Examinateur : Mr Joël Yk

Exercice 01 : Les Pointeurs (8pts)

  1. Comment déclarez-vous un pointeur sur un tableau de 10 entiers ? Illustrer par un exemple.
  2. Comment accédez-vous au troisième élément d'un tableau à l'aide d'un pointeur ? Illustrer par un exemple.
  3. Quelle est la différence entre une expression de déréférencement de pointeur (*ptr) et une expression d'adresse (&var) ?
  4. Comment pouvez-vous allouer de la mémoire dynamiquement pour un tableau à l'aide de pointeurs ? Illustrer par un exemple.
  5. Comment pouvez-vous copier le contenu d'un tableau dans un autre tableau à l'aide de pointeurs  ? Illustrer par un exemple ( ecrire une petite fonction qui realise cela).
  6. Comment pouvez-vous comparer deux tableaux à l'aide de pointeurs ? Illustrer par un exemple ( ecrire une petite fonction qui realise cela).
  7. Comment pouvez-vous trier (tri-bulle) un tableau à l'aide de pointeurs ? Illustrer par un exemple ( ecrire une petite fonction qui realise cela).
  8. Comment pouvez-vous concaténer deux tableaux à l'aide de pointeurs ? Illustrer par un exemple ( ecrire une petite fonction qui realise cela).
  9. Comment pouvez-vous passer un tableau en tant qu'argument d'une fonction à l'aide de pointeurs ?Illustrer par un exemple.
  10. Comment pouvez-vous retourner un tableau à partir d'une fonction à l'aide de pointeurs ?Illustrer par un exemple ( ecrire une petite fonction qui realise cela).

Exercice 02 : Les fichiers en C (5pts)

  1. Qu'est-ce qu'un fichier en C ? Comment ouvrir un fichier en lecture et en écriture ?
  2. Comment lire et écrire des valeurs simples (entiers, chaînes de caractères, etc.) dans un fichier en C ?
  3. Comment parcourir les lignes d'un fichier en C ?
  4. Comment utiliser la fonction fseek() pour se déplacer dans un fichier en C ?
  5. Qu'est-ce qu'une structure de données de fichier et comment l'utiliser pour stocker des enregistrements complexes dans un fichier ?
  6. Comment gérer les erreurs lors de l'utilisation de fichiers en C, en utilisant la fonction ferror() et la macro feof() ?

Probleme :  7pts

Dans la ville de Dschang Mr Joel ouvre une petite boutique de Gestion de produits IT (Ordianteurs, souris, clavier etc ...) et desire pour cela realise une petite application a cet effet et se tourne vers un informaticien pour cela :

  1. Qu'est-ce qu'un enregistrement en C ? Comment déclarer un enregistrement nommé "produit" contenant les champs "nom", "prix" et "quantite" ?
  2. Comment écrire une fonction en C float prix_total(struct produit p) qui prend un enregistrement "produit" en entrée et renvoie son prix total (prix * quantite) ?
  3. Comment définir une procédure en C ( void sort_products(struct produit *arr, int size) ) qui prend en entrée un tableau d'enregistrements "produit" et un entier "taille" et trie le tableau par ordre croissant de prix total en utilisant un trie selection ?
  4. Comment utiliser une chaîne de caractères (char*) pour stocker le nom d'un produit dans l'enregistrement "produit"  vous devez ecrire une fonction (void set_name(struct produit *p, char *nom)) ?
  5. Comment écrire une fonction en C (int find_product(struct produit *arr, int size, char *nom))qui prend en entrée un tableau d'enregistrements "produit", un entier "taille" et une chaîne de caractères "nom" et renvoie l'indice du premier produit ayant ce nom dans le tableau, ou -1 si aucun produit n'a ce nom ?
  6. Comment écrire une procédure en C (void update_price(struct produit *arr, int size, int index, float new_price) )qui prend en entrée un tableau d'enregistrements "produit", un entier "taille" et un entier "indice" et met à jour le prix du produit à l'indice donné avec un nouveau prix donné en entrée ?
  7. Comment écrire une fonction en C (int count_zero_quantity(struct produit *arr, int size)) qui prend en entrée un tableau d'enregistrements "produit", un entier "taille" et renvoie le nombre total de produits ayant une quantité nulle ?

Correction :

Exercice 01 :

  1. Pour déclarer un pointeur sur un tableau de 10 entiers, vous pouvez utiliser la syntaxe suivante : int (*ptr)[10];.
  2. Pour accéder au troisième élément d'un tableau à l'aide d'un pointeur, vous pouvez utiliser la syntaxe suivante : *(ptr + 2).
  3. Une expression de déréférencement de pointeur (*ptr) permet d'accéder à la valeur stockée à l'adresse pointée par ptr, tandis qu'une expression d'adresse (&var) renvoie l'adresse de la variable var.
  4. Pour allouer de la mémoire dynamiquement pour un tableau à l'aide de pointeurs, vous pouvez utiliser la fonction malloc de la bibliothèque standard stdlib.h. Par exemple, pour allouer de la mémoire pour un tableau de 10 entiers, vous pouvez utiliser la syntaxe suivante : int *ptr = malloc(10 * sizeof(int));.
  5. Pour copier le contenu d'un tableau dans un autre tableau à l'aide de pointeurs, vous pouvez utiliser une boucle for et des expressions de déréférencement de pointeur. Par exemple : int arr1[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int arr2[10]; int *p1 = arr1, *p2 = arr2; for (int i = 0; i < 10; i++) { *(p2 + i) = *(p1 + i); }
  6. Pour comparer deux tableaux à l'aide de pointeurs, vous pouvez utiliser une boucle for et des expressions de déréférencement de pointeur. Si vous trouvez une valeur différente dans l'un des deux tableaux, vous pouvez conclure que les tableaux sont différents. Si vous parcourez tout le tableau sans trouver de valeur différente, vous pouvez conclure que les tableaux sont identiques. Voici un exemple de fonction qui compare deux tableaux de 10 entiers et renvoie 1 si les tableaux sont identiques, 0 sinon :

    #define N 10

    int compare_arrays(int *arr1, int *arr2) {
        for (int i = 0; i < N; i++) {
            if (*(arr1 + i) != *(arr2 + i)) {
                return 0;
            }
        }
        return 1;
    }

     

    Pour utiliser cette fonction, vous pouvez déclarer deux tableaux et appeler la fonction en passant leurs adresses en argument :

    int arr1[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int arr2[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int result = compare_arrays(arr1, arr2);

     

  7. Pour trier un tableau à l'aide de pointeurs, vous pouvez utiliser un algorithme de tri comme le tri par sélection ou le tri à bulles. Vous pouvez utiliser des pointeurs pour parcourir le tableau et échanger les valeurs des éléments en utilisant des expressions de déréférencement de pointeur. Par exemple, voici comment trier un tableau à l'aide de l'algorithme du tri à bulles :

    #define N 10 void sort_array(int *arr) { int temp; for (int i = 0; i < N - 1; i++) { for (int j = 0; j < N - i - 1; j++) { if (*(arr + j) > *(arr + j + 1)) { temp = *(arr + j); *(arr + j) = *(arr + j + 1); *(arr + j + 1) = temp; } } } }

  8. 8) Pour concaténer deux tableaux à l'aide de pointeurs, vous pouvez utiliser une boucle for et des expressions de déréférencement de pointeur pour copier les éléments du deuxième tableau à la suite du premier. Par exemple :

    #define N 10 #define M 20 void concat_arrays(int *arr1, int *arr2, int *result) { int *p = result; for (int i = 0; i < N; i++) { *p = *(arr1 + i); p++; } for (int i = 0; i < M; i++) { *p = *(arr2 + i); p++; } }

    9) Pour passer un tableau en tant qu'argument d'une fonction à l'aide de pointeurs, vous pouvez utiliser la syntaxe suivante : void func(int *arr). Dans la définition de la fonction, arr sera un pointeur vers le premier élément du tableau passé en argument.

    10. Pour retourner un tableau à partir d'une fonction à l'aide de pointeurs, vous pouvez utiliser la syntaxe suivante : int *func(void). Dans la définition de la fonction, vous pouvez allouer de la mémoire pour le tableau à l'aide de pointeurs et renvoyer l'adresse du premier élément du tableau en utilisant l'expression d'adresse (&arr[0]). Voici un exemple de fonction qui retourne un tableau de 10 entiers :

    int *get_array(void) { int *arr = malloc(10 * sizeof(int)); for (int i = 0; i < 10; i++) { *(arr + i) = i; } return arr; }

    Pour utiliser cette fonction, vous pouvez déclarer un pointeur et l'initialiser avec le résultat de la fonction : int *ptr = get_array();. Vous pouvez alors accéder aux éléments du tableau en utilisant des expressions de déréférencement de pointeur (*(ptr + i)). N'oubliez pas de libérer la mémoire allouée pour le tableau une fois que vous avez terminé de l'utiliser avec la fonction free.

Exercice 02 :

Qu'est-ce qu'un fichier en C ?

Un fichier en C est un ensemble de données stockées sur un support de stockage (disque dur, clé USB, etc.) et accessibles via un nom de fichier. Les fichiers permettent de stocker et de récupérer des données de manière persistante, c'est-à-dire même après l'arrêt du programme.

2)Comment ouvrir un fichier en lecture et en écriture ?

Pour ouvrir un fichier en lecture ou en écriture, on utilise la fonction fopen() de la bibliothèque standard de C. Cette fonction prend en paramètres le nom du fichier et le mode d'ouverture souhaité ("r" pour la lecture, "w" pour l'écriture, "a" pour ajouter à la fin du fichier). Elle retourne un pointeur sur le type FILE, qui représente le fichier ouvert.

Voici un exemple d'ouverture d'un fichier en lecture :

FILE *fichier = fopen("mon_fichier.txt", "r");
if (fichier == NULL) {
    // Erreur lors de l'ouverture du fichier
}

Et voici un exemple d'ouverture d'un fichier en écriture :

FILE *fichier = fopen("mon_fichier.txt", "w");
if (fichier == NULL) {
    // Erreur lors de l'ouverture du fichier
}

2)Comment lire et écrire des valeurs simples (entiers, chaînes de caractères, etc.) dans un fichier en C ?

Pour lire et écrire des valeurs simples dans un fichier en C, on utilise les fonctions de la bibliothèque standard de C. Par exemple, pour lire un entier, on utilise la fonction fscanf() :

int entier;
fscanf(fichier, "%d", &entier);

 on utilise la fonction fprintf()

int entier = 42;
fprintf(fichier, "%d", entier);

Voici quelques exemples de fonctions pour lire et écrire d'autres types de données :

Pour lire une chaîne de caractères : fgets()

Pour écrire une chaîne de caractères : fputs()

Pour lire un caractère : fgetc()

Pour écrire un caractère : fputc()

3)Comment parcourir les lignes d'un fichier en C ?

Pour parcourir les lignes d'un fichier en C, on peut utiliser la fonction fgets(), qui permet de lire une ligne jusqu'à rencontrer un retour à la ligne ou la fin du fichier. Voici un exemple de boucle qui parcourt toutes les lignes d'un fichier :

char ligne[1024]; // Tableau de caractères pour stocker la ligne lue

while (fgets(ligne, sizeof(ligne), fichier) != NULL) {
    // Traitement de la ligne
}

4)

Comment utiliser la fonction fseek() pour se déplacer dans un fichier en C ?

La fonction fseek() permet de se déplacer dans un fichier en spécifiant un décalage en nombre de bytes à partir de la position actuelle, du début du fichier ou de la fin du fichier. Voici comment utiliser cette fonction pour se déplacer au début du fichier :

fseek(fichier, 0, SEEK_SET);

Voici comment utiliser cette fonction pour se déplacer de 10 bytes à partir de la position actuelle :

fseek(fichier, 10, SEEK_CUR);

Voici comment utiliser cette fonction pour se déplacer de 10 bytes avant la fin du fichier :

fseek(fichier, -10, SEEK_END);

5)

Une structure de données de fichier est une structure qui permet de stocker des données complexes de manière organisée dans un fichier. Par exemple, si on veut stocker une liste d'étudiants dans un fichier, on peut définir une structure Etudiant contenant les champs nom, prenom, age et classe, et créer un tableau de cette structure pour stocker tous les étudiants.

Pour utiliser cette structure de données de fichier, il faut d'abord ouvrir le fichier en écriture (en utilisant la fonction fopen()) et utiliser des fonctions d'écriture (comme fwrite()) pour écrire les données dans le fichier. Voici un exemple d'écriture de plusieurs étudiants dans un fichier :

Etudiant etudiants[100];
int nbEtudiants = 3;

FILE *fichier = fopen("etudiants.bin", "w");
fwrite(etudiants, sizeof(Etudiant), nbEtudiants, fichier);
fclose(fichier);

pour lire ces données depuis le fichier, il faut ouvrir le fichier en lecture (en utilisant la fonction fopen()) et utiliser la fonction fread() pour lire les données dans un tableau de la structure Etudiant. Voici un exemple de lecture de tous les étudiants d'un fichier :

Etudiant etudiants[100];

FILE *fichier = fopen("etudiants.bin", "r");
int nbEtudiants = fread(etudiants, sizeof(Etudiant), 100, fichier);
fclose(fichier);

Il est important de fermer le fichier à la fin de l'opération (en utilisant la fonction fclose()) pour libérer les ressources système utilisées par le fichier.

6)

La fonction ferror() permet de savoir si une erreur s'est produite lors de l'utilisation d'un fichier en C. Elle prend en paramètre un pointeur de fichier et retourne un entier non nul si une erreur s'est produite, ou 0 si aucune erreur n'a été détectée. Voici un exemple d'utilisation de la fonction ferror() :

FILE *fichier = fopen("fichier.txt", "r");
if (ferror(fichier)) {
    // Une erreur s'est produite, il faut gérer l'erreur ici
}

La macro feof() permet de savoir si la fin du fichier a été atteinte lors de l'utilisation d'un fichier en C. Elle prend en paramètre un pointeur de fichier et retourne un entier non nul si la fin du fichier a été atteinte, ou 0 sinon. Voici un exemple d'utilisation de la macro feof() :

FILE *fichier = fopen("fichier.txt", "r");
while (!feof(fichier)) {
    // Lire les données du fichier ici
}

Il est recommandé de vérifier à chaque fois qu'on utilise un fichier en C si une erreur s'est produite ou si la fin du fichier a été atteinte, pour éviter des comportements indésirables de votre programme.

 

Probleme :

1) Un enregistrement en C est une structure de données qui permet de regrouper plusieurs variables de différents types sous un même nom. Pour déclarer un enregistrement nommé "produit" contenant les champs "nom", "prix" et "quantite", vous pouvez utiliser la syntaxe suivante :

struct produit {
    char *nom;
    float prix;
    int quantite;
};

 

2) Voici comment écrire une fonction en C qui prend un enregistrement "produit" en entrée et renvoie son prix total (prix * quantite) :

float prix_total(struct produit p) {
    return p.prix * p.quantite;
}

3) Voici comment définir une procédure en C qui prend en entrée un tableau d'enregistrements "produit" et un entier "taille" et trie le tableau par ordre croissant de prix total en utilisant un tri par sélection :

#define N 10

void sort_products(struct produit *arr, int size) {
    struct produit temp;
    for (int i = 0; i < size - 1; i++) {
        int min_index = i;
        for (int j = i + 1; j < size; j++) {
            if (prix_total(arr[j]) < prix_total(arr[min_index])) {
                min_index = j;
            }
        }
        temp = arr[i];
        arr[i] = arr[min_index];
        arr[min_index] = temp;
    }
}

4)Pour affecter une chaîne de caractères à ce champ, vous pouvez utiliser la fonction strcpy de la bibliothèque string.h. Voici comment définir une fonction qui prend en entrée un enregistrement "produit" et une chaîne de caractères "nom" et met à jour le nom du produit :

void set_name(struct produit *p, char *nom) { strcpy(p->nom, nom); }

5)Voici comment écrire une fonction en C qui prend en entrée un tableau d'enregistrements "produit", un entier "taille" et une chaîne de caractères "nom" et renvoie l'indice du premier produit ayant ce nom dans le tableau, ou -1 si aucun produit n'a ce nom :

int find_product(struct produit *arr, int size, char *nom) {
    for (int i = 0; i < size; i++) {
        if (strcmp(arr[i].nom, nom) == 0) {
            return i;
        }
    }
    return -1;
}

6)Voici comment écrire une procédure en C qui prend en entrée un tableau d'enregistrements "produit", un entier "taille" et un entier "indice" et met à jour le prix du produit à l'indice donné avec un nouveau prix donné en entrée :

void update_price(struct produit *arr, int size, int index, float new_price) {
    if (index >= 0 && index < size) {
        arr[index].prix = new_price;
    }
}

7)Voici comment écrire une fonction en C qui prend en entrée un tableau d'enregistrements "produit", un entier "taille" et renvoie le nombre total de produits ayant une quantité nulle :

int count_zero_quantity(struct produit *arr, int size) {
    int count = 0;
    for (int i = 0; i < size; i++) {
        if (arr[i].quantite == 0) {
            count++;
        }
    }
    return count;
}

  • Aucune note. Soyez le premier à attribuer une note !

Ajouter un commentaire

Anti-spam