Les pièges du langage C

Documents pareils
1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.


Introduction au langage C

Algorithmique et Programmation, IMA

Chap III : Les tableaux

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Programmation en langage C

Bases de programmation. Cours 5. Structurer les données

Le langage C. Séance n 4

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr

Rappels Entrées -Sorties

Claude Delannoy. 3 e édition C++

Le prototype de la fonction main()

Algorithmique & Langage C IUT GEII S1. Notes de cours (première partie) cours_algo_lgc1.17.odp. Licence

Java Licence Professionnelle CISII,

Cours d Algorithmique et de Langage C v 3.0

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Programmation en langage C d un µcontrôleur PIC à l aide du compilateur C-CCS Sommaire

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année

Programmation C++ (débutant)/instructions for, while et do...while

Cours de C. Petits secrets du C & programmation avancée. Sébastien Paumier

Les structures de données. Rajae El Ouazzani

INITIATION A LA PROGRAMMATION

Algorithmes et Programmes. Introduction à l informatiquel. Cycle de vie d'un programme (d'un logiciel) Cycle de vie d'un programme (d'un logiciel)

Introduction à l algorithmique et à la programmation M1102 CM n 3

Introduction au Langage de Programmation C

as Architecture des Systèmes d Information

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Notions fondamentales du langage C# Version 1.0

Les structures. Chapitre 3

Plan du cours. Historique du langage Nouveautés de Java 7

SUPPORT DE COURS. Langage C

Le Langage C Licence Professionnelle Qualité Logiciel Pr. Mouad BEN MAMOUN ben_mamoun@fsr.ac.ma Année universitaire 2011/2012

Langage Éric Guérin 5 octobre 2010

Langage C. Patrick Corde. 22 juin Patrick Corde ( Patrick.Corde@idris.fr ) Langage C 22 juin / 289

I. Introduction aux fonctions : les fonctions standards

Outils pour la pratique

INF111. Initiation à la programmation impérative en C amini/cours/l1/inf111/ Massih-Reza Amini

Le langage C. Introduction, guide de reference

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Programmation en C. École Nationale Supérieure de Techniques Avancées. Pierre-Alain Fouque et David Pointcheval

Conventions d écriture et outils de mise au point

Programmation système I Les entrées/sorties

V- Manipulations de nombres en binaire

Programmation C. J.-F. Lalande. 15 novembre 2012

Chapitre 1 : La gestion dynamique de la mémoire

Initiation. àl algorithmique et à la programmation. en C

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

Programmation Classique en langage C

Programmer en JAVA. par Tama

Utilisation d objets : String et ArrayList

INF 321 : mémento de la syntaxe de Java

Langages et Concepts de Programmation Introduction à la programmation en langage C

Notes du cours 4M056 Programmation en C et C++ Vincent Lemaire et Damien Simon

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

UE C avancé cours 1: introduction et révisions

Brefs rappels sur la pile et le tas (Stack. / Heap) et les pointeurs

Cours Informatique Master STEP

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

Archivage Messagerie Evolution pour usage HTML en utilisant Hypermail

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

UE Programmation Impérative Licence 2ème Année

Compression de Données - Algorithme de Huffman Document de Conception

MICROINFORMATIQUE NOTE D APPLICATION 1 (REV. 2011) ARITHMETIQUE EN ASSEMBLEUR ET EN C

Cours de programmation avancée. Le langage C. Université du Luxembourg

ALGORITHMIQUE ET PROGRAMMATION En C

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

OS Réseaux et Programmation Système - C5

TP2 : tableaux dynamiques et listes chaînées

3IS - Système d'exploitation linux - Programmation système

Algorithmique, Structures de données et langage C

Travaux pratiques. Compression en codage de Huffman Organisation d un projet de programmation

Cours Programmation Système

Introduction à MATLAB R

Programmation système de commandes en C

#include <stdio.h> #include <stdlib.h> struct cell { int clef; struct cell *suiv; };

