2 - Éléments de base

Le traitement de l’information

Catégorie d’information

Sous l’angle de la programmation, on classe l’information en trois catégories :

  • Les données : les informations qu’on doit traiter

  • Les résultats : les informations recherchées (une fois traitées)

  • Informations intermédiaires : celles qui servent de relais pour passer des données aux résultats

Exemple : Déterminer la facture finale d’un repas à partir du montant d’une addition au restaurant.

  • Données : le montant de l’addition avant pourboire, le taux du pourboire (15 %)

  • Résultats : le montant total à régler au serveur

  • Information(s) intermédiaire(s) : le montant du pourboire à ajouter

Identification d’une information

Dans la vie de tous les jours, nos noms et prénoms servent à nous identifier et à nous distinguer des autres personnes. Il en va de même en programmation : un identificateur est un nom servant à désigner une information.

Un identificateur est une suite de caractères composée de lettres et/ou de chiffres et débutant par une lettre. La majorité des compilateurs tolèrent aussi le caractère “souligné” afin d’améliorer la lisibilité d’un identificateur.

Exemples : tp1, intra, tauxPourboire, montantAddition, totalFacture, TAUX_POURBOIRE,

Il est désormais autorisé d’employer des caractères accentués dans un identificateur, mais cette pratique reste déconseillée.

Les identificateurs ci-dessous sont invalides :

tp#1, tp 1 (les caractères # et espace ne sont pas permis)

1erTP (le premier caractère n’est pas une lettre)

Conseils pratiques :

  1. Un identificateur sert à nommer une information (une donnée, un résultat, un nom de programme, une tâche à réaliser, …). Mieux vaut recourir à des identificateurs significatifs : taille plutôt que t, racine plutôt que r, prix plutôt que p, etc.

  2. Longueur maximale d’un identificateur :

Cette longueur diffère d’un langage à l’autre, d’un compilateur à l’autre, et ce, à l’intérieur d’un même langage.

On vous recommande d’employer des identificateurs significatifs de longueur raisonnable : taille est plus simple et plus rapide à taper que la_taille_de_la_personne_a_traiter

  1. Les compilateurs C distinguent les identificateurs écrits en majuscules de ceux écrits en minuscules :

Exemple : TP1, tp1, Tp1, tP1 désignent des identificateurs distincts.

  1. Identificateurs prédéfinis ou réservés, reconnus par le compilateur : on doit les écrire correctement (souvent en lettres minuscules), par exemple :

int main(), int, float, const, …

  1. Erreurs fréquentes sur les identificateurs :
  • 1ertp Faux commence par un chiffre

  • tp#1 Faux “#” n’est ni une lettre, ni un chiffre

  • tp 1 Faux espace n’est ni une lettre, ni un chiffre

Type de l’information

numérique :

  • entier : int (exemple : -32, 0, 12345)

  • réel : float (exemple : -32.67, 0.0, 1.78)

caractère(s) :

  • un seul caractère : char (exemple : ‘P’, ‘F’)

  • ou une chaîne de caractère(s) : à voir plus tard …

logique de type entier :

  • une valeur non nulle vaut vrai

  • une valeur nulle vaut faux

Au cours des deux premières semaines, on manipule surtout les types entiers (int), réels (float) et caractères (char). Le type logique (booléen) sera abordé vers la troisième semaine. Les autres types seront présentés plus tard dans le cours.

Exemple 1

Écrire les déclarations des variables suivantes :

  • categorie : une variable de type caractère (’e’ pour étudiant, ‘p’ pour professeur)

  • moyenne et mediane : deux variables de type réel

  • nbCours : une variable de type entier

Solution

char  categorie;
float moyenne, mediane;
int   nbCours;

Exemple 2

Écrire les déclarations des variables suivantes :

categorie et programme : deux variables de type caractère (’e’ pour étudiant, ‘p’ pour professeur; ‘i’ pour informatique, ‘g’ pour génie, ’s’ pour sciences)

matricule : numéro de l’étudiant (un entier, exemple : 5478)

nbCredits : le nombre de crédits accumulés (un entier)

Moyenne pondérée : un réel

Solution

char  categorie, programme;
float moyennePonderee;
int   matricule, nbCredits;

Exercice (sans solution)

Écrire les déclarations des variables représentant les informations suivantes d’un livre dans le catalogue d’une bibliothèque :

Sa cote de rangement, son numéro d’exemplaire, le prix d’achat, son état de conservation (neuf, bon, usé, abîmé, perdu).

Nature de l’information

Les constantes

On distingue deux catégories de constantes :

  • Les constantes éternelles : 2, 17.3, 3.14159 (PI), …

  • Les valeurs inchangées d’un problème à traiter : pour notre cours, les barèmes sont identiques pour tous les étudiants. Cependant, il se peut qu’on applique d’autres barèmes pour un autre cours ou qu’on modifie les barèmes d’un cours.

Quand doit-on déclarer les constantes? :

  • Pour généraliser le programme : les barèmes, les taux de taxes, les bonus, etc. Si les taux de taxes changent, par exemple la TPS qui passe de 7 % à 5 % et la TVQ qui passe de 7.5 % à 9.975 %. Il suffira alors de modifier la valeur des constantes déclarées au lieu de parcourir tout le programme pour les repérer et les corriger.

  • Pour éviter des erreurs de frappe ou pour gagner en précision dans les calculs (la valeur de PI par exemple).

