Année universitaire 2002-2003
espace

Licence d'informatique
Module 4 - partie "C / shell"



Travaux dirigés 3 :

  • 1. Comparateurs et opérateurs logiques.
  • 2. Exercice 1 : années bissextiles.
  • 3. Exercice 2 : nombre de jours écoulés.
  • 4. Tableaux unidimensionnels.
  • 5. Représentation graphique de la mémoire.
  • 6. Passage d'un tableau en paramètre.
  • 7. Tableaux bidimensionnels.
  • 8. Définition d'un type.
  • 9. Exercice 3 : tableau à deux dimensions.

  • 1. Comparateurs et opérateurs logiques.

    1.1. Valeurs retournées par les comparateurs et les opérateurs logiques.

    Les comparateurs (>, <, >=, <=, ==, !=) et les opérateurs logiques "binaires" (&&, ||) renvoient 0 si le résultat est FAUX et 1 s'il est VRAI. L'opérateur logique "unaire" de négation (!) renvoie 0 pour toute valeur non nulle et 1 pour la valeur 0 :

    !0 == 1 espace!8 == 0

    1.2. Ordre d'évaluation des opérateurs logiques binaires.

    Les opérateurs logiques binaires && et || doivent être utilisés selon la syntaxe suivante :

    expr1 et expr2 doivent être des expressions de valeurs entières ou flottantes.

    Pour l'opérateur &&, si expr1 est nulle (c'est-à-dire évaluée à FAUX), alors expr2 n'est pas évaluée, et le résultat de l'opération vaut 0

    Pour l'opérateur ||, si expr1 est non nulle (c'est-à-dire évaluée à VRAI), alors expr2 n'est pas évaluée, et le résultat de l'opération vaut 1

    Les opérateurs && et || ne sont donc pas commutatifs. Par conséquent, si on change l'ordre des expressions expr1 et expr2 d'une opération logique binaire, cela peut modifier le comportement d'un programme, en particulier si ce programme comporte des pré-incrémentations ou des post-incrémentations.

    Exemple :

    2. Exercice 1.

    Écrire une fonction qui détermine si une année est bissextile.

    Rappel :

    Exemples :

    3. Exercice 2.

    Écrire un programme qui, à partir d'une date exprimée sous la forme jour mois année, calcule le nombre de jours écoulés depuis le début de l'année jusqu'à la date précisée.

    Exemple :

    4. Tableaux unidimensionnels.

    La déclaration suivante :

    est celle d'un tableau unidimensionnel de 3 entiers, ayant pour adresse tab ou encore &tab[0]

    Les 3 cases associées à ce tableau sont situées en mémoire de manière contiguë, et sont 3 variables de type int de noms tab[0], tab[1] et tab[2].

    5. Représentation graphique de la mémoire.

    Afin de donner une représentation de la manière dont la mémoire centrale d'un ordinateur est gérée lors de l'exécution d'un programme, on conseille de toujours dessiner un graphique respectant les conventions suivantes :

    Exemple :

    image 1

    6. Passage d'un tableau en paramètre.

    L'exemple de programme suivant donne une solution pour récupérer l'adresse du tableau précédent dans une fonction :


    Langage C


    Équivalent Ada


    Équivalent Pascal

    #include <stdio.h>



    void lecture_tab_C(int tab2[],
    int nbcar)
    {
    int i;
    for (i=0;i<nbcar;i++)
    scanf("%d",&tab2[i]);

    }
    int main(void)
    {
    int i,tab[3];
    lecture_tab_C(tab,3);
    for (i=0;i<3;i++)
    printf("%d ",tab[i]);
    printf("\n");
    return(0);
    }
    with Ada.Text_Io,Ada.Integer_Text_Io;
    use Ada.Text_Io,Ada.Integer_Text_Io;
    procedure init_tab_Ada is
    type tableau is array (0..2) of integer;
    procedure lecture_tab_Ada
    (tab2:out tableau;nbcar:in integer) is
    begin
    for i in 0..nbcar-1 loop
    get(tab2(i));
    skip_line;
    end loop;
    end lecture_tab_Ada;
    tab:tableau;
    begin
    lecture_tab_Ada(tab,3);
    for i in tab'range loop
    put(tab(i),0);
    put(' ');
    end loop;
    new_line;
    end init_tab_Ada;
    PROGRAM init_tab_Pascal;
    USES crt;
    TYPE tableau=ARRAY [0..2] OF INTEGER;

    PROCEDURE lecture_tab_Pascal
    (VAR tab2:tableau;nbcar:INTEGER);
    VAR i:INTEGER;
    BEGIN
    FOR i:=0 TO nbcar-1 DO
    readln(tab2[i])
    END;
    VAR i:INTEGER;
    tab:tableau;
    BEGIN
    lecture_tab_Pascal(tab,3);
    FOR i:=0 TO 2 DO
    write(tab[i],' ');
    writeln
    END.

    Les valeurs des trois cases de tab sont modifiées, lors de l'appel des fonctions lecture_tab_C, lecture_tab_Ada ou lecture_tab_Pascal, par la lecture de nombres tapés au clavier.

    Remarque :

    En revanche, dans le programme suivant, dans lequel le paramètre de la fonction n'est plus un tableau, mais un entier, seules les versions Ada et Pascal sont correctes :


    Langage C


    Équivalent Ada


    Équivalent Pascal

    #include <stdio.h>


    void lecture_int_C_incorrecte(int a2)

    {
    scanf("%d",&a2);
    a2++;
    }

    int main(void)
    {
    int a=0;
    lecture_int_C(a);
    printf("%d\n",a);
    return(0);
    }
    with Ada.Text_Io,Ada.Integer_Text_Io;
    use Ada.Text_Io,Ada.Integer_Text_Io;
    procedure init_int_Ada is
    procedure lecture_int_Ada
    (a2:out integer) is
    begin
    get(a2);
    skip_line;
    a2:=a2+1;
    end lecture_int_Ada;
    a:integer:=0;
    begin
    lecture_int_Ada(a);
    put(a,0);
    new_line;
    end init_int_Ada;
    PROGRAM init_int_Pascal;
    USES crt;

    PROCEDURE lecture_int_Pascal
    (VAR a2:INTEGER);
    BEGIN
    readln(a2);
    a2:=a2+1
    END;
    VAR a:INTEGER;

    BEGIN
    a:=0;
    lecture_int_Pascal(a);
    writeln(a1)
    END.

    Dans la version C, le programme principal produira l'affichage de la valeur 0 initialement affectée à a. La raison en est la suivante : à l'intérieur de la fonction lecture_tab_C de l'exemple précédent, on a accès à l'adresse du tableau tab (passage "par adresse"), alors qu'à l'intérieur de la fonction lecture_int_C, on n'a pas accès à l'adresse de l'entier a (passage "par valeur"). On verra dans la séance 4 de travaux dirigés comment rendre correcte la fonction lecture_int_C.

    Remarque :

    7. Tableaux bidimensionnels.

    Soit tab un tableau à deux dimensions (un tel tableau est également appelé une "matrice"), déclaré de la manière suivante :

    Les six cases de ce tableau sont situées en mémoire de manière contiguë. Il semble a priori qu'il y ait une ambiguïté concernant l'ordre dans lequel ces six cases apparaissent en mémoire. Il est important de savoir que c'est le dernier indice qui varie en premier. Voici donc la configuration en mémoire des cases du tableau tab :

    representation en memoire

    Si on suppose que le premier indice du tableau tab désigne le numéro de ligne, et le second le numéro de colonne, on peut également retenir que cette configuration correspond à la manière dont on lit un texte, c'est-à-dire ligne par ligne.

    Soit une fonction fonct, retournant par exemple un entier, à laquelle on souhaite passer l'adresse du tableau tab en paramètre. L'appel de la fonction fonct se fera en passant l'adresse du tableau tab, sous la forme suivante :

    Quant à l'en-tête de la déclaration de fonct, il peut être écrit de l'une des deux manières suivantes :

    Attention :

    Remarque :

    8. Définition d'un type.

    Il est possible de définir un type en C, à l'aide du mot-clé typedef

    Exemple :

    9. Exercice 3.

    Écrire un programme C permettant de saisir les notes (entières) obtenues par quatre élèves à trois examens successifs. Les notes sont tapées dans l'ordre suivant :

    À l'issue de la saisie des notes, le programme devra afficher la moyenne obtenue par chaque élève à l'ensemble des examens.

    Remarques :


    Ces pages ont été réalisées par A. Crouzil, J.D. Durou et Ph. Joly.
    Pour tout commentaire, envoyer un mail à crouzil@irit.fr, à durou@irit.fr ou à Philippe.Joly@irit.fr.