Cours d initiation à la programmation en C++ Johann Cuenin

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Méthodes de programmation systèmes UE n NSY103. Notes de cours. Nombre d'heures : 55h (~ cours de 3 heures)

Programmation en Java IUT GEII (MC-II1) 1

Anis ASSÈS Mejdi BLAGHGI Mohamed Hédi ElHajjej Mohamed Salah Karouia

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Représentation d un entier en base b

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

Initiation à l algorithmique

Derrière toi Une machine virtuelle!

Premiers Pas en Programmation Objet : les Classes et les Objets

Les fichiers. Chapitre 4

Aide mémoire UML & Java 1ère partie : Introduction. marc.lemaire@u-cergy.fr

STAGE IREM 0- Premiers pas en Python

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

INF 104 (SELC) Introduction au langage C

COMPARAISONDESLANGAGESC, C++, JAVA ET

Transcription:

Analyse et programmation 1 Les pièges du langage C 1

Thèmes abordés Les pièges? Une petite collection de pièges Est-il possible d écrire un programme fonctionnel en C? Référence utilisée : «Les pièges du langage C», Andrew Koenig 2

Les pièges De quoi s agit-il? Principe du piège Semble attrayant et rassurant au premier abord. Cause quelques soucis quand on s est fait prendre. En programmation Un élément de code source qui semble tout à fait juste Même à la dixième relecture. Mais qui ne fonctionne pas. A cause d un détail de syntaxe quasiment invisible. 3

Les pièges Comment s en protéger? Pour les souris Eviter les pièges Se nourrir dans des zones non fréquentées par les humains. Vérifier l absence de piège : tester le bout de fromage. Attendre qu une autre souris y ait goûté. Limites de la méthode Le piège ne se déclenche pas à tous les coups. En programmation Eviter les pièges Utiliser des instructions ayant peu de risques de pièges. Vérifier l absence de piège Apprendre à les reconnaitre. Programmer très attentivement pour les éviter. Tester rigoureusement le code. 4

Les pièges du préprocesseur Les espaces jouent un rôle prépondérant dans les définitions de macros #include <stdio.h> #include <stdlib.h> #define f (x) x + 1 Espace après f : f est une macro sans paramètres! Message d erreur généré ici : Identificateur x non déclaré printf("resultat:%d\n", f(1)); Résolution Vigilance particulière dans les définitions de macros. Être toujours prêt à mettre en doute le code généré par macro. 5

Les pièges du préprocesseur Les macros ne sont pas des fonctions (1/2) #include <stdio.h> #include <stdlib.h> #define ABS(x) (x >= 0? x : -x) printf("resultat:%d\n", ABS(5-8)); Toujours bien parenthéser les macros. Expansion de ABS(5 8): (5 8 >= 0? 5 8 : -5 8) Résultat inattendu : -13 6

Les pièges du préprocesseur Les macros ne sont pas des fonctions (2/2) #define ABS(x) ((x) >= 0? (x) : -(x)) int i = 5; printf("resultat:%d\n", ABS(++i)); Penser qu une macro n est pas une fonction. Expansion de ABS(++i): ((++i) >= 0? (++i) : -(++i)) Résultat inattendu : 7 Les arguments peuvent être évalués plusieurs fois! 7

Les pièges du préprocesseur Les macros ne sont pas des instructions #define rendre_positif(x) if (x < 0) x = -x int i = 5; if (i < 0) rendre_positif(i); else Expansion : if (i < 0) if (i < 0) i = -i; else printf("i est deja positif\n"); printf("i est deja positif.\n"); Résultat inattendu : Cette instruction printf n est jamais exécutée! Eviter ce genre de macros. Préférer les fonctions. 8