Comment peut-on déclarer les constantes? :

Méthode 1 : utiliser
#define  identificateur  valeur

Exemples :

#define TAUX_TPS 0.05
#define TAUX_TVQ 0.09975

#define BAREME_INTRA 0.20

#define FEMININ 'F'
#define AGE_ADULTE 18

La directive #define substitue la valeur au nom de la constante partout dans le programme. En langage C, on conseille d’écrire les identificateurs des constantes en lettres majuscules.

Méthode 2 : utiliser

const type nom = valeur ….

Exemples :

const int   BORNE_ADULTE = 18;
const float TAUX_TPS = 0.05,
            TAUX_TVQ = 0.09975,
            BAREME_INTRA = 0.20,
            PI = 3.14159;
const char  FEMININ = 'F';

Les variables

Une variable est une information dont la valeur peut changer (varier) durant l’exécution du programme.

type liste de variable(s);

Exemples :

int    nbCours;
float  moyenne, mediane, moyennePonderee;
char   categorie, programme;

Affectation

L’un des moyens de donner une valeur à une variable consiste à lui affecter (déposer) soit une constante, soit le résultat d’un calcul, soit la valeur d’une autre variable, etc. L’opérateur d’affectation est le symbole “=” en langage C :

variable = .....;

Exemples :

int nbCours;
float moyenne1, moyenne2;

nbCours = 5;
nbCours = 2 * 3 - 1;
moyenne1 = (78 + 85 + 92) / 3.0;
moyenne2 = moyenne1 + 2.5;

L’une des particularités du langage C est qu’on peut déclarer une variable et lui donner sa valeur de départ en même temps :

int nbCours = 5, nbCredits, nbReussites = 0;
float somMoyenne = 0.0, moyenne;

Commentaires

On insère des commentaires pour décrire l’objectif d’un programme, pour expliquer certaines déclarations ou quelques portions d’un programme.

Les lignes de commentaires se placent entre les symboles /* et */.

Exemples :

/* But du programme : Ce programme permet de ....    */
int nbReussites;   /* le nombre d'etudiants ayant reussi */

/* Calcul de la moyenne ponderee : */
moyennePonderee = (note1 * 0.4 + note2 * 0.6);

Opérateurs de base

Opérateurs arithmétiques

Les opérateurs arithmétiques servent à effectuer des calculs entre des valeurs numériques :

  • Entre des réels et/ou des entiers : +, -, * (la multiplication), / (la division entière ou réelle selon le type des opérandes)

  • Entre deux entiers : % (le reste d’une division)

Exemples :

3 * 5.4 vaut 16.2

10 / 4 vaut 2 (la division entre 2 entiers donne un entier comme résultat, on laisse tomber la partie des décimales)

10.0 / 4 ou 10 / 4.0 ou 10.0 / 4.0 vaut 2.5.

17 % 10 vaut 7 (dans 17 on a 1 fois 10, il reste 7)

25 % 4 vaut 1 (dans 25 on a 6 fois 4, il reste 1)

Notez que les opérateurs *, / et % ont priorité sur + et -. De plus, dans le cas d’une même priorité, on doit effectuer les calculs de gauche à droite pour les opérateurs arithmétiques :

17 / 5 * 4 + 2
------
   3
   -------
      12
      --------
         14

Pour IFT 1810, on utilise souvent l’opérateur % dans les travaux et aussi dans les questions d’examen.

Pour assurer une priorité absolue, on met des parenthèses :

17 / (5 * 4) + 2
     ------
       20
---------
    0
    ------------
         2

Dans le cours, on utilise assez souvent l’opérateur % qui donne le reste dans une division pour plusieurs exemples, notamment :

16 est un multiple de 4 car le reste dans la division de 16 par 4 vaut zéro : ainsi il est vrai d’écrire 16 % 4 == 0.

1237 % 10 vaut 7 (le dernier chiffre, celui des unités)

1996 % 100 vaut 96 (les 2 derniers chiffres)

Opérateurs relationnels (pour la comparaison)

Le résultat d’une comparaison est de type entier : 1 (vrai) ou 0 (faux)

< inférieur à

<= inférieur ou égal à

> supérieur à

>= supérieur ou égal à

== égale à (notez que le symbole “=” est utilisé pour l’affectation)

!= différent de

Exemples :

17 < 23 vaut 1

'c' != 'C' vaut 1

17 % 5 == 4 vaut 0 ( 17 % 5 donne 2, 2 == 4 est faux )

Opérateurs logiques

Relier deux conditions : && (et logique) , || (ou logique)

Pour obtenir le contraire d’une condition : ! (non logique)

A && B vaut vrai (1) <==> A et B sont “vrai simultanément”

A || B vaut vrai (1) <==> A ou B ou les deux sont “vrai”

Exemples

(25 > 36 && 8 > 5)  
 -------
 faux (0) et "n’importe quoi"
 ----------------------------
           faux (0)
(3 <= 3 && 4 >= 2.5)
 ------
 vrai (1)
           --------
           vrai (1)
        et
 ------------------
      vrai (1)

