Questions INGINIOUS

  1. Le premier exercice INGINIOUS porte sur le heap et le stack : https://inginious.info.ucl.ac.be/course/LEPL1503/s3_stack_vs_heap
  2. La question suivante porte sur les déclarations de types de données : https://inginious.info.ucl.ac.be/course/LEPL1503/s3_types
  3. strcpy(3) est une fonction de la librairie standard qui permet de copier une chaîne de caractères. Cet exercice vous propose d’écrire une variante de cette fonction : https://inginious.info.ucl.ac.be/course/LEPL1503/s3_strcpy
  4. Lorsque l’on travaille avec les pointeurs, il est possible d’accéder à n’importe quel endroit de la mémoire. Cet exercice vous permet de tester vos compétences de manipulation des pointeurs: https://inginious.info.ucl.ac.be/course/LEPL1503/s3_pointer_types
  5. malloc(3) est une fonction clé en C puisqu’elle permet d’allouer une zone de mémoire. Elle a l’inconvénient de ne pas initialiser cette mémoire, contrairement à calloc(3). Lisez les pages de manuel de ces deux fonctions et implémentez vous-même la fonction calloc(3) en utilisant malloc(3) : https://inginious.info.ucl.ac.be/course/LEPL1503/s3_calloc2
  6. Lorsque l’on utilise les fonctions de la librairie ou les appels systèmes, il est nécessaire de vérifier chaque fois leur valeur de retour pour éviter tout problème. Dans cet exercice, vous écrivez une variante de malloc(3) qui essaye plusieurs fois d’allouer de la mémoire pour pallier à un problème temporaire de manque de mémoire : https://inginious.info.ucl.ac.be/course/LEPL1503/s3_sleep_malloc
  7. Un exercice classique pour montrer que l’on comprend bien les pointeurs est de manipuler des listes chaînées: https://inginious.info.ucl.ac.be/course/LEPL1503/s3_basic_linked_list
  8. Un exercice sur le parcours simple d’un arbre binaire de recherche https://inginious.info.ucl.ac.be/course/LEPL1503/s3_BST
  1. Maintenant que vous avez écrit de nombreuses fonctions sur INGINIOUS, il est temps pour vous d’écrire votre premier programme directement en C. Utilisez un éditeur de texte pour écrire le fichier test.c qui implémente un sous-ensemble du programme standard test(1). Pensez à structurer votre code en utilisant des sous-fonctions. Compilez votre programme sur votre ordinateur et testez-le avant de le soumettre sur INGINIOUS. Vous ne pouvez faire qu’une soumission par jour, vérifiez le bon fonctionnement de votre programme avant de le soumettre. https://inginious.info.ucl.ac.be/course/LEPL1503/s3_commandetest

Vérifiez vos réponses

Questions complémentaires

  1. En C, on peut définir des tableaux à deux dimensions avec une déclaration comme int a[3][3];. Ecrivez un petit programme qui utilise des pointeurs pour déterminer si un tel tableau à deux dimensions est stocké ligne par ligne ou colonne par colonne.

  2. Exécutez plusieurs fois le code suivant. Expliquez les différents résultats obtenus.
    int global;
    void main(void)
    {
            int local;
            int *ptr1 = (int *)malloc(sizeof(*ptr1));
            int *ptr2 = (int *)malloc(sizeof(*ptr2));
    
            printf("global %p loc %p p1 %p p2 %p\n", &global, &local, ptr1, ptr2);
    }
    
  1. Un étudiant a fait l’implémentation d’un sous-ensemble des fonctions définies dans string.h, mais il rencontre quelques problèmes avec son code ./src/string.c. Utilisez gdb pour corriger son code. Utilisez le flag -g de gcc pour ajouter les informations de debug dans votre programme. Pour rappel, voici quelques commandes importantes de gdb :

    • run [ARGS] permet de lancer l’exécution du programme avec les arguments ARGS si spécifiés.

    • break string.c:9 met un point d’arrêt à la ligne 9 du fichier string.c

    • next permet d’exécuter la ligne courante et de s’arrêter à la ligne suivante

    • print var affiche la valeur de la variable var

    • backtrace affiche la pile d’appel des fonctions courantes

    • quit quitte gdb

  2. Vous travaillez sur un programme qui doit manipuler des vecteurs. Afin de pouvoir supporter des vecteurs de taille quelconque, vous décidez de réimplémenter ces vecteurs vous même en utilisant des pointeurs. Votre programme définit la structure struct vector_t et les fonctions ci-dessous. Implémentez ces fonctions sans jamais utiliser la notation des tableaux en C ([ et ]).

    struct vector_t {
      int size;
      float *v;
    };
    // initialise le vecteur à la valeur du réel
    struct vector_t * init(int, float) ;
    // récupère le nième élément
    float get(struct vector_t *, int) ;
    // fixe la valeur du nième élément
    void set(struct vector_t *, int , float);
    // supprime un vecteur
    void destroy(struct vector_t *);
    
    
  3. Expliquez à quoi sert l’attribut packed des structures dans gcc(1) (regardez la manpage). Appliquez cet attribut à la structure de l’exercice précédent. Qu’observez-vous comme différence ? Quel sont les avantages et désavantages d’utiliser cet attribut ? Dans quel cas est-il intéressant de l’utiliser ?