Les pièges du préprocesseur Les macros ne sont pas des définitions de type #define PCHAR char * Expansion : char * texte1, texte2; PCHAR texte1, texte2; texte1 = "Hello"; texte2 = "World!\n"; printf(texte1); printf(texte2); Résultat inattendu : texte2 contient un char, et non pas l adresse d un texte. Erreur fatale à l exécution! Utiliser typedef plutôt que les macros pour créer des types. 9

Les pièges lexicaux Le plus répandu #include <stdio.h> #include <stdlib.h> char c; L opérateur d affectation est utilisé à la place de la comparaison do c = getchar(); while (c == ' ' c = '\t' c == '\n'); Être très vigilant. Placer les constantes à gauche. Certains compilateurs peuvent émettre un Warning. Résultat inattendu : boucle sans fin! 10

Les pièges lexicaux Le plus sournois L opérateur donne ici l impression de fonctionner comme int i; i = 0; if (i++ > -10 i++ < 10) printf("resultat:%d\n", i); i = 0; if (i++ > -10 i++ < 10) printf("resultat:%d\n", i); Différence sournoise : même si cela fonctionne dans ce cas, avec, les deux opérandes sont toujours évalués! Bien connaître la syntaxe des opérateurs bit à bit et logiques. 11

Les pièges lexicaux Combinaison d opérateurs déroutante #include <stdio.h> #include <stdlib.h> int i = 1, j = 10, k; k = i---j; printf("i:%d, j:%d, k:%d\n", i, j, k); i---j est interprété comme (i--) - j Penser que l analyse lexicale du C est gloutonne. Eviter d utiliser des formes ambigües. Quel sera le résultat? i = 0, j = 10, k = -9 ou i = 1, j = 9, k = -8 12

Les pièges lexicaux Les constantes entières #include <stdio.h> #include <stdlib.h> Mathématiquement, dans le système décimal, 123 et 0123 désignent le même nombre. int i = 123, j = 0123; printf("i:%d, j:%d\n", i, j); En langage C, une constante qui commence par 0 est considérée en base octale. Donc 123!= 0123 Connaissances rigoureuses des conventions du C requises. 13

Les pièges lexicaux Les constantes caractère et chaînes de caractères #include <stdio.h> #include <stdlib.h> printf("hello World!%s", '\n'); printf('\n'); Certains compilateurs émettent un warning pour le 2 ème cas. Très grande rigueur nécessaire. Un caractère est passé au lieu d une chaîne de caractère. Résultat : affichage incorrect ou plantage du programme 14

Les pièges syntaxiques Les priorités des opérateurs s int registre, masque; registre = 0x80; masque = 0x80; if (registre & masque!= 0) printf("le bit b7 du registre est a 1\n"); else printf("le bit b7 du registre est a 0\n"); User et abuser des parenthèses. On pourrait penser que ce test fait un et bit à bit de registre et masque, et teste si le résultat est différent de 0. Attention, l opérateur!= est prioritaire. Résultat, ce programme affiche à tort que le bit b7 est à 0 15

Les pièges syntaxiques Les structures de contrôle qui ne fonctionnent plus int i; i = 100; if (i < 0); printf("i est negatif.\n"); while (i > 0); i--; Ce programme semble correct. Ce programme affiche que i est négatif. Puis il boucle à l infini. Seule une rigueur extrême permet d éviter ces problèmes. 16

Les pièges syntaxiques L instruction switch char reponse; printf("voulez vous vraiment effacer ce fichier (o:oui, n:non)? "); reponse = getchar(); switch (reponse) default: printf("reponse incorrecte.\n"); case 'n': printf("operation abandonnee.\n"); case 'o': EraseFile("ListeClient.txt"); printf("le fichier a été efface.\n"); Toujours penser switch => break. Ce programme a une structure bien lisible, mais il manque les break. Résultat inattendu : Le fichier sera effacé quelle que soit la réponse! 17