Écriture et lecture en mode conversationnel

En mode conversationnel (interactif), on affiche les informations à l’écran et on saisit les données tapées au clavier par l’usager du programme.

Affichage à l’écran avec printf
printf("format", liste d'informations à afficher);

où :

  1. printf désigne l’écriture (print : imprimer, ici dans le sens d’afficher, f vient du mot format (de présentation)).

  2. format désigne des messages à afficher tels quels et des codes formats pour afficher des informations de type différents :

%d pour un entier

%f pour un réel

%c pour un caractère

%s pour une chaîne de caractères (plus tard dans le cours)

etc.

Dans le format, on rencontre très souvent les caractères \n qui provoquent un changement de ligne (new line).

Dans les exemples d’affichage, on utilise le symbole ^ (chapeau) pour représenter une espace (un blanc).

Exemples

Avec les déclarations et les affectations suivantes :

int nbCours, nbCredits;
float moyenne;
char  categorie;

nbCours = 5;
nbCredits = 3;
moyenne = 82.5;
categorie = 'E';
  1. printf("%d%d", nbCours, nbCredits);

fait afficher : 53 (les 2 entiers sont collés)

  1. printf("%3d%4d", nbCours, nbCredits);

fait afficher : ^^5^^^3

3 espaces pour afficher l’entier nbCours (valeur 5)

4 espaces pour afficher l’entier nbCredits (valeur 3)

  1. printf("Nombre de cours = %3d, Nombre de credits = %4d", nbCours, nbCredits);

fait afficher :

Nombre de cours = ^^5, Nombre de credits = ^^^3
printf("Nombre de cours   : %4d\n", nbCours);

printf("Nombre de credits : %4d\n", nbCredits);`

fait afficher :

Nombre de cours   : ^^^5
Nombre de credits : ^^^3
printf("%f%f%6.3f%8.2f", moyenne, moyenne, moyenne, moyenne);`

fait afficher :

82.50000082.500000^82.500^^^82.50

(par défaut, on a 6 chiffres après le point décimal).

Comme auparavant, on encourage la manière suivante :

printf("La moyenne de l'etudiant : %5.2f pourcent\n", moyenne);

qui fait afficher :

La moyenne de l’etudiant : 82.50 pourcent

  1. printf("%c%3c%5c\n", categorie, categorie, categorie);

fait afficher : E^^E^^^^E

  1. En résumé, la suite des instructions suivantes :
printf("Les informations de l'etudiant :\n\n");
printf("  - categorie : %5c\n", categorie);
printf("  - cours     : %5d cours\n", nbCours);
printf("  - moyenne   : %5.2f pourcent\n", moyenne);
printf("  - credits   : %5d credit(s)\n", nbCredits);

fait afficher :

Les informations de l’etudiant :

  • categorie : ^^^^E

  • cours : ^^^^5 cours

  • moyenne : 82.50 pourcent

  • credits : ^^^^3 credit(s)

Warning

Attention :

Voici comment on répartit une longue instruction qui contient un long message sur plus d’une ligne :

printf("La commande contient %d articles pour un total de %6.2f $ "
       "avec des frais de livraison de %5.1f $\n", nbArticles, total, frais);

Nous reviendrons plus tard sur les autres détails de printf.

Lecture de données avec scanf

scanf("codes format", liste des adresses des variables à lire);

Nous utilisons l’opérateur & (adresse de) qui sera présenté en détail au prochain chapitre. Pour les deux premières semaines de cours, on interprète une saisie de donnée :

printf("Entrez le nombre de credits : ");
scanf("%d", &nbCredits);

Comme ceci :

  • Lire un entier tapé au clavier par l’usager;

  • Déposer cet entier à l’adresse de la variable nbCredits.

et on essaie de comprendre avec le simple exemple suivant :

un facteur peut livrer une lettre chez-nous s’il connaît notre adresse;

(un compilateur peut déposer une valeur lue dans une variable s’il connaît son adresse).

Exemples

  1. Lecture d’un seul entier ou d’un seul réel
printf("Entrez le nombre de credits : ");
scanf ("%d", &nbCredits);

On lit la valeur et on la dépose à l’adresse de la variable nbCredits (à son emplacement en mémoire).

Après le message d’incitation “Entrez le nombre de credits : “, l’usager peut taper le nombre (avec ou sans espaces) suivi de la touche <Entrée> :

Entrez le nombre de credits : ^^^^^3
nbCredits vaut 3

Entrez le nombre de credits : 3
nbCredits vaut aussi 3
printf("Entrez la moyenne de l'etudiant : ");
scanf("%f", &moyenne);

Après le message “Entrez la moyenne de l’etudiant : “, si l’usager tape ^^^82.5 suivi de la touche <Entrée>, moyenne vaut 82.5

  1. Lecture des valeurs numériques
printf("Entrez le nombre de credits et la moyenne : ");
scanf("%d%f", &nbCredits, &moyenne);

Après le message “Entrez le nombre de credits et la moyenne : “, il suffit de taper 2 valeurs séparées par au moins une espace suivie de la touche <Entrée> :

Entrez le nombre de credits et la moyenne : 3^82.5

nbCredits vaut 3 et moyenne vaut 82.5.

  1. Lecture d’un caractère
printf("Entrez e, E, p ou P pour la categorie :");
scanf("%c", &categorie);

Après le message “Entrez e, E, p ou P pour la categorie :”, on tape tout de suite le caractère suivi de la touche <Entrée> :

Entrez e, E, p ou P pour la categorie :e
categorie vaut 'e'

Par contre :

Entrez e, E, p ou P pour la categorie :^e
categorie vaut ' ' (caractère espace)

On utilise souvent getchar() pour la lecture d’un seul caractère :

printf("Entrez e, E, p ou P pour la categorie :");
categorie = getchar(); /* avec écho (on voit le caractère tapé) */
  1. Lecture de plusieurs informations
printf("Entrez categorie, nombre de credits et moyenne :");
scanf("%c%d%f", &categorie, &nbCredits, &moyenne);
Avec : Entrez categorie, nombre de credits et moyenne :e^3^82.5
categorie vaut 'e', nbCredits vaut 3 et moyenne vaut 82.5

Instructions de base en langage C

Instruction simple

Une seule instruction qui réalise un traitement : une lecture, une écriture, une affectation, etc . On doit terminer une instruction simple par le point virgule ;.

Exemples

printf("Entrez le rayon d'un cercle :");
scanf("%f", &rayon);

surface = 3.14159 * rayon * rayon;

Instruction composée

  • Un bloc d’instructions séparées les unes des autres (très souvent) par un point virgule et délimitées par { (début) et } (fin)

  • On recourt souvent à une instruction composée lorsqu’on souhaite réaliser deux actions ou plus sous une condition (vrai ou faux).

Exemple

if (categorie == 'E' || categorie == 'e'){
    printf("C'est un etudiant");
    nbEtudiants = nbEtudiants + 1 ;
} else {
    printf("C'est un professeur");
    somMoyenne = somMoyenne + moyenne;
    nbProfs = nbProfs + 1;
}

Instructions de sélection (de décision)

La sélection simple

  1. Syntaxe
if (condition)
  instruction 1
else
  instruction 2	

ou

if (condition)
  instruction 1
  1. Fonctionnement

Si la condition vaut vrai (c’est-à-dire, en langage C, sa valeur est non nulle), on exécute l’instruction 1. Dans le cas contraire (sinon), et si la clause else est présente, on effectue l’instruction 2.

  1. Remarques
  • La clause else est facultative (optionnelle)

  • La condition (l’expression) doit être entre parenthèses

  • Le then (alors) n’existe pas comme en PASCAL ou en Visual Basic

  • L’instruction sous le if (instruction 1) et l’instruction sous le else (instruction 2) peuvent être simples (une seule action), structurées (une autre instruction de contrôle) ou composées (bloc d’instructions). Si c’est une instruction simple, il faut la terminer par le point virgule (même si elle se trouve devant la clause else).

  1. Exemples

a)

if (note < 60)
   printf("Echec\n");
else
   printf("Reussite\n");

b)

if (categorie == 'e' || categorie == 'E')
  nbEtudiants = nbEtudiants + 1;

c)

if (categorie == 'p' || categorie == 'P'){
  nbProfs = nbProfs + 1;
  printf("categorie : Professeur\n");
} else {
  nbEtudiants = nbEtudiants + 1;
  printf("categorie : Etudiant\n");
  somMoyenne = somMoyenne + moyenne;
}

d) Cas de if imbriqué (if à l’intérieur d’un autre if) :

if (programme == 'I'){
    bonus = 123.45;
    printf("informatique\n");
} else if (programme == 'G'){
    nbGenie = nbGenie + 1;
    printf("genie\n");
    totMoyGenie = totMoyGenie + moyenne;
} else
    printf("Autre programme\n");

e) Exercices

Soient les déclarations suivantes :

int  humidite;
char saison;

Écrire une instruction permettant de vérifier s’il fait un temps lourd (saison : été, humidité : entre 80 et 100).

Solution :

if ((saison == 'e' || saison == 'E') &&
    (humidite >= 80 && humidite <= 100))
    printf("Temps lourd");

Écrire une instruction permettant de vérifier si une journée d’hiver est très sèche (humidité inférieure à 30).

Solution :

if ((saison == 'h' || saison == 'H') && humidite < 30)
    printf("Journee d'hiver tres seche");

Écrire une instruction permettant de vérifier si l’air est saturé (humidité supérieure ou égale à 90). Dans ce cas, on affiche des messages du genre :

Air sature avec une humidite de 95

saison : ete

Dans le cas contraire, on affiche un message pertinent.

Solution :

if (humidite >= 90){
   printf("Air sature avec une humidite de %d\n", humidite);
   if (saison == 'e' || saison == 'E')
      printf("saison : ete\n");
   else
      printf("saison : hiver\n");
} else
   printf("L'air n'est pas sature\n");

Écrire des instructions permettant d’afficher des messages du genre :

Temps sec en ete ou

Temps humide en hiver ou

Temps tres humide en ete

Solution :

if (humidite < 40)
   printf("Temps sec ");
else if (humidite < 80)
   printf("Temps humide ");
else 
   printf("Temps tres humide ");

if (saison == 'e' || saison == 'E')
   printf("en ete");
else
   printf("en hiver");

Exercice