Les pièges syntaxiques Les appels de fonction char reponse; reponse = getchar; switch (reponse) default: printf("reponse incorrecte.\n"); break; case 'n': printf("operation abandonnee.\n"); break; case 'o': EraseFile("C:\listeClient.txt"); printf("fichier effacé.\n"); break; Ce programme semble correct. Mais il manque () pour l appel de getchar. Résultat inattendu : La réponse n est pas saisie. Elle dépend de l adresse de getchar! Certains compilateurs génèrent un warning. Activer tous les warning possibles. Rigueur, toujours! 18

Les pièges syntaxiques Le else qui pend #include <stdio.h> #include <stdlib.h> int x, y, z; if (x == 0) if (y == 0) printf("erreur.\n"); else z = y / x; printf("z:%g\n", z); User des accolades à la moindre ambigüité. Toujours s interroger à propos du else après un if. Contrairement à ce que la présentation laisse imaginer, ce else se rapporte au 2 ème if. Résultat inattendu : si x vaut 0 et y différent de 0, il y a une division par zéro! 19

Les pièges sémantiques Ca fonctionnait hier, ça ne fonctionne plus aujourd hui int x, y, z, somme; printf("valeur de x:"); scanf("%d", &x); printf("valeur de y:"); scanf("%d", &y); /* printf("valeur de z:"); scanf("%d", &z); */ somme = x + y + z; printf("somme:%d\n", somme); Certains compilateurs émettent un warning. Rigueur Suite à une modification du programme, la variable z est utilisée sans avoir été initialisée. Ce programme fonctionnera très bien si le hasard fait que z vaut 0, et ne plus fonctionner du jour au lendemain! 20

Les pièges sémantiques Problème implicite #include <stdio.h> #include <stdlib.h> Ce programme semble correct. Mais il manque le prototype pour sqrt. double resultat; resultat = sqrt(100.0); printf("resultat:%g\n", resultat); Résultat inattendu : la fonction sqrt est considérée comme retournant int! (Visual C++ 2010: 1.07958e+009) (Visual C++ 2013: Erreur de compilation) S assurer que le prototype d une fonction est spécifié avant l utilisation. Certains compilateurs émettent un warning. 21

Les pièges sémantiques Un résultat surprenant long factorielle(long n) long i; long resultat; resultat = 1; for (i = 2; i <= n; i++) resultat *= i; Ce programme semble correct. Mais il manque l instruction return pour renvoyer le résultat à l appelant. double d; printf("factorielle 5: %d\n", factorielle(5)); Certains compilateurs émettent un warning. Résultat inattendu : La valeur retournée est quelconque! 22

Les problèmes de portabilité La taille des types entiers int i = 20000; int j = 2 * i; printf("resultat:%d\n", j); Avec certaines compilateurs, int est un format 16 bits limité à -32768..+32767 Utiliser des typedefs pour préciser le format supposé des types. typedef long int32; typedef short int16; typedef char int8; 23

Est-il possible d écrire un programme fonctionnel en C? Quelques recommandations pour surmonter les difficultés Compiler en mode C++ Activer le plus haut niveau de warning possible Limiter l usage du préprocesseur Bannir toutes les expressions ambigües Appliquer des stratégies de recherche d erreurs Utiliser le debugger Mettre en place des traces avec printf. Effectuer une recherche dichotomique dans le code. Que faire en cas de désespoir? Relecture critique du code. Être prêt à tout remettre en question Même le compilateur peut être buggé! Essayer de mettre en évidence le problème observé. Eventuellement analyser le code assembleur généré. 24

Est-il possible d écrire un programme fonctionnel en C? Contexte industriel Des application difficiles écrites en assembleur existent. L écriture en langage C est nettement plus facile. Le langage C permet d écrire des applications complexes A condition d avoir les connaissances nécessaires. De structurer correctement les programmes. De réaliser la programmation de façon attentive. 25

Conclusions Le langage C comporte de nombreux pièges. Mieux vaut prévenir que guérir. Un ingénieur averti en vaut deux. 26

Vos questions 27

28