Écrire un bloc d’instructions permettant de saisir le niveau d’une cote de qualité de l’air (le niveau 1 représente le meilleur air, le niveau 2 le suivant, …) et d’afficher un message du genre :

Air de bonne qualite                (niveaux 2 à 5)

Air a surveiller                    (niveau 6)

Excellente qualite ou alerte!       (niveaux 1 et 7)

Niveau invalide!                    (pour un niveau imprévu)

La donnée du problème est la variable niveau (de type entier) tandis que le résultat est un message qui dépend de la valeur de niveau (voir ci-dessus)

Cheminement :

   Lire niveau

   Si (niveau >= 2 et niveau <= 5) Alors
      Afficher "Air de bonne qualite"
   Sinon
      Si (niveau == 6) Alors
          Afficher "Air a surveiller"
      Sinon
         Si (niveau == 1 ou niveau == 7) Alors
            Afficher "Excellente qualite ou alerte!"
         Sinon
            Afficher "Niveau invalide!"

Le code en langage C

/*  Auteurs : Charbonneau Julien, Section C et 
               Dube Renée, Section D

     Date : 13 septembre 2024 pour le cours IFT 1810

     But : Ce programme permet de saisir le niveau d'une cote de
           qualité de l'air et d'afficher un message pertinent
           selon la valeur du niveau saisi
*/

#include <stdio.h>

int main() {
   int niveau; /* le niveau de la cote (1 : excellent, 2 : tres bon, ...,        
                  7 : alerte)*/

   /* Saisir le niveau */
   printf("Entrez le niveau de qualite de l'air (entre 1 et 7) : ");
   scanf("%d", &niveau);



   /* afficher un message pertinent : */
   if (niveau >= 2 && niveau <= 5)          /* niveaux 2 à 5 */
      printf("Air de bonne qualite");
   else 
     if (niveau == 6) /* niveau 6 */
      printf("Air a surveiller");
     else 
         if (niveau == 1 || niveau == 7) /* niveau 1 ou 7 */
            printf("Excellente qualite ou alerte!");
         else /* dans le sens autrement */
            printf("Niveau invalide!");
   
   printf("\n\n");
   
   system("pause");
   
   return 0;
}

Exécution :

Entrez le niveau de qualite de l'air (entre 1 et 7) : 5
Air de bonne qualite

Appuyez sur une touche pour continuer...

La sélection multiple avec switch … :

  1. Syntaxe : cette instruction est semblable à Select Case … en Visual Basic.
switch (expression){
   case valeur1:
      instructions1;
      break;

   case valeur2:
      instructions2;
      break;
...

   case valeurn:
      instructionsn;
      break;

   default:
      instructionsn+1;
      break;
}

Le switch permet de construire une table de branchement à partir d’une expression. Il remplace avantageusement une suite de if imbriqués.

L’expression expression est évaluée, puis elle branche directement sur le bon cas case s’il est défini. Les valeurs valeur1, valeur2,… , valeurn, doivent être des valeurs de type entier ou de type caractère. Si le branchement est trouvé, les énoncés qui suivent le case seront exécutés. Le mot réservé break signale la fin de la série d’énoncés à exécuter pour un case particulier et force, du même coup, la fin de l’instruction switch. Si le résultat de l’expression ne correspond à aucun branchement, les instructions correspondant au branchement default, s’il existe, seront exécutées.

Il est possible d’accepter plus d’une valeur pour une même série d’instructions, sans réécrire ceux-ci. On écrit tout simplement les autres case à la suite du premier, comme ceci :

case valeur1:
case valeur2: instructions;
    break;

Ici, les instructions sont exécutées lorsque l’expression est égale à valeur1 ou à valeur2.

Exemple :

char  programme;
float credits;
.....
switch (toupper(programme)){ /* suivant que le programme vaut  */
   case 'I': credits = 90.0;
             printf("informatique\n");
             break;
   case 'S':
   case 'G': credits = 120.0;
             break;
   case 'L': credits = 60.0;
             printf("Lettres\n");
             break;
   default:  printf("programme errone\n");
}
  1. Fonctionnement

L’expression suivant switch est évaluée; sa valeur vaut x, par exemple;

On cherche dans le bloc s’il existe une étiquette de la forme case xx est la valeur de l’expression :

  • Si oui :

On exécute les instructions à partir de ce cas jusqu’à ce qu’on rencontre :

  1. Un break (on sort du bloc et on termine le switch)

  2. La fin du switch

Après avoir exécuté ces instructions, on quitte le switch.

  • Si non :

Si la clause default (qui signifie “autrement”) est présente, on effectue la suite d’instructions sous cette clause et on quitte le switch.

Si la clause default n’existe pas, on termine le switch.

  1. Remarques
  • L’expression dans switch(expression) est une expression entière. Le cas d’un caractère est accepté car le compilateur convertit un caractère en entier (son ordre).

  • La suite d’instructions peut être vide : aucune instruction.

  • Pour sortir de switch, après avoir effectué des instructions voulues, ne pas oublier de terminer avec un break. Si oublié, toutes les suites d’intructions suivantes seront exécutées jusqu’à la rencontre d’un break ou la fin de switch.

  • La clause default est facultative.

  1. Exemples

Exemple 1 (deuxième solution de l’exercice précédent)

int niveau;
printf("Entrez le niveau de qualite de l'air (entre 1 et 7) :");
scanf("%d", &niveau);

switch (niveau){
            /* niveaux 2 à 5 : */
    case 2:
    case 3:
    case 4:
    case 5: printf("Air de bonne qualite\n");
            break;
           /* niveau 6 : */
    case 6: printf("Air a surveiller\n");
            break ;
           /* niveau 1 ou 7 : */
    case 7:
    case 1: printf("Excellente qualite ou alerte!\n");
            break ;
           /* autrement : */
    default: printf("Niveau invalide!\n");
         }

Exemple 2

Un écocentre rachète les matériaux rapportés par les citoyens : 0.50 $ le kilo pour l’aluminium, 0.40 $ le kilo pour le verre et le plastique, et 0.375 $ le kilo pour le carton.

Écrire un programme en langage C permettant :

  • D’obtenir la masse rapportée (en kilos)

  • D’obtenir le code du matériau, soit un seul caractère :

    • ‘A’ ou ‘a’ pour aluminium

    • ‘V’ ou ‘v’ pour verre

    • ‘P’ ou ‘p’ pour plastique

    • ‘C’ ou ‘c’ pour carton

  • De calculer le montant à verser selon le matériau

  • D’afficher à l’écran un message du genre :

C’est du plastique de 12.50 kilo(s) qui rapporte 5.00 $.

Solution :

#include <stdio.h>
#include <ctype.h>  /* pour la conversion en majuscule : 
                       toupper(...) : to (en) upper (majus)*/

void main()
{
   char  materiau;
   float montant, masse;

   #define TARIF_A  0.500  /* tarif pour l'aluminium       */
   #define TARIF_VP 0.400  /* tarif pour le verre          */
                           /* ou le plastique              */
   #define TARIF_C  0.375  /* tarif pour le carton         */

   printf("Entrez le code du materiau et la masse en kilos : ");
   scanf ("%c%f", &materiau, &masse);

   materiau = toupper(materiau);
   printf("C'est du ");

   switch (materiau){
     case 'A': montant = masse * TARIF_A;
               printf("aluminium ");
               break;
     case 'P':
     case 'V': montant = masse * TARIF_VP;
               if (materiau == 'P')
                  printf("plastique ");
               else
                  printf("verre ");
               break;
     case 'C': montant = masse * TARIF_C;
               printf("carton ");
   }

   printf("de %6.2f kilo(s) qui rapporte %6.2f $ \n", masse, montant);
}
  1. Exercices

Numéro 1 (niveau simple)

Écrire un programme permettant de saisir un caractère représentant le code d’un solide :

  • ’s’ ou ‘S’ pour une sphère

  • ‘b’ ou ‘B’ pour une boîte (pavé droit)

  • ‘k’ ou ‘K’ pour un cube

Dans le cas d’une sphère, le programme saisit son rayon. Il effectue les calculs et affiche les résultats à l’écran :

  • Le volume (4/3 x PI x (rayon au cube)) et

  • La surface (4 x PI x (rayon au carré))

Dans le cas d’une boîte, le programme saisit la longueur, la largeur et la hauteur. Il effectue les calculs et affiche les résultats à l’écran :

  • Le volume (longueur x largeur x hauteur)

  • La surface (2 x (longueur x largeur + longueur x hauteur + largeur x hauteur))

Dans le cas d’un cube, le programme saisit l’arête. Il effectue les calculs et affiche les résultats à l’écran :

  • Le volume (arête au cube)

  • La surface (6 x (arête au carré))

Si le code est imprévu, nous affichons un message pertinent.

Numéro 2 (bon exercice de révision)

Écrire un programme en langage C permettant de saisir le numéro d’un forfait de vélo en libre-service (1 à 5) et d’afficher la durée incluse dans le forfait. Lorsqu’il s’agit du forfait « à la minute » (le numéro 2), on saisit en plus le nombre total de minutes utilisées afin de l’exprimer en heures et minutes, et de signaler un éventuel dépassement.

Notez que :

  • Les forfaits 1, 3 et 5 (journée, semaine, saison) donnent un accès illimité.

  • Les forfaits 4 (demi-journée) donnent 4 heures incluses.

  • Pour le forfait à la minute, à partir du nombre total de minutes, on calcule :

Soit min le total de minutes saisi. Le nombre d’heures complètes vaut heures = min / 60 (division entière) et le nombre de minutes restantes vaut reste = min % 60.

Un dépassement est facturé <===> (le total dépasse 120 minutes) c’est-à-dire (min > 120).

Exemples : min = 135 ==> heures = 2 et reste = 15

La condition : 135 est supérieur à 120 est vérifiée. Il y a donc un dépassement de durée.

min = 90 ==> heures = 1 et reste = 30. La condition : 90 n’est pas supérieur à 120; il n’y a aucun dépassement.

#include <stdio.h>
 /*********************************************************************
  *  Auteurs : Gagnon Sophie, Section C et                            * 
  *            Lemieux Antoine, Section D                             *
  *                                                                   *
  *  Date : 1 septembre 2024 pour le cours IFT 1810                   *
  *                                                                   *
  *  But : Ce programme permet de saisir le numero d'un forfait de    *
  *        velo et d'afficher la duree incluse. Pour le forfait a la  *
  *        minute, on saisit aussi le nombre de minutes et on le      *
  *        convertit en heures et minutes en signalant un depassement *
  *********************************************************************/

int main()
{
   int forfait;  /* le numero du forfait */
   int min,      /* total de minutes utilisees, exemple 135 */
   heures,       /* nombre d'heures completes, exemple 2 */
   reste;        /* minutes restantes, exemple 15 */

   /* saisir le numero du forfait */
   printf("Entrez le numero d'un forfait (entre 1 et 5) : ");
   scanf("%d", &forfait);

   printf("\nSolution avec if ...... : \n");

   printf("Le forfait numero %d ", forfait);

   if (forfait == 1 || forfait == 3 || forfait == 5) 
      printf("donne un acces illimite ");
   else if (forfait == 4)
      printf("inclut 4 heures");
   else if (forfait == 2){
      printf("est a la minute. On a besoin de la duree\n");
      printf("Entrez le nombre de minutes (exemple 135) : ");
      scanf("%d", &min);

      heures = min / 60;
      reste = min % 60;

      if (min > 120)
         printf("Duree de %dh%02d avec depassement facture", heures, reste);
      else
         printf("Duree de %dh%02d sans depassement", heures, reste);

   } else
      printf("n'existe pas!");
   printf("\n\n");

   printf("\nSolution avec switch ...... : \n");

   switch (forfait){
      case 1 :
      case 3 :
      case 5 : printf("acces illimite\n");
               break;
      case 4 : printf("4 heures incluses\n");
               break;

      case 2 :  printf("On a besoin de la duree\n");
                printf("Entrez le nombre de minutes (exemple 135) : ");
                scanf("%d", &min);

                heures = min / 60;
                reste = min % 60;

                if (min > 120)
                   printf("Duree de %dh%02d avec depassement facture", 
                              heures, reste);
                else
                   printf("Duree de %dh%02d sans depassement", 
                              heures, reste);
                break;
      default : printf("Le forfait numero %d est invalide", forfait);
   }
   printf("\n\n");
   
   system("pause");
   return 0; 
}

Exécution:

Entrez le numero d'un forfait (entre 1 et 5) : 2

Solution avec if ...... :
Le forfait numero 2 est a la minute. On a besoin de la duree
Entrez le nombre de minutes (exemple 135) : 90
Duree de 1h30 sans depassement


Solution avec switch ...... :
On a besoin de la duree
Entrez le nombre de minutes (exemple 135) : 135
Duree de 2h15 avec depassement facture

Appuyez sur une touche pour continuer...

Écriture “raccourcie” en langage C

variable = variable operateur opérande;

peut aussi s’écrire ainsi : variable operateur= opérande;

Exemples :

somme = somme + moyenne; //===> somme += moyenne;
n = n / 10;              //===> n /= 10;
  • Incrémentation : nbEtud = nbEtud + 1;

peut aussi s’écrire ainsi: nbEtud += 1; /* voir point précédent */

ou plus court encore : nbEtud++;

  • Décrémentation : nbEtud = nbEtud - 1;

peut aussi s’écrire ainsi: nbEtud -= 1; /* voir point précédent */

ou plus court encore : nbEtud--;

  • D’autres utilisations des opérateurs “++” et “–” seront présentées dans le cours suivant (IFT 1166, suite de IFT 1810).

  • Déclaration et initialisation en même temps :

int   nbEtud = 0, note, nbProfs = 0;
float somMoyenne = 0.0, moyenne;
  • Affectation multiple :
nbEtud = 0;
nbProfs = 0;
Nb_Pers= 0;

peut aussi s’écrire ainsi:

nbEtud = nbProfs = Nb_Pers = 0;

Le type booléen (logique)

Une valeur de type booléen peut être VRAI ou FAUX.

La condition : 27 > 12 vaut VRAI tandis que 12 > 45 vaut FAUX.

En langage C, le type booléen n’existe pas.

Avec :

printf("%d", 27 > 12); le langage C affiche 1.
printf("%d", 12 > 45); le langage C affiche 0.

Ainsi, une condition qui est VRAI vaut un et une condition qui est FAUX vaut zéro.

Par contre, une valeur numérique non nulle est considérée comme VRAI.

Le bloc :

int note = 75;
if (note)  /* Si (note) <==> Si (note est non nul) */
  printf("ABC");
else 
  printf("XYZ");

affiche à l’écran ABC.

On utilise très souvent le type int pour programmer le type booléen.

char categorie;
int  valide;

printf("Entrez e ou p pour la categorie :");
categorie = toupper(getchar());

valide = (categorie == 'E') || (categorie == 'P');

if (!valide)  /* Si Non valide */
   printf("caractere imprevu pour la categorie ");
...

Introduction aux notions d’adresse

Une variable a un nom (son identificateur), un type et une valeur. Avec la déclaration suivante :

int note = 87;

note est le nom d’une variable de type entier dont la valeur est 87. Dépendant du type de la variable, le compilateur réserve un nombre d’octets (bytes) pour mémoriser l’information. L’opérateur sizeof (taille de …, nombre d’octets de …) permet de calculer le nombre d’octets nécessaires pour mémoriser une variable ou une information d’un type donné. Dans notre environnement Windows XP, et sous Microsoft Visual C++ :

  • sizeof(int) ou sizeof(note) vaut 4 (note est de type int)

  • sizeof(float) ou sizeof(moyenne) vaut 4 (moyenne est de type float)

  • sizeof(char) ou sizeof(categorie) vaut 1 (categorie est de type char)

Chaque octet a une adresse en mémoire :

Mémoire Mémoire

En langage C, on ajoute une caractéristique de plus à une variable : son adresse (son emplacement en mémoire) déterminée par l’opérateur & (adresse de). C’est l’adresse du premier octet du bloc d’octets qui mémorise la valeur de cette variable.

L’adresse d’une variable est déterminée souvent à la compilation de manière séquentielle.

Exemple d’illustration des adresses

Soit le programme suivant :

/* Fichier Adresse.C (introduction aux adresses)
Dans ce programme, on affiche une adresse avec le code format %u, "u" pour "unsigned integer" : entier sans signe (positif) : entre 0 et 65535. Ce format en valeur de décimale rend facile des explications (le format %p donne l'adresse en hexadécimal) 
 */

#include <stdio.h>

int          a = 5, b = 23;
float        x = 123.4;
char         d = 'V';
int          c = 100;
double       moyenne  = 82.75;

int main()
{
  printf("Nom            Type     Nb. octets  Adresse   Valeur\n");
  printf("------         -----    ----------  -------   ------\n");
  printf(" a             int           %d      %u   %d\n", sizeof(a), &a, a);
  printf(" b             int           %d      %u   %d\n", sizeof(b), &b, b);
  printf(" x             float         %d      %u   %6.2f\n",sizeof(x), &x, x);
  printf(" d             char          %d      %u   %c\n",sizeof(char), &d, d);
  printf(" c             int           %d      %u   %d\n", sizeof(int), &c, c);
  printf(" moyenne       double        %d      %u   %6.2f\n", sizeof(moyenne), &moyenne, moyenne);
  
  printf("\n\nL'operateur * (contenu de l'adresse) :\n");
  printf("Le contenu a l'adresse %u est %d\n", &b, *(&b));
  printf("Le contenu a l'adresse %u est %6.2f\n", &x, *(&x));
  
  printf("\n\n");
  system("pause");
  
  return 0;
}

Exécution :

Nom            Type     Nb. octets  Adresse   Valeur
------         -----    ----------  -------   ------
 a             int           4      4202496   5
 b             int           4      4202500   23
 x             float         4      4202504   123.40
 d             char          1      4202508   V
 c             int           4      4202512   100
 moyenne       double        8      4202520    82.75


L'operateur * (contenu de l'adresse) :
Le contenu a l'adresse 4202500 est 23
Le contenu a l'adresse 4202504 est 123.40


Appuyez sur une touche pour continuer...

Schéma d’explication

La case d’un octet dispose d’une adresse en mémoire. Dépendant du type de la variable, le compilateur alloue un nombre de cases (dans notre environnement de travail : 4 cases pour un entier, 4 pour un réel, 1 pour un caractère, etc.).

Les valeurs sont codées en binaire. Pour une meilleure compréhension, on les représente ici comme des valeurs usuelles (entier, réel, caractère). Veuillez remarquer que le premier octet de chaque variable est un multiple de 4 (plus facile pour obtenir l’adresse d’une information car 4 fois 8 = 32 bits)

Mémoire2 Mémoire2

On voit aussi l’opérateur * dont :

*(adresse) <===> le contenu (la valeur) qui se trouve à cette adresse

Ainsi : *(&b) <==> le contenu à l’adresse 1245048 <==> 23 (valeur de b)

*(&x) <==> le contenu à l’adresse 1245044 <==> 123.40 (valeur de x)

Veuillez noter que ces informations ne sont pas à évaluer pour IFT 1810.

Elles vous permettent d’avoir une petite idée sur la notion de l’adresse et plus tard, dans certains autres cours, la notion de pointeur.

On revient maintenant à la lecture de données réalisée lors de la première semaine :

printf("Entrez la valeur de b :");
scanf("%d", &b);

On interprète scanf("%d", &b); comme suit :

Lire la valeur tapée et déposer cette valeur à l’adresse 1245048 (l’adresse de b) ===> b vaut la valeur saisie.

Exercices de révision

Exercice 1

Écrire les déclarations qui rendent valide les instructions suivantes :

printf("Entrez un type d'abonnement :");
abonnement = getchar();

mensuel = abonnement == 'm' || abonnement == 'M';

annuel = toupper(abonnement) == 'A';

Solution :

#include <ctype.h> /* pour appeler toupper to upper : en majuscule */
. . . 
char abonnement;

/* En langage C, on utilise souvent le type int (entier) pour remplacer
   le type booléen */
int mensuel, annuel;

Exercice 2

Que fait afficher la suite d’instructions ci-dessous?

int  zone = 13;
switch (zone){
   case  5: printf("zone 5 ");
            break ;
   case  7:
   case 13:
   case  9: printf("zone 7, 13 ou 9 ");
   default: printf("autres zones ");
}

Solution :

zone 7, 13 ou 9 autres zones