[Title of the course] Présentation du langage Campus-Booster ID : 301 14-Apr-17 [Title of the course] Langage C - Niveau 1 Présentation du langage Campus-Booster ID : 301 www.supinfo.com Copyright © SUPINFO. All rights reserved Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Votre formateur… Titre : Enseignant 14-Apr-17 Langage C – Niveau 1 [Title of the course] Votre formateur… Titre : Enseignant Distinctions & expérience : Ancien ingénieur de recherche chez Hewlett-Packard Laboratories Formation : Diplôme d’ingénieur et doctorat d’informatique Publications : Thèse et papier IEEE sur le thème du cluster-computing Contact : Campus-Booster ID: 50590 emmanuel.romagnoli@supinfo.com Emmanuel ROMAGNOLI Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Votre formateur… Titre: SUPINFO Certified Trainer 14-Apr-17 Langage C – Niveau 1 [Title of the course] Votre formateur… Titre: SUPINFO Certified Trainer Distinctions & expérience: Formateur au Laboratoire des Technologies .NET. Formation: *****************************************. Publications: Visual Basic – Codes prêts à l’emploi. Contact: Campus-Booster ID: 39572 mauricio.diazorlich@supinfo.com Mauricio DIAZ ORLICH Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Objectifs de ce module En suivant ce module vous allez: 14-Apr-17 Langage C – Niveau 1 [Title of the course] Objectifs de ce module En suivant ce module vous allez: Connaître l’évolution des langages de programmation Apprendre les principes de base du développement d’un programme en C Découvrir le compilateur GCC et l’environnement de développement Visual Studio 2005 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Plan du module Voici les parties que nous allons aborder: 14-Apr-17 Langage C – Niveau 1 [Title of the course] Plan du module Voici les parties que nous allons aborder: Présentation du langage Les données Les opérations de base Les structures de contrôle Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Présentation du langage 14-Apr-17 [Title of the course] Langage C – Niveau 1 Présentation du langage Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Plan de la partie Voici les chapitres que nous allons aborder: 14-Apr-17 Présentation du langage [Title of the course] Plan de la partie Voici les chapitres que nous allons aborder: Famille de langage – Historique et évolution Principes de développement en C Présentation des environnements de développement Structure d’un programme C Note sur cette partie Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution Avant 1950 : Programmation par câblage Différentes machines ont été construites avant 1950 mais l'une des plus fameuses reste l'ENIAC. A cette époque, la programmation s'effectuait par câblage : des opératrices ou des opérateurs reliaient différents modules électroniques afin de réaliser les opérations souhaitées. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1950 : Invention de l’assembleur Maurice V. Wilkes de l'université de Cambridge invente en 1950 le langage Assembleur qui permet de programmer plus facilement l'EDSAC (Electronic Delay Storage Automatic Calculator). Ce calculateur était capable de réaliser 700 additions/seconde et il utilisait des mémoires à ligne de mercure. Il était en service jusqu'en 1958. Maurice V. Wilkes Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1951 : Mise au point du A-0 Grace Murray Hopper met au point le compilateur A0 qui permet de passer d'un code source à un langage binaire pour les machines UNIVAC I et II. D'autres versions de ce langage suivront A-1, A-2, A-3 (ARITH-MATIC). Grace Hopper Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1954 : Création du FORTRAN John Backus conçoit le FORTRAN (FORmula TRANslation) en novembre 1954. IBM introduit ce nouveau langage sur son ordinateur 704 en 1957. Ce langage de haut niveau est plutôt orienté vers les applications scientifiques (gestion des vecteurs et des matrices, nombreuses bibliothèques de calcul numérique ...) Il a fait l'objet de plusieurs normalisation (FORTRAN 66, FORTRAN 77, FORTRAN 90, F 2k) afin de suivre l'évolution de l'informatique (introduction de la programmation orientée objets ...). John Backus Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1958 : ALGOL En Octobre 1955, un symposium international sur « l'informatique automatique » se tient à Darnstadt (Allemagne). Plusieurs conférenciers mettent en évidence le besoin d'un langage standard universel et indépendant de la machine. Des chercheurs américains et européens ont alors collaboré pour développer ce nouveau langage appelé ALGOL 58 (ALGOrithmic Language). Ce langage a fait l'objet de deux autres normalisations en 1960 et 1968 puis il a été progressivement abandonné. Comme le FORTRAN, ce langage est destiné à l'implantation d'application scientifique mais contrairement à celui-ci, il est plutôt conçu par faciliter l'implantation d'algorithmes (définition de bloc, introduction de la récursivité ...). Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1958 : Création du LISP John McCarthy, un mathématicien responsable du département d'Intelligence Artificielle au MIT développe le langage LISP (LISt Processing) sur un IBM 7090. Ce langage connait un certain succès dans le domaine de l'intelligence artificielle et de nombreux interpréteurs ont été mis au point. Dans les années 80 et 90, les différents « dialectes » ont été unifiés en un langage appelé Common-LISP (normalisé en 1994 sous la référence ANSI X3.226-1994). John McCarthy Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1959 : Création du COBOL Le Pentagone a formé le comité CODASYL afin d'écrire les spécifications du COBOL (COmmon Business-Oriented Language), un nouveau langage, indépendant des constructeurs, pour les applications de gestion de l'administration américaine. Ce travail, achevé en 1959, s'est largement inspiré du FLOW-MATIC (Grace Hopper) et du COMTRAN d'IBM (Bob Bemer). A l'instar du FORTRAN, ce langage a fait l'objet de plusieurs normalisations afin de suivre l'évolution de l'informatique : COBOL-60, COBOL ANS-74, et COBOL ANS-85. Il est encore assez utilisé dans le milieu bancaire : 60% des applications business sont encore écrites en COBOL selon 01 Informatique. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1964 : BASIC Le BASIC (Beginner's All-purpose Symbolic Instruction Code) a été développé par John KEMENY et Thomas KURTZ afin de mettre la programmation à la portée du plus grand nombre de leurs étudiants (il devait servir de passerelle vers des langages comme FORTRAN ou ALGOL). Ce langage a été très populaire et il a en partie fait la fortune de la jeune société Microsoft de Paul Allen et Bill Gates. Plus tard, ce langage a été décrié par les « puristes » car, mal utilisé, le BASIC pouvait permettre de produire du code « spaghetti » (du code nom structuré). Il a donc laissé sa place dans l'enseignement à des langages comme le Pascal mais il est revenu au goût du jour grâce au Visual Basic. John Kemeny et Thomas Kurtz Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1968 : Pascal Le langage Pascal est un descendant direct de l'ALGOL 60. Il a été développé par Niklaus Wirth, loin des contraintes de consensus de l'International Federation of Information Processing (IFIP), dont il était membre. Son objectif était de fournir un langage structuré et indépendant de la machine afin d'enseigner les techniques de programmation à l'Ecole et à l'Université. La première version fut mise au point à Zurich sur un CDC 6000 et elle fut rapidement adoptée par le monde de l'Enseignement. Ce langage a en outre été popularisé par la version « Turbo Pascal » développé par Philippe KAHN et sa société Borland. Niklaus Wirth Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1972 : PROLOG PROLOG (PROgrammation en LOGique) est un langage dit « descriptif de l‘intelligence artificielle ». Il a été codé en Pascal en 1972 par Alain Colmerauer, Robert Kowalski et Philippe Roussel dans le cadre de leurs activités de recherche pour le « traitement en langage naturel ». Aujourd'hui, il constitue l'un des langages les plus utilisés dans le domaine de l'intelligence artificielle. Alain Colmerauer Robert Kowalski Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution Contexte de la naissance du langage C Projet MULTICS Connecter plusieurs ordinateurs Difficultés techniques Mise en production au MIT UNICS inspiré de MULTICS UNIX En 1964, le MIT, les laboratoires Bell et la société General Electric lance le projet MULTICS (Multiplexed Information and Computing Service) dont l'objectif était de pouvoir connecter plusieurs centaines d'utilisateurs à une énorme machine (un GE 645 de General Electric) qui fournirait de la puissance de calcul : l'idée était donc d'obtenir de la puissance de calcul comme on obtient de la puissance électrique simplement en connectant l'ordinateur sur le réseau. La réalisation de ce projet s'est avéré plus difficile que prévu : le système MULTICS fut mis en production au MIT après de nombreuses difficultés techniques et l'abandon des partenaires industriels. La réalisation de ce projet a suscité une abondante littérature qui a influencé la réalisation des autres systèmes d'exploitation ... Ken Thompson (qui a travaillé sur MULTICS) et Dennis Ritchie écrivent en assembleur un système d'exploitation pour un PDP-7 en s'inspirant du système MULTICS. Le système fut d'abord baptisé UNICS (Uniplexed Information and Computing Service) par Brian Kernighan, en opposition à MULTICS puis UNIX. Les premiers travaux furent effectués sans financement mais les premiers succès permirent à Thompson et Ritchie d'obtenir un PDP-11 pour continuer leurs travaux. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1973 : Naissance du langage C Ken Thompson Brian Kernighan Dennis Ritchie Le premier système UNIX, opérationnel en 1970, devait être implanté sur d'autres machines. Thompson chercha un langage évolué dans lequel re-écrire UNIX. Il s'intéressa au BCPL (Basic Combined Programming Langage) qui disposait de plusieurs compilateurs sur différentes machines (l'objectif était alors de recompiler le code source d'UNIX sur la machine cible) Thompson fit évoluer ce langage (cela donna alors le langage B) afin de re-écrire UNIX mais le B comportait encore des limitations. En 1971, Ritchie améliora le langage B afin de répondre aux besoins du développement d'UNIX, ce nouveau langage fut simplement baptisé langage C. UNIX put alors être re-écrit en C en 1973. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution Développement et normalisation 1978 : « The C Programming Language » Grand succès ANSI C (C89) C90 ISO/IEC 9899:1999 (support limité) En 1978, Kernighan et Ritchie documentent ce nouveau langage afin d'en développer l'utilisation. Cela donne lieu à la publication du livre de référence « C Programming Langage ». Le C connait un grand succès et est porté sur de nombreuses machines. Des compilateurs sont développés indépendamment en comblant de façon non concerté des manques relevés dans les premières versions du langages. Il en résulta une incompatibilité entre les différentes versions du C. Afin de résoudre ce problème, l'ANSI normalisa le C en 1989. Le langage C qui respectait la norme ANSI X3.159-1989 fut baptisé ANSI C ou C89. L'année suivante, l'ISO normalisa également le C en ce basant sur la norme de l'ANSI. On obtint alors le C90 qui respectait la norme ISO/IEC 9899:1990. Cette norme a été modifiée afin de tenir d'éléments tels que les caractères internationaux. En 1999, l'ISO a publié une nouvelle norme ISO/IEC 9899:1999 afin d'intégrer de nouvelles « bonnes idées » comme les commentaires « // » du C++, le mot clé inline, le type long long de 64 bits ... mais il existe peu de compilateur qui soit compatible avec cette norme. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1979 : ADA En 1973, le ministère américain de la défense a déterminé qu'il dépensait annuellement 3 milliard de dollars pour ses développements informatiques. Le comité HOLWG (Higher Order Language Working Group) a donc été formé avec pour mission de proposer un langage de programmation qui permette de standardiser les développements dans les différents services. Après avoir évalué 23 langages (FORTRAN, COBOL, PL/I, HAL/S, TACPOL, CMS-2, CS-4, SPL/I, JOVIAL J3, JOVIAL J73, ALGOL 60, ALGOL 68, CORAL 66, Pascal, SUMULA 67, LIS, LTR, TRL/2, EUCLID, PDL2, PEARL, MORAL, EL/I ), ce comité en a conclu qu'aucun langage n‘était adapté aux besoins. Néanmoins, ce même comité a indiqué que le Pascal, l'ALGOL 68 et le PL/1 constituaient une bonne base pour le développement d'un nouveau langage. Une première spécification de nouveau langage a alors été écrite afin de faire un appel d'offre auprès des entreprises. La Compagnie Honeywell-Bull a remporté le marché en mars 1979. Le nouveau langage, baptisé ADA en honneur à Ada Lovelace, fut développé par une équipe d'ingénieurs, dirigée par Jean D. Ichbiah Jean D. Ichbiah Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1986 : C++ Bjarne Stroustrup effectue une thèse au laboratoire d'informatique de l'Université de Cambridge et il doit implanter, dans le cadre de ses travaux, un simulateur sur un IBM 360/165 en utilisant les langages Simula puis BCPL. Ces langages souffrent de quelques limitation (vitesse d’exécution …), il se définit donc l’outil idéal pour résoudre ce type de problème. Plus tard, Stroustrup entre au centre de recherche en informatique des laboratoires Bell (à Murray Hill dans le New Jersey) et il commence à analyser, en avril 1979, le noyau d'UNIX afin de déterminer les extensions nécessaires pour rendre possible son fonctionnement sur un réseau d'ordinateurs connectés par un réseau local. Ce travail correspond à la catégorie de problème qui nécessite “l’outil idéal” pour le résoudre : il s’attaque donc au développement de cet outil avant de s’attaquer au problème. - En 1979 : Ajout de quelques directives au langage C - En 1989 : Développement d’un premier langage appelé “C with classes” (il se consacre à ce développement en plus de son travail) - En 1982 : Stroustrup se consacre totalement au développement du langage C++ - la version 1.0 est officiellement sortie en 1986 ; - la version 1.1 (juin 1986) et 1.2 (février 1987) ont permis l'ajout des pointeurs sur les membres et des membres protégés dans les classes - la version 2.0 (juin 1989) introduit l'héritage multiple. - la version 2.1 (avril 1990) - la version 3.0 (septembre 1991) ajoute les patrons (templates) - la version 4.0 (1993) gère les exceptions - En 1989 : Début du processus de normalisation - Premier brouillon de la norme en 1995 - La norme est approuvée en 1998 Bjarne Stroustrup Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 1995 : Java En 1990, Patrick Naughton, un ingénieur de Sun Microsystem, se vit confier la mise au point de nouvelles technologie de développement en remplacement du langage C++ qui se révélait insatisfaisant. Ce premier projet, baptisé Stealth, fut renommé Green Project avec l'arrivée de James Gosling et de Mike Sheridan. Dans le cadre de ce projet, ces trois personnes, aidées d'autres ingénieurs, se sont isolés afin de réfléchir à la « prochaine vague » d'informatique et de planifier les prochains développements à ce sujet. Durant cette période de réflexion, ils ont mis en évidence le besoin du garbage collector, les lacunes au niveau de la sécurité, de la programmation distribuée, du multi-threading… Le résultat de ce travail a donné lieu au développement d'un nouveau langage baptisé Oak et d'un PDA afin de démontrer l'efficacité de ce nouveau langage. Cette technologie fut d'abord mal accueilli et elle fut modifiée en 1994 pour être intégré aux navigateurs web afin de proposer des pages web avec un contenu plus riche (les applets). A cette époque, le langage fut rebaptisé JAVA. Cette adaptation assura alors le succès de langage auprès du grand publique. James Gosling Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution 2000 : C# C# est un langage de programmation orienté objet mis au point par une équipe de développeurs de Microsoft, dirigée par Anders Hejlsberg. Ce langage permet de tirer pleinement parti des possibilités de la plateforme .NET. Ce langage s’inspire des points de vue syntaxique et conceptuel des langages comme Java, C++ et Pascal-Objet (Anders Hejlsberg étant responsable de l’équipe chargée du développement du Turbo Pascal et de Delphi chez Borland). Anders Hejlsberg Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution Synthèse – Différentes générations de langages 1ère génération Langage machine 2ème génération Assembleur 3ème génération FORTRAN, ALGOL, Pascal, C 4ème génération RAD : Visual Studio, Delphi, … Après avoir rapidement évoqué quelques langages de programmation, nous allons maintenant en proposer une synthèse afin de voir où se positionne le langage C. Si on essaye d’établir une taxinomie des langages par génération, nous obtenons la liste suivante : - La première génération de langages (encore appelé 1GL ou L1G) correspond à la programmation directe en langage machine - La deuxième génération de langages (2GL ou L2G) contient l’assembleur : le programmeur manipule des mnémoniques à la place des bits - La troisième génération (3GL ou L3G) regroupe l’ensemble des langages que nous avons évoqués jusqu’à présent : le programmeur utilise un ensemble de mots clés qui sont traduit en langage machine par un interpréteur ou un compilateur - La quatrième génération (4GL ou L4G) concerne plutôt les environnements de programmation rapide (Rapid Application Development ou RAD) : ces RAD peuvent encapsuler des langages de 3ème génération dans un environnement qui propose un ensemble d’outils facilitant le développement (prototypage d’interfaces …) Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution Synthèse – Différents types de langages Procéduraux C, C++, PASCAL, FORTRAN Déclaratif ou logique PROLOG Fonctionnel LISP, CAML Nous pouvons établir une autre taxinomie des langages en considérant le type de programmation : - La programmation procédurale ou impérative où le programme est constitué d’une suite d’instructions (le programme fonctionne alors comme une machine à états selon le paradigme de Turing) Nous pouvons placer le langage C dans cette catégorie mais également le C++, le PASCAL, le FORTRAN, le BASIC, le COBOL, l’Assembleur … - La programmation déclarative ou logique consiste à développer des programmes comme une suite de propositions logiques C’est dans cette catégorie que nous pouvons placer les langages de l’intelligence artificielle comme PROLOG ou Mercury - La programmation fonctionnelle se distingue de la programmation procédurale par le fait qu’un programme est constitué comme un emboitement de fonctions Cette catégorie contient des langages comme LISP ou CAML Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution Synthèse – Principaux avantages du langage C Efficacité Portabilité Diffusion Proche de la machine Ses principaux avantages sont : * l'efficacité : rapidité d'exécution des programmes. * la portabilité : accepté par de nombreuses machines. * la diffusion : utilisé partout. * il est proche de la machine : il peut manipuler des éléments de bas niveau (mémoire, processus, fichiers) de façon performante. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Famille de langage – Historique et évolution 14-Apr-17 Présentation du langage [Title of the course] Famille de langage – Historique et évolution Synthèse – Principaux inconvénients du langage C Permissivité Erreurs difficiles à détecter Possibilité de code illisible Ses principaux inconvénients sont : * la permissivité : un programme peut être considéré correct par l'ordinateur (compilateur, éditeur de liens) alors qu'il comporte de graves erreurs (accès à de la mémoire invalide, voir cours sur les pointeurs). * des erreurs difficiles à détecter * la possibilités d'écrire des programmes illisibles. Tout ceci donne naissance à des programmes ne fonctionnant pas correctement, qu'il est souvent très difficile de corriger ou de faire évoluer. Il est donc fondamental de prendre dès le départ de bonnes habitudes de programmation, de travailler avec méthode et de s'interdire l'utilisation de constructions dangereuses ou difficiles à lire, sous prétexte en particulier d'écrire un programme ``plus efficace''. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Principes de développement en C 14-Apr-17 Présentation du langage [Title of the course] Principes de développement en C La structure d’un code C 1 Analyse du problème. 2 Concevoir les algorithmes. 3 Spécifier les structures de données. Après avoir effectué l'analyse du problème, conçu le ou les algorithmes à implanter et déterminé les différentes structures de données à mettre en place, le programmeur écrit un ou plusieurs fichiers textes appelés fichiers source. L'ensemble de ces fichiers constitue le programme C. Un programme C est composé d'instructions qui sont regroupées au sein de fonctions qui peuvent être utilisées par d'autres fonctions. Une fonction principale sert de point d'entrée au programme, elle est exécutée en premier lors du lancement du programme et elle appelle d'autres fonctions. 4 Ecrire le code source. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Principes de développement en C 14-Apr-17 Présentation du langage [Title of the course] Principes de développement en C Du code source au fichier exécutable Lorsque le code source est saisi, on lance le processus qui va nous permettre d'obtenir un exécutable. Ce processus se déroule en 3 phases. Préprocesseur Source Source modifié Compilateur Lorsque le code source est saisi, on lance le processus qui va nous permettre d'obtenir un exécutable. Ce processus se déroule en 3 phases : le prétraitement (preprocessing) : le code source est modifié en mémoire (des termes sont remplacés ...) ; la compilation : le code source modifié est vérifié (d'un point de vue syntaxique) puis traduit en un code binaire, compréhensible par la machine, qui est stocké dans un fichier objet ; l'édition de lien (linking) : dans le cas où le programme n'est constitué que d'un fichier source, l'éditeur de lien ajoute quelques instructions machines pour permettre à l'OS d'exécuter ce fichier (appeler le code binaire de la fonction principale). Fichier objet Editeur de liens Fichier exécutable Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Principes de développement en C 14-Apr-17 Présentation du langage [Title of the course] Principes de développement en C Cas d’un code C sur plusieurs fichiers Un programme C peut être scindé en plusieurs fichiers source. Un fichier peut regrouper des fonctions dévolues aux calculs mathématiques, un autre fichier peut contenir les fonctions qui gèrent les affichages ... (nous reviendrons un peu plus loin sur cet aspect). Compte tenu de cette possibilité, une fonction d'un fichier source peut faire appel à une fonction d'un autre fichier source Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Principes de développement en C 14-Apr-17 Présentation du langage [Title of the course] Principes de développement en C Compilation de plusieurs fichiers sources Préprocesseur Lorsque le code source est saisi, on lance le processus qui va nous permettre d'obtenir un exécutable. Ce processus se déroule en 3 phases. Sources Source modifié Compilateur Lorsque le code source est saisi, on lance le processus qui va nous permettre d'obtenir un exécutable. Ce processus se déroule en 3 phases : le prétraitement (preprocessing) : le code source est modifié en mémoire (des termes sont remplacés, le contenu d'autres fichiers sources est ajouté ...) la compilation : le code source modifié est vérifié (d'un point de vue syntaxique) puis traduit en un code binaire (si plusieurs fichiers sources existent plusieurs fichiers binaires peuvent être produits) l'édition de lien (linking) : lorsque plusieurs fichiers binaires existent, l'éditeur de lien crée le fichier exécutable en chaînant les différents fichiers binaires entre eux et en ajoutant quelques instructions machines pour permettre à l'OS d'exécuter ce fichier. Fichier objet Editeur de liens Fichier exécutable Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Principes de développement en C 14-Apr-17 Présentation du langage [Title of the course] Principes de développement en C Utilisation de bibliothèques Un programme C peut également utiliser des fonctions toutes prêtes regroupées dans des bibliohtèques. Généralement, les programmes C s'appuient sur les fonctions de la bibliothèque standard car son contenu a été normalisé : les différents compilateurs C sont donc tenus de fournir cette bibliothéque et de respecter les comportements des fonctions tels qu'ils ont été définis dans la norme. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Principes de développement en C 14-Apr-17 Présentation du langage [Title of the course] Principes de développement en C Compilation faisant intervenir une bibliothèque Lorsque le code source est saisi, on lance le processus qui va nous permettre d'obtenir un exécutable. Ce processus se déroule en 3 phases. Préprocesseur Sources Source modifié Compilateur Lorsque le code source est saisi, on lance le processus qui va nous permettre d'obtenir un exécutable. Ce processus se déroule en 3 phases : le prétraitement (preprocessing) : le code source est modifié en mémoire (des termes sont remplacés, le contenu d'autres fichiers sources est ajouté ...) la compilation : le code source modifié est vérifié (d'un point de vue syntaxique) puis traduit en un code binaire (si plusieurs fichiers sources existent plusieurs fichiers binaires peuvent être produits) l'édition de lien (linking) : lorsque plusieurs fichiers binaires existent, l'éditeur de lien crée le fichier exécutable en chaînant les différents fichiers binaires entre eux et en ajoutant quelques instructions machines pour permettre à l'OS d'exécuter ce fichier. Fichier objet Editeur de liens Biblio. Fichier exécutable Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Présentation des environnements de développement 14-Apr-17 Présentation du langage [Title of the course] Présentation des environnements de développement Le compilateur GCC Présent dans la plupart des distributions Linux Ligne de commande Fichier makefile Le compilateur GCC (GNU Compilator C) est présent dans la plupart des distribution Linux mais il peut être téléchargé à partir de http://gcc.gnu.org/gcc-4.1/. On peut l'utiliser directement en ligne de commande ou par l'intermédiaire d'un fichier de compilation (le Makefile) que nous présenterons un peu plus tard. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Présentation des environnements de développement 14-Apr-17 Présentation du langage [Title of the course] Présentation des environnements de développement Principales options du compilateur GCC -o -c gcc source.c –o executable gcc –c source.c –o binaire.o gcc comporte de nombreux arguments, ceux que nous utiliserons souvent sont (les autres seront présentés au besoin durant les TPs) : - o (output name) : gcc source.c a pour effet de produire un fichier exécutable « a.out ». Si on souhaite donner un autre nom à ce fichier, il faut taper gcc source.c -o executable. - c (compile) : gcc -c source.c -o binaire.o active simplement le préprocesseur et le compilateur pour produire le fichier binaire correspondant au fichier source. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Présentation des environnements de développement 14-Apr-17 Présentation du langage [Title of the course] Présentation des environnements de développement Remarques sur le compilateur GCC Compilation séparée Extension des fichiers source (.c) gcc -c source2.c -o bin2 gcc -c source3.c -o bin3 gcc -c source1.c bin2.o bin3.o -o exec Lorsque nous aborderons plus tard la compilation séparée qui consiste à scinder le programme C en plusieurs fichiers source, nous taperons d'abord plusieurs fois la commande gcc -c pour créer les fichiers binaires puis un gcc pour produire l'exécutable. Si nous reprenons l'exemple du chapitre “principe de développement en C”, nous obtenons : gcc -c source2.c -o binaire2 gcc -c source3.c -o binaire3 gcc -c source1.c binaire2.o binaire3.o -o executable Remarque importante : gcc est sensible à l'extension du fichier source, de ce fait le nom des fichiers source devra toujours se terminer par .c. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Présentation des environnements de développement 14-Apr-17 Présentation du langage [Title of the course] Présentation des environnements de développement Microsoft Visual Studio 2005 Environnement de développement intégré de Microsoft Permet de programmer en plusieurs langages : Visual Basic .NET C# C++ C … Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Présentation des environnements de développement 14-Apr-17 Présentation du langage [Title of the course] Présentation des environnements de développement Microsoft Visual Studio 2005 Exécuter Compile, exécute et débogue le programme. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Structure d’un programme C 14-Apr-17 Présentation du langage [Title of the course] Structure d’un programme C La notion d’instruction Programme constitué d’un ensemble d’instructions Instruction terminée par un point-virgule « ; » Instruction 1; ... Instruction 2; Un programme est constitué d'un ensemble d'instructions qui peuvent être des traitements simples comme des opérations arithmétiques ou des traitements plus complexes comme des fonctions d'affichage, des fonctions de lecture d'un fichier ... En C, une instruction est toujours terminée par un point-virgule « ; » afin de permettre au compilateur de séparer les instructions les unes des autres. Il est possible d'écrire plusieurs instructions sur une même ligne, pourvues qu'elles soient séparée des points-virgules. Cependant cette méthode d'écriture n'est pas conseillée à moins qu'elle n'améliore ponctuellement la présentation et la lisibilité du programme Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Structure d’un programme C 14-Apr-17 Présentation du langage [Title of the course] Structure d’un programme C La notion de bloc Ensemble d’instructions délimité par des accolades Chaque sous-bloc est considéré comme une instruction Fonction { instruction 1; instruction 2; instruction 3; instruction 4; } Nous avons vu dans le chapître 2 qu'un programme C est constitué d'un ensemble de fonctions qui s'appellent entre elles. D'un point de vue syntaxique, les fonctions sont un ensemble d'instructions qui sont délimités par des accolades afin de former un bloc de code. A l'intérieur d'un bloc de code, il est possible voire indispensable – par exemple, lorsqu'on utilise des structures de contrôle – de délimiter des instructions par des accolades afin qu'elles soient vues comme un seul bloc : ce bloc sera alors considéré comme une intruction (on parle alors d’instruction composée) Bloc d’instructions Sous-bloc d’instructions Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Structure d’un programme C 14-Apr-17 Présentation du langage [Title of the course] Structure d’un programme C Les commentaires Ne sont pas analysés Aident à la compréhension du code 2 types : /* ... */ et // /***************************/ /* Projet X – Auteur: S.B. */ /* Date : 03/09/82 */ instruction 1; // commentaire instruction 2; Ce texte n’est pas analysé L'ensemble des éléments, qui sont saisis dans un fichier source, est analysé par le préprocesseur et le compileur à l'exception des commentaires. Les commentaires sont des morceaux du code source qui débutent par un slash suivi d'une étoile « /* » et qui se termine par une étoile suivi d'un slash « */ » Le commentaire est un élément à ne pas négliger car il aide à la compréhension du code. Il permet au programmeur d'expliquer au sein même du fichier source, l'astuce de codage employé, d'indiquer les références décrivant l'algorithme implanté ... Le commentaire peut également être employé pour construire un cartouche qui sera placé en début de code afin de spécifier des informations comme l'auteur, la date de création ... Il peut enfin être utilisé pour scinder un fichier de code en plusieurs sections afin d'en améliorer la lisibilité. Le // permet simplement d'ajouter un commentaire sur une seule ligne. Le commentaire débute après les deux slash et se termine à la fin de la ligne (la ligne suivante est donc analysé par le préprocesseur et le compilateur). Ce second type de commentaire ne fait pas parti de la définition originel du langage C. Il a été introduit par l'ISO en 1990 lorsqu'une nouvelle norme de ce langage est sortie. De ce fait, tous les compilateur n'acceptent pas nécessairement ce type de commentaire. Il peut cependant être pratique pour commenter temporairement quelques lignes de code lors de scéance de debogage par exemple ou pour décrire un paramètre, une variable ... Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Structure d’un programme C 14-Apr-17 Présentation du langage [Title of the course] Structure d’un programme C La fonction principale : main Point d’entrée de l’application /***************************/ /* Mon premier programme */ /* Date : 03/09/82 */ main () { 10 + 20; // instruction } Nous terminons cette présentation de la structure du programme C en évoquant la fonction principale. Nous avons vu dans le second chapître que celle-ci sert de point d'entrée dans le code C (autrement dit, cette fonction est la première fonction exécutée lorsque l'OS lance le programme). En langage C, cette fonction s'appelle main et elle est suivie de deux parenthèses (). A ce niveau, nous pouvons écrire un premier programme C, qui n'affiche malheureusement rien à ce stade de nos connaissances. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Annexes 1.1.1 et 1.1.2 Note sur cette partie Présentation du langage 14-Apr-17 Présentation du langage [Title of the course] Note sur cette partie Annexes 1.1.1 et 1.1.2 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les données Langage C – Niveau 1 14-Apr-17 [Title of the course] Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Plan de la partie Voici les chapitres que nous allons aborder: 14-Apr-17 Les données [Title of the course] Plan de la partie Voici les chapitres que nous allons aborder: Les variables Les types L’affectation Les conversions implicites L’opérateur sizeof Les constantes Note sur cette partie Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
type nomDeLaVariable; 14-Apr-17 Les données [Title of the course] Les variables La notion de variable Zone de mémoire Stockage d’information Nommée a-z, A-Z, 0-9, _ Ne commence pas par un chiffre Doit être déclarée Doit avoir un type type nomDeLaVariable; Le langage C permet d'implanter des algorithmes qui effectuent des manipulations sur des données fournies en entrée du programme afin de retourner un résultat. Cet algorithme peut être vu comme un enchaînement de traitements où les résultats d'un traitement peuvent constituer les entrées du traitement suivant. Pour ce faire, le programme C doit conserver ces données intermédiaires dans des variables. Une variable est une petite zone de mémoire dans laquelle est stockée l'information et qui est manipulée au sein d'un programme C par l'intermédiaire de son nom. Pour manipuler cette variable, nous devons au préalable la déclarer afin que l'espace mémoire nécessaire soit réservée. Le C étant un langage typé, nous devons en outre indiquer au compilateur, lors de la déclaration, le type d'information qui sera stockée. La déclaration d'une variable en C s'ecrit donc de la manière suivante : type nomDeLaVariable ; Le langage C utilise un compilateur qui analyse le texte afin de produire le code objet. Ce compilateur introduit un certain nombre de contraintes sur le nommage des variable : Le nom d'une variable n'est constitué que de lettres non accentués, de chiffres et du caractère souligné : {A ... ... Z, a ... ... z, 0 ... ... 9, _} Le nom d'une variable ne doit pas commencer par un chiffre. Le nom d'une variable ne peut pas être un mot clé réservé dont la liste est donnée ci-dessous : auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les variables Déclaration des variables C89 (ANSI) : 14-Apr-17 Les données [Title of the course] Les variables Déclaration des variables C89 (ANSI) : Au début d’un bloc C90 (ISO) : N’importe où Cours : Norme ANSI La déclaration de la variable s'effectue au début du bloc d'instructions selon la norme ANSI de 1989 qui est la plus employée. Cependant, si le compilateur respecte la norme ISO de 1999, il est possible de déclarer les variables n'importe où dans le programme (la déclaration se fait « au besoin »). Dans le cadre du cours, nous nous baserons plutôt sur la norme ANSI, la déclaration des variables s'effectuera donc au début des blocs d'instructions. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les variables Conventions de nommage Constantes #define CONSTANTE 14-Apr-17 Les données [Title of the course] Les variables Conventions de nommage Constantes #define CONSTANTE enum { Constante } Noms évocateurs var1 nomUtilisateur Plusieurs termes deux_mots, deuxMots La déclaration de la variable s'effectue au début du bloc d'instructions selon la norme ANSI de 1989 qui est la plus employée par la compilateur. Cependant, si le compilateur respecte la norme ISO de 1999, il est possible de déclarer les variables n'importe où dans le programme (la déclaration se fait « au besoin »). Dans le cadre du cours, nous nous baserons plutôt sur la norme ANSI, la déclaration des variables s'effectuera donc au début des blocs d'instructions. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les types Les types char, unsigned char char 8 bits signés -128 ↔ 127 14-Apr-17 Les données [Title of the course] Les types Les types char, unsigned char char 8 bits signés -128 ↔ 127 Table ASCII-7 unsigned char 8 bits non-signés 0 ↔ 255 char monCaractere; unsigned char monCar; Le type char permet de stocker des nombres signés, codés sur 8 bits qui désignent généralement des caractères de la table ASCII-7 bits. Autrement dit, le signe de ce nombre ne constitue pas une gêne puisque les codes de la table ASCII-7 bits sont compris entre 0 et 127 inclus. Cependant, la plupart du temps, nous avons également accès à 128 autres symboles qui forment la table ASCII étendue. Elle a été créée afin que chaque zone géographique puisse ajouter sa table comprenant des symbôles comme les accents ou les caractères semi-graphiques permettant de dessiner un tableau en mode texte. Pour accéder simplement à ces symbôles, il est préférable d'utiliser un unsigned char sinon pour accéder au caractère numéro N, il vous faudra utiliser son opposé. On peut également utiliser le type char pour manipuler des nombres entiers compris entre -128 et +127 afin d'économiser de la place mémoire. Pour déclarer une variable v de type char, nous écrivons : char v ; Pour manipuler des nombres non-signés, il suffit d'ajouter le mot clé unsigned devant char. Pour déclarer une variable v de type unsigned char, nous écrivons donc : unsigned char v ; Les valeurs stockées dans v sont alors comprises entre 0 et 255 inclus. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les types Les types short, unsigned short short 14-Apr-17 Les données [Title of the course] Les types Les types short, unsigned short short 8/16 bits signés (selon architecture et/ou OS) -128 ↔ 127 -32 768 ↔ 32 767 unsigned short 0 ↔ 255 0 ↔ 65 535 short monShort; unsigned short monSh; Le type short permet de manipuler des nombres entiers signés codés sur 8 bits ou 16 bits selon l'architecture et/ou l'OS. Dans le cas où le short est codé sur 8 bit, il permet de distinguer les variables désignant des nombres, des variables de type char qui sont plutôt sensés désigner des caractères ASCII. Pour déclarer une variable v de type short, nous tapons short v; Une variable de type short codé sur 8 bits peut stocker des nombres compris entre -128 et +127. Le programmeur doit donc avoir à l'esprit cette contrainte afin de se prémunir contre des résultats de calculs erronés. Par exemple, si nous considérons deux variables a et b de type short, qui contiennent tous les deux 120, lorsque nous plaçons dans a le cumul des deux variables, nous obtenons -16 et non 240 car la somme dépasse 127. 240 s'écrit 11110000 en binaire. Comme les nombres signés sont codés en utilisant le complément à deux, il suffit de faire 11110000 – 1 (nous obtenons 11101111) puis de prendre le complément à un (on inverse les 1 et les 0) pour obtenir 00010000 qui correspond à 16. Remarque : L'explication reste valable lorsque le type short est codé sur 16 bits, à la différence que les valeurs stockées sont comprises entre -32768 et +32767. Si nous souhaitons manipuler des nombres non-signés, il suffit d'ajouter le mot clé unsigned devant short. Pour déclarer une variable v de type unsigned short, nous écrivons : unsigned short v ; Lorsque le unsigned short est codé sur 8 bits, les valeurs stockées sont comprises entre 0 et 255 et si le unsigned short est codé sur 16 bits, l'intervalle des valeurs est [0,65535] Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les types Les types int, unsigned int int 14-Apr-17 Les données [Title of the course] Les types Les types int, unsigned int int 16/32 bits signés (selon architecture et/ou OS) -32 768 ↔ 32 767 -2 147 483 648 ↔ 2 147 483 647 unsigned int 0 ↔ 65 535 0 ↔ 4 294 967 295 int monInt; Le type int est utilisé pour manipuler des nombres entiers signés codés sur 16 bits ou 32 bits selon l'architecture et/ou l'OS. Pour déclarer une variable v de type int, nous tapons : int v; Si le int est codé sur 16 bits, il peut stocker des valeurs comprises entre -32768 et +32767. Si le int est codé sur 32 bits, l'intervalle des valeurs pouvant être stockées est porté à [-2147483648, +2147483647]. A l'instar du type short, le programmeur doit avoir à l'esprit ces intervalles afin de prévenir tout résultat erronés dû à des dépassements de capacité durant les calculs. Si le programmeur souhaite manipuler des nombres non-signés, il doit ajouter le mot clé unsigned. Pour déclarer une variable v de type unsigned short, nous écrivons : unsigned int v; L'intervalle des valeurs pouvant être stockées est alors [0, 65536] lorsque le int est codé sur 16 bits, et [0, 4294967295] lorsque le int est codé sur 32 bits. unsigned int monInt; Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les types Les types long, unsigned long long 32 bits signés 14-Apr-17 Les données [Title of the course] Les types Les types long, unsigned long long 32 bits signés -2 147 483 648 ↔ 2 147 483 647 unsigned long 0 ↔ 4 294 967 295 long monLong; unsigned long monLon; Le type long est utilisé pour manipuler des nombres entiers signés codés sur 32 bits. Pour déclarer une variable v de type long, nous tapons : long v; Le long permet de stocker des valeurs comprises entre -2147483648, +2147483647 (le programmeur doit toujours veiller à ne pas effectuer de dépassement de capacité durant les calculs). Pour manipuler des long non-signés, il doit ajouter le mot clé unsigned. Pour déclarer une variable v de type unsigned long, nous écrivons : unsigned long v; L'intervalle des valeurs pouvant être stockées est alors porté à [0, 4294967295]. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les types Les types long long, unsigned long long long long 14-Apr-17 Les données [Title of the course] Les types Les types long long, unsigned long long long long 64 bits signés -9 223 372 036 854 775 808 ↔ 9 223 372 036 854 775 807 unsigned long long 0 ↔ 18 446 744 073 709 551 615 long monLong; unsigned long monLon; Le type long long permet de manipuler des nombres entiers signés codés sur 64 bits. La déclaration d'une variable v de type long long, s'effectue en tapant : long long v; Le long long est capable de stocker des valeur comprises entre -9223372036854775808, +9223372036854775807 (le programmeur doit toujours veiller à ne pas effectuer de dépassements de capacité durant les calculs). Pour manipuler des long long non-signés, il suffit d'ajouter le mot clé unsigned. Pour déclarer une variable v de type unsigned long long, nous écrivons : unsigned long long v; Les valeurs pouvant être stockées sont alors comprises entre 0 et 18446744073709551615. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les types Le type float Format IEEE 754 32 bits 0-22 : mantisse 14-Apr-17 Les données [Title of the course] Les types Le type float Format IEEE 754 32 bits 0-22 : mantisse 23-30 : exposant 31 : signe Valeurs entre : ± 2-126 ↔ ±(2 − 2-23)×2127 float monFloat; Le type float est utilisé pour manipuler des nombres réels codés sur 32 bits selon le format IEEE 754. La déclaration d'une variable v de type float, s'effectue en tapant : float v; Le float permet de stocker des valeurs comprises entre ± 2-126 et ±(2 – 2-23)×2127 En interne, le float utilise 32 bits qui sont répartis de la manière suivante (voir cours d'architecture des ordinateurs) : Les bits 0 à 22 inclus sont utilisés pour stocker la mantise ; Les bits 23 à 30 inclus sont destinés à stocker l'exposant ; Le bit 31 est dévolu au stockage du bit de signed. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les types Le type double Format IEEE 754 64 bits 0-51 : mantisse 14-Apr-17 Les données [Title of the course] Les types Le type double Format IEEE 754 64 bits 0-51 : mantisse 52-62 : exposant 63 : signe Valeurs entre : ± 2-1022 ↔ ±(2 − 2-52)×21023 double monFloat; Le type double permet de manipuler des nombres réels codés sur 64 bits selon le format IEEE 754. La déclaration d'une variable v de type float, s'effectue en tapant : double v; Le double permet de stocker une fourchette de valeurs beaucoup plus importante car la taille de l'exposant a fortement augmenté. Les valeurs sont désormais comprises entre ± 2-1022 et ±(2 – 2-52)×21023 En interne, la répartition des 64 bits du double s'effectue de la manière suivante (voir cours d'architecture des ordinateurs) : Les bits 0 à 51 inclus sont utilisés pour stocker la mantise ; Les bits 52 à 62 inclus sont destinés à stocker l'exposant ; Le bit 63 est dévolu au stockage du bit de signed. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les types Le type long double Format IEEE 754 80 bits 0-63 : mantisse 14-Apr-17 Les données [Title of the course] Les types Le type long double Format IEEE 754 80 bits 0-63 : mantisse 64-78 : exposant 79 : signe Valeurs entre : ± 2-32766 ↔ ±(2 − 2-64)×232767 Pas supporté par le C89 long double monLongD; Le type long double permet manipuler des nombres réels avec une précision encore plus importante car ils sont codés sur 80 bits selon le format IEEE 754. La déclaration d'une variable v de type float, s'effectue en tapant : long double v; Le long double permet de stocker des valeurs comprises entre ± 2-32766 et ±(2 – 2-64)×232767 En interne, la répartition des 80 du long double est la suivante (voir cours d'architecture des ordinateurs) : Les bits 0 à 63 inclus sont utilisés pour stocker la mantise ; Les bits 64 à 78 inclus sont destinés à stocker l'exposant ; Le bit 79 est dévolu au stockage du bit de signed. Remarque : Ce dernier type n'est défini que dans la norme ISO de 1999. Il est cité pour information dans ce cours mais il ne sera pas utilisé car nous nous baserons sur la norme ANSI de 1989 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les types Le type void Type vide Ne sert pas à typer des variables 14-Apr-17 Les données [Title of the course] Les types Le type void Type vide Ne sert pas à typer des variables Utilisations : Pointeurs Déclarations de fonctions void* monPointeur; void maFonction(void) Le type void est un cas un peu particulier car il correspond à un type vide pour spécifier clairement au compilateur qu'il n'y a rien. void ne sert pas à typer des variables (une variable de type rien n'a aucun sens), il est plutôt utilisé dans les deux cas ci-dessous : lorsqu'on souhaite créer un type « pointeur sur n'importe quoi », on utilise void* comme nous verrons un peu plus tard dans ce cours ; lorsqu'on écrit la signature d'une fonction pour spécifier qu'il n'a pas de paramètre en entrée et/ou lorsqu'il n'y a aucun résultat retourné. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
L’affectation Affectation d’une valeur à une variable 14-Apr-17 Les données [Title of the course] L’affectation Affectation d’une valeur à une variable Après déclaration… …affectation Opérateur = Conseillé d’initialiser dès la création int a; a = 10; int b = 0; Après avoir créé une variable typée, nous somme amené à l'utiliser en lui affectant une valeur (ou une information). Cette opération s'effectue simplement en utilisant le signe égal = . Par exemple, si créons une variable a de type int et que nous voulons lui affecter la valeur 10, nous écrivons : int a; a = 10; Nous pouvons également affecter une valeur à une variable dès sa création, ainsi l'exemple précédent devient : int a = 10; Il est vivement conseillé d'initialiser les variables dès leur création (en leur affectant 0 par exemple) car au moment de cette création, la valeur contenue dans la valeur peut être n'importe laquelle. Nous pouvons alors obtenir un comportement erroné de notre programme si nous utilisons cette variable par la suite. Nous avons vu qu'il existe différents types de données et nous avons vu comment déclarer les variables de différents types et comment leur affecter des valeurs. Nous devons maintenant aborder l'écriture des données car il existe différentes manières d'écrire ces données, selon que nous manipulons des caractères, des nombres entiers (en base décimale, octale, binaire ou héxadécimale) ou des nombres flottants Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
L’affectation Le cas des nombres entiers Base 10 int val = 128; Base 8 14-Apr-17 Les données [Title of the course] L’affectation Le cas des nombres entiers Base 10 Base 8 Base 16 int val = 128; int val = 0200; Lorsque nous manipulons des nombres entiers, nous pouvons le faire dans différentes bases selon nos besoins : Si nous manipulons des nombres décimaux, nous les écrivons « normalement » Si nous souhaitons utiliser des nombres en base octale, nous devons les faire précéder du chiffre 0 « 0 ». Par exemple, si nous voulons affecter la valeur 27 en base 8 à la variable val de type int, nous devons écrire : int val = 027 ; Si nous voulons employer des nombres hexadécimaux, nous devons les faire précéder de « 0x » ou « 0X ». Par exemple, si nous voulons affecter la valeur A7 en base 16 à la variable val de type int, nous devons écrire int val = 0xA7 ; int val = 0x80; Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
L’affectation Le cas des nombres à virgule flottante Notation simple 14-Apr-17 Les données [Title of the course] L’affectation Le cas des nombres à virgule flottante Notation simple Notation scientifique double val = 23.3; float val = 7.45E-27; float val = 7.45e-27; Lorsque nous utilisons des nombres à virgule flottante, nous pouvons les écrire de deux manières : Nous pouvons simplement utiliser un point « . » pour matérialiser la virgule qui sépare la partie entière de la partie décimale ; Nous pouvons écrire ce nombre en utilisant la notation scientifique, nous devons alors séparer la mantisse de l'exposant en utilisant un e ou un E. Par exemple, si nous voulons affecter le nombre 7,45 10-27 à une variable val de type float, nous devons écrire float val = 7.45E-27 ; ou float val = 7.45e-27 ; Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
L’affectation Les suffixes Type Suffixe Exemple long L 10L unsigned U 14-Apr-17 Les données [Title of the course] L’affectation Les suffixes Type Suffixe Exemple long L 10L unsigned U 0x4U unsigned long UL 24UL Etant donné la conversion implicite, il parfois nécessaire de préciser les types des valeurs, notamment dans les opérations, en utilisant des suffixes : Si on veut indiquer que le nombre est un long, nous devons ajouter L après l'écriture de ce nombre. Nous pouvons écrire par exemple : 10L pour indiquer que ce 10 est codé sous forme de long (il occupe donc 4 octets) 0x4AL pour indiquer que 4A16 est aussi codé sous forme de long Si on veut indiquer que le nombre est un unsigned, nous devons ajouter U après l'écriture de ce nombre. Nous pouvons écrire par exemple : 4U pour indiquer que ce 4 est non signé 0x3BU pour indiquer que 3B16 est également non signé Nous pouvons enfin cumuler les deux notations 5UL pour indiquer que ce 5 est un long non signé 0x7DU pour indiquer que 7D16 est également un long non signé Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
L’affectation Le cas des caractères Utilisation d’apostrophes ('') 14-Apr-17 Les données [Title of the course] L’affectation Le cas des caractères Utilisation d’apostrophes ('') Caractères affichables Caractères non-affichables char carac = 'G'; Dans le cas des caractères, lorsque nous manipulons des variables de type char ou unsigned char, nous pouvons affecter les valeurs de différentes manières : La première manière consiste à affecter directement la valeur numérique du caractère mais cela oblige à se référer à la table ASCII afin de déterminer la bonne valeur en fonction du caractère, ce qui est peu pratique. La seconde manière se base sur l'utilisation des quotes (les apostrophes '). Nous mettons le caractère entre quotes et ce dernier est automatiquement interprété pour être transformé en son code ASCII. Par exemple, si nous souhaitons affecter le caractère G à la variable carac, nous pouvons écrire char carac = 'G' ; Si nous souhaitons utiliser la seconde méthode d'affectation, nous devons utiliser le caractère d'échappement – le back slash \ - pour manipuler des caractères non-affichables. Par exemple, si nous souhaitons affecter le caractère n°9 (la tabulation horizontale), nous devons écrire : char carac = '\t'; char carac = '\t'; Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
L’affectation Le cas des caractères Caractères spéciaux utiles : 14-Apr-17 Les données [Title of the course] L’affectation Le cas des caractères Caractères spéciaux utiles : '\n' Nouvelle ligne '\r' Retour chariot '\t' Tabulation horizontale '\0' Caractère nul '\\' Backslash '\'' Apostrophe '\"' Guillemet '\x41' Caractère ASCII 41 (A) La liste de ces caractères non-affichables est la suivante : \a correspond au caractère numéro 7 : l'alarme \f correspond au caractère numéro 12 : nouvelle page \n correspond au caractère numéro 10 : nouvelle ligne \r correspond au caractère numéro 13 : retour chariot \t correspond au caractère numéro 9 : tabulation horizontale \v correspond au caractère numéro 11 : tabulation verticale \0 correspond au caractère numéro 0 : null (à ne surtou pas confondre avec le chiffre 0 qui correspond au code ASCII 48) Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les conversions implicites 14-Apr-17 Les données [Title of the course] Les conversions implicites char Hiérarchie de types unsigned char short unsigned short int unsigned int long Il existe une hierarchie des types au niveau du langage C, qui se base essentiellement sur la fourchette de valeurs que permettent de manipuler ces types. Du plus important vers le moins important, nous avons : long double double float unsigned long long unsigned int int unsigned short short unsigned char Char Dans une certaine mesure, il est possible d'affecter des valeurs d'un certain type à une variable d'un autre type. Le compilateur prend alors en charge la conversion d'un type à l'autre : on parle alors de conversion implicite. On peut avoir deux cas de figures : Si le type de la variable qui accueille la valeur est plus haut dans la hiérarchie, la conversion s'effectue sans perte d'information. Dans le cas contraire, la valeur est tronquée et il y a perte d'information. Par exemple, si nous avons : int a = 8; double b = a; float c = 0.32; long d = c; Nous aurons b = 8 et c = 0 car dans le premier il n'y a pas de perte d'information et dans le second cas la valeur 0.32 est tronqué pour être transformée en une valeur entière. Autre exemple, si nous avons : unsigned long a = 65523 ; unsigned char b = a; Nous avons b = 243; En effet, si nous exprimons 65523 en binaire, nous obtenons 11111111111100112 Cela fait un nombre binaire à 16 bits. Comme le type unsigned char ne sait stocker que des nombres codés sur 8 bits, il ne retiendra que les 8 bits de poids faible. Cela nous fait le nombre 111100112 qui nous fait 243 en décimal. Le programmeur doit donc avoir en tête ce phénomène de conversion implicite qui peut entraîner des comportements erronés de son programme. unsigned long float double long double Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les conversions implicites 14-Apr-17 Les données [Title of the course] Les conversions implicites Conversions d’un type à l’autre Affectation des valeur d’un type à des variables d’un autre : Pas de problèmes en descendant la pyramide, mais dans le sens inverse : int a = 8; double b = a; // b = 8 Dans une certaine mesure, il est possible d'affecter des valeurs d'un certain type à une variable d'un autre type. Le compilateur prend alors en charge la conversion d'un type à l'autre : on parle alors de conversion implicite. On peut avoir deux cas de figures : Si le type de la variable qui accueille la valeur est plus haut dans la hiérarchie, la conversion s'effectue sans perte d'information. Dans le cas contraire, la valeur est tronquée et il y a perte d'information. Par exemple, si nous avons : int a = 8; double b = a; float c = 0.32; long d = c; Nous aurons b = 8 et d = 0 car dans le premier il n'y a pas de perte d'information et dans le second cas la valeur 0.32 est tronqué pour être transformée en une valeur entière. float c = 0.32; long d = c; // d = 0 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les conversions implicites 14-Apr-17 Les données [Title of the course] Les conversions implicites Données tronquées Exemple : Explication : unsigned long a = 65523; unsigned char b = a; // b = 243 Autre exemple, si nous avons : unsigned long a = 65523 ; unsigned char b = a; Nous avons b = 243; En effet, si nous exprimons 65523 en binaire, nous obtenons 11111111111100112 Cela fait un nombre binaire à 16 bits. Comme le type unsigned char ne sait stocker que des nombres codés sur 8 bits, il ne retiendra que les 8 bits de poids faible. Cela nous fait le nombre 111100112 qui nous fait 243 en décimal. Le programmeur doit donc avoir en tête ce phénomène de conversion implicite qui peut entraîner des comportements erronés de son programme. 6552310 = 1111 1111 1111 00112 = 1111 00112 24310 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
L’opérateur sizeof Récupérer la taille d’une donnée ou d’un type 14-Apr-17 Les données [Title of the course] L’opérateur sizeof Récupérer la taille d’une donnée ou d’un type Fonction sizeof int taille = sizeof(char); // retourne 1 Il est parfois utile de connaître la taille d'une donnée ou d'un type de donnée afin de réserver la place mémoire nécessaire pour stocker l'information (nous verrons cet aspect lorsque nous aborderons les pointeurs et l'allocation dynamique de mémoire). Une telle information peut être obtenue grâce à la fonction sizeof qui retourne un entier (un int) correspondant au nombre d'octets occupées par la donnée ou le type de données. Par exemple, si on souhaite connaître le nombre d'octets nécessaires pour stocker un char, nous devons taper sizeof (char) Nous pouvons stocker ce résultat dans une variable taille de type int. Nous devons alors taper (taille contiendra la valeur 1) : int taille = sizeof (char) ; Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les constantes Les constantes définies par #define 14-Apr-17 Les données [Title of the course] Les constantes Les constantes définies par #define Directive du préprocesseur N’est pas une instruction Pas de point-virgule Pas d’opérateur = La première chaîne de caractères sera remplacé par la seconde avant la compilation #define CST 20 Jusqu'à présent, nous avons parlé des variables, autrement dit des zones mémoires contenant des informations pouvant être modifiées au cours du fonctionnement. Nous avons parfois besoin d'utiliser des informations qui ne doivent pas évoluer au cours du temps : on parle alors de constantes. En C-ANSI, nous définissons les constantes en utilisant la directive #define du préprocesseur qui définit une correspondance entre deux termes. Par exemple, si nous voulons définir la constante CST comme étant égale à 20, nous écrirons #define CST 20 Cette ligne n'est pas une instruction (elle ne se termine donc pas par un point-virgule), il s'agit d'une directive du préprocesseur. Autrement dit, nous indiquons au préprocesseur qu'il doit remplacer partout dans le programme (à l'exception des commentaires) la chaîne de caractères « CST » par la chaîne de caractère « 20 » avant de lancer la compilation proprement dite. Nous verrons un peu plus tard lorsque nous aborderons le switch que ces constantes peuvent se révéler très intéressantes pour améliorer la lisibilité d'un code. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les constantes Les constantes définies par const 14-Apr-17 Les données [Title of the course] Les constantes Les constantes définies par const Instruction du compilateur Instruction Point-virgule Opérateur = La constante reçoit une lors de la compilation et est ensuite protégée contre d’autres modifications Ne fait pas partie de la norme ANSI const double CST = 20.3; La norme ISO de 1999 introduit une autre manière de créer des constante en utilisant le mot clé const. La création d'une constante s'effectue alors de la même manière que la création d'une variable, il suffit simplement d'ajouter le mot clé const devant la déclaration. Par exemple, si on souhaite définir une constante cst de type double égale à 10.3, il faut écrire const double cst = 10.3; Cette fois-ci, il s'agit d'une instruction donc il faut mettre le point-virgule. En outre, cette manière de créer les variables implique de réserver une zone mémoire pour stocker l'information (ce qui n'était pas nécessaire dans le cas précédent). En contre partie, cela permet de mieux typer les constantes. Dans le cadre de ce cours, nous nous limitons au C-ANSI, cette méthode ne sera donc pas utilisée : elle est mentionné ici à titre d'information. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Annexes 1.2.1 et 1.2.2 Note sur cette partie Les données 14-Apr-17 [Title of the course] Note sur cette partie Annexes 1.2.1 et 1.2.2 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations de base Langage C – Niveau 1 14-Apr-17 [Title of the course] Langage C – Niveau 1 Les opérations de base Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Plan de la partie Voici les chapitres que nous allons aborder: 14-Apr-17 Les opérations de base [Title of the course] Plan de la partie Voici les chapitres que nous allons aborder: La notion d’expression Les opérations arithmétiques Les opérations logiques Les opérateurs relationnels Le transtypage Les expressions complexes et les priorités entre opérateurs Note sur cette partie Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
La notion d’expression 14-Apr-17 Les opérations de base [Title of the course] La notion d’expression Expression – combinaison d’un opérateur et d’une ou deux données. Le résultat de l’évaluation d’une expression peut devenir une opérande pour une expression englobante. Dans la partie précédente, nous avons présenté comment le C permet de stocker et de manipuler les données au moyen des variables et des constantes. Dans cette partie, nous allons apprendre à manipuler ces données en utilisant des opérateurs. Pour cela, nous allons combiner un opérateur et une ou deux données (variables et/ou constantes) afin de former une expression. Lorsque cette expression est évaluée par le compilateur, elle produit un résultat qui peut devenir une opérande pour une expression englobante. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
La notion d’expression 14-Apr-17 Les opérations de bases [Title of the course] La notion d’expression Exemple int a = 10 + 3; Expression 1 10 + 3 Expression 2 a = 13 Prenons l'exemple de la ligne de code ci-dessous : int a = 10 + 3 ; La première expression, qui est évaluée, est « 10 + 3 » qui produit 13 et la seconde expression, qui est évaluée, est « a = 13 » qui a pour effet d'affecter 13 à la variable a Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations arithmétiques 14-Apr-17 Les opérations de base [Title of the course] Les opérations arithmétiques Les opérateurs Opérateur Opération + Addition − Signe / Soustraction * Multiplication / Division Le langage C permet naturellement d'effectuer des opérations arithmétiques sur des valeurs de différents types. Ces opérations sont codées par des symboles dont certains sont issus des mathématiques : le plus (+) permet d'effectuer l'addition ; le moins (–) est utilisé pour le changement de signe (dans ce cas, on le considère comme un opérateur unaire) et la soustraction et (dans ce cas, il se trouve dans la catégorie des opérateurs binaires) ; l'étoile (*) correspond à la multiplication ; le slash (/) permet d'effectuer une multiplication et une division ; le pourcent (%) permet de récupérer le reste d'une division entière. Par exemple, si on souhaite effectuer la multiplication de deux variables, a et b, de type float, valant respectivement 10 et 20, et mettre le résultat dans une variable c de type float, nous devons écrire float a = 10; float b = 20; float c = a * b ; % Reste division (modulo) float a = 10; float b = 20; float c = a * b; Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations arithmétiques 14-Apr-17 Les opérations de base [Title of the course] Les opérations arithmétiques Les conversions implicites Exemple : int a = 10; long b = 20; double c = a * b; 1 a → long Nous pouvons également effectuer des opérations entre des variables de types différents et stocker le résultat dans un autre type, le compilateur C effectuera les conversions nécessaires conformément au principe de converson implicite que nous avons évoqué dans la partie précédente. Si nous changeons l'exemple précédent pour effectuer une opération entre un int et un long et stocker le résultat dans un double, nous devons écrire int a = 10; long b = 20; double c = a * b ; 2 a * b (long) 3 a * b → double 4 c = 200.0 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations arithmétiques 14-Apr-17 Les opérations de base [Title of the course] Les opérations arithmétiques Les opérateurs combinés Opérateur Opération += Addition −= Soustraction *= Multiplication /= Division Le langage C propose quelques « raccourcis » afin d'alléger l'écriture des expressions. La première catégorie de raccourcis sont ceux qui concernent les opérations de cumul. Les symboles +, -, *, / et % peuvent être couplés au signe = pour donner les nouveaux symboles ci-dessous : +=, -=, *=, /= et %=. Ces nouveaux symboles signifient simplement qu'il faut effectuer l'opération +, -, *, / ou % entre les deux opérandes et stocker le résultat dans la première opérande. Par exemple, si on déclare une variable a de type int qui vaut initialement 10 et qu'on veut lui ajouter 5, nous pouvons écrire : int a = 10; a += 5; La valeur finale de a sera alors 15 %= Reste division (modulo) int a = 10; a += 20; // a = a + 20 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations arithmétiques 14-Apr-17 Les opérations de base [Title of the course] Les opérations arithmétiques Les opérateurs d’incrémentation et décrémentation Opérateur Opération ++ Incrémentation −− Décrémentation int a = 0; a++; // a = 1 a--; // a = 0 La seconde catégorie de raccourcis sont ceux qui concernent les opératons d'incrémentation et de décrémentation des variables. Ces opérations sont effectuées au travers des symboles ci-dessous : ++ et -- Par exemple, si on considère une variable a de type int qui est initialisée à 0, l'incrémentation et la décrémentation de la variable s'effectuera de la manière suivante : int a = 0 ; a++ ; /* on incrémente la variable */ a-- ; /* on décrémente la variable */ Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations arithmétiques 14-Apr-17 Les opérations de base [Title of the course] Les opérations arithmétiques Pré-incrémentation, Post-incrémentation Pré-décrémentation, Post-décrémentation Post Pré int a = 1; int b = 2; int c = a++ * b; int a = 1; int b = 2; int c = -a * b; 1 c = a * b 1 a = a - 1 Les symbole d'incrémentation et de décrémentation peuvent être placés avant ou après la variables à modifier : on parle alors de pré-incrémentation, post-incrémentation, pré-décrémentation et post-décrémentation. Cette nuance est très importante, lorsque l'expression globale fait intervenir d'autres symboles car elle permet de déterminer si l'incrémentation ou la décrémentation s'effectue avant ou après avoir évalué l'expression globale. Par exemple, si nous considérons les deux séries d'instructions ci-dessous, les valeurs de c et d seront totalement différentes : int a = 1; int b = 2; int c = (a++ * b); /* on place d'abord le produit de a par b dans c avant d'incrémenter a a vaut donc 2 et c vaut 2 */ int c = (++a * b); /* on effectue d'abord l'incrémentation de a avant de placer le produit de a par b dans c a vaut donc 2 et c vaut 4 2 a = a + 1 2 c = a * b Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations logiques 14-Apr-17 Les opérations de base [Title of the course] Les opérations logiques Les opérateurs Opérateur Opération & Et logique | Ou logique ^ Ou exclusif logique ~ Négation logique Le langage C propose des opérations logiques qui effectuent des traitements au niveau des bits de chaque variable. Les symbole correspondant à ces opérations sont les suivants : Le et commercial (&) permet de faire le « et logique » entre les bits de même poids de deux variables. Si nous considérons par exemple deux variables a et b de type int valant respectivement 12 et 10 et une troisième variable c de type int permettant de stocker le résultat de l'opération, nous obtenons le morceau de code c-dessous : int a = 12 ; int b = 10 ; int c = a & b ; c vaut alors 12 & 10 soit 11002 & 10102 ce qui donne 10002 soit 8 en décimal Remarque : on aurait pu initialiser c en écrivant directement int c = 12 & 10 ; la barre verticale (I) est utilisé pour faire le « ou logique » entre les bits de même poids de deux variables Si nous reprenons l'exemple précédent en remplaçant & par |, nous obtenons le morceau de code c-dessous : int c = a | b ; c vaut alors 12 | 10 soit 11002 | 10102 ce qui donne 11102 soit 14 en décimal Remarque : comme précédemment, on aurait pu initialiser c en écrivant directement int c = 12 | 10 ; l'accent circonflexe (^) correspond au « ou exclusif logique » entre les bits de même poids de deux variables Si nous utilisons encore le même exemple en remplaçant | par ^, nous obtenons le morceau de code c-dessous : int c = a ^ b ; c vaut alors 12 ^ 10 soit 11002 ^ 10102 ce qui donne 01102 soit 6 en décimal int c = 12 ^ 10 ; le tilde (~) est employé pour faire le « non logique » (l'inversion) de chaque bit d'une variable (à la différence des 3 opérateurs précédents, il s'agit d'un opérateurs unaires) Si nous considérons une variable a de type int, initialisée à 10 et une autre variable b de type int qui reçoit le non logique de a, nous obtenons le morceau de code c-dessous : int a = 10 ; int b = ~a ; c vaut alors ~10 soit ~10102 ce qui donne 01012 soit 5 en décimal Remarque : il est également possible d'initialiser b en écrivant directement int b = ~10 ; deux inférieurs (<<) permet de faire le décalage de N bits vers la gauche de tous les bits du premier opérande (N étant le second opérande) Si nous considérons deux variables a et b de type int, initialisées à 10 et à 3, et une autre variable c de type int qui recevra le résultat de l'opération, nous pouvons écrire int b = 3 ; int c = a << b Comme 10 = 10102 , le décalage de 3 bits vers la gauche provoque l'insertion de 3 zéro à gauche, ce qui donne 10100002=80 (c vaut donc 80 en décimal) Remarque : il est encore possible d'initialiser c en écrivant directement int c = 10 << 3; deux supérieurs (>>) permet de faire le décalage de N bits vers la droite de tous les bits du premier opérande (N étant le second opérande) Si nous considérons le même exemple que précédement en remplaçant « << » par « >> » , et en assignant 1 à b nous obtenons int b = 1 ; int c = a >> b Comme 10 = 10102 , le décalage de 1 bits vers la gauche donne 1012 = 5 (c vaut donc 5 en décimal) Remarque : comme précédement, il est possible d'initialiser c en écrivant directement int c = 10 >> 1; << Décalage (shift) à gauche >> Décalage (shift) à droite &=, |=, ^=, <<=, >>= Opérateurs combinés Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations logiques 14-Apr-17 Les opérations de base [Title of the course] Les opérations logiques Quelques exemples & ^ et ~ char a = 10; char b = 12; char c = a & b; 1010 (a = 10) & 1100 (b = 12) ------ 1000 (c = 8) char a = ~10; char b = 12; char c = a ^ b; 1010 (10) ------ 0101 (a = ~10 = 5) ^ 1100 (b = 12) 1001 (c = 9) Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations logiques 14-Apr-17 Les opérations de base [Title of the course] Les opérations logiques Quelques exemples << >> char a = 10; char b = a << 2; char a = 10; char b = a >> 2; 1 1 b = 8 a = 10 a = 10 b = 2 1 1 Le décalage à gauche peut conduire à des pertes d'informations. En effet, si la première opérande a une taille de T bits, son bit de poids fort est poussé vers la gauche, autrement vers l'extérieur : il est donc perdu comme le montre le schéma ci-dessous : Considérons par exemple une variable a de type char initialisé de la manière suivante : char a = 240 << 2 ; Comme 240 = 111100002, la variable a contiendra 111100002 << 2 soit 110000002 qui est égal à 192. A l'instar de l'opération de décalage vers la gauche, l'opération de décalage vers la droite peuvent également conduire à des pertes d'informations. Si la première opérande a une taille de T bits, son bit de poids faible est poussé vers la droite, autrement vers l'extérieur : il est donc perdu Considérons cette fois-ci la variable a de type char initialisé de la manière suivante : char a = 10 >> 2 ; Comme 10 = 000010102, la variable a contiendra 000010102 >> 2 soit 000000102 qui est égal à 2 Remarquez les pertes de données ! Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations relationnelles 14-Apr-17 Les opérations de base [Title of the course] Les opérations relationnelles Les opérateurs Opérateur Opération == Egalité != Inégalité > Strictement supérieur < Strictement inférieur Le langage C permet d'effectuer des comparaisons entre deux opérandes : == permet de tester si deux opérandes sont égales != permet de tester si deux opérandes sont différentes > est utilisé pour tester si la première opérande est strictement plus grande que la seconde < est utilisé pour vérifier si la première opérande est strictement plus petite que la seconde >= teste si la première opérande est supérieure ou égale à la seconde <= vérifie si la première opérande est inférieure ou égale à la seconde Le résultat d'une opération de comparaison est un nombre entier qui prendre deux valeurs : 0 si la relation est vérifiée 1 si le relation n'est pas vérifiée >= Supérieur ou égal <= Inférieur ou égal Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations relationnelles 14-Apr-17 Les opérations de base [Title of the course] Les opérations relationnelles Exemples int a = 10; int b = 3; int c; c = a == b relation fausse, c = 0 c = a != b relation vraie, c = 1 c = a > b relation vraie, c = 1 Par exemple, si nous considérons deux variables a et b de type int, initialisées avec les valeurs 10 et 3, et une variable c qui recueille les valeurs des différents tests, nous pouvons écrire : int a = 10; int b = 3; int c = a == b; /* relation fausse, c = 0 */ c = a != b ; /* relation vraie, c = 1 */ c = a > b; /* relation vraie, c = 1 */ c = a < b; /* relation fausse, c = 0 */ c = a >= b; /* relation vraie, c = 1 */ c = a <= b; /* relation fausse, c = 0 */ Remarques : dans cet exemple, nous avons effecté successivement différentes valeurs à la variable c, chaque valeur écrasant (effaçant) la précédente ; nous n'avons déclaré c qu'une seule fois, sinon le compilateur produit une erreur. c = a < b relation fausse, c = 0 c = a >= b relation vraie, c = 1 c = a <= b relation fausse, c = 0 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les opérations relationnelles 14-Apr-17 Les opérations de base [Title of the course] Les opérations relationnelles Les opérateurs Opérateur Opération && Et logique || Ou logique ! Négation logique int a = 10; int b = 3; int c = (a != b && a > b); // c = 1 car 10 != 3 ET 10 > 3 Les opérations relationnelles que nous avons décrites, peuvent être combinés entre elle pour former des expressions relationnels complexes. Pour cela, nous utilisons des opérateurs logiques différents de ceux utiliser pour manipuler les bits : L'opérateur && permet d'effectuer un « et logique » entre deux relations L'opérateur || permet d'effectuer un « ou logique » entre deux relations L'opérateur ! permet d'effectuer un « non logique » d'une relation En C, il n'existe pas d'opérateur pour effectuer un « ou exclusif » entre deux relations Si nous reprenons l'exemple précédent, nous pouvons par exemple écrire : int a = 10; int b = 3; /* comme 10 != 3 et 10 > 3 alors c = 1 */ int c = a != b && a > b; Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Le transtypage Conversion implicite int a = 10; long b = a; 14-Apr-17 Les opérations de base [Title of the course] Le transtypage Conversion implicite Conversion explicite (cast) int a = 10; long b = a; (typeSouhaité)donnée char a = 10; double b = (double)a; Dans la partie précédente, nous avons vu que le compilateur C peut effectuer des conversion implicite lorsque des expressions font intervenir des données de type différents. Il est parfois nécessaire de spécifier de manière explicite au compilateur C, qu'un donnée doit être convertie d'un type vers un autre. Cette opération est appelée le transtypage ou la conversion explicite. D'un point de vue syntaxique, elle s'effectue simplement en mettant le type souhaité entre parenthèse et devant la donnée à convertir (typeSouhaité) donnée_à_caster Par exemple, si on considère une variable de a de type char qui est initialisée à 10 et une variable b de type double, nous pouvons écrire char a = 10 ; /* on caste a en double */ double b = (double) a ; Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les expressions complexes et les priorités entre opérateurs 14-Apr-17 Les opérations de base [Title of the course] Les expressions complexes et les priorités entre opérateurs L’opération d’affectation Evaluation d’une expression R-value : Droite de l’affectation Partie évaluée L-value : Gauche de l’affectation Partie qui reçoit le résultat de la R-value Dans la partie précédente, nous avons vu que le compilateur C peut effectuer des conversion implicite lorsque des expressions font intervenir des données de type différents. Il est parfois nécessaire de spécifier de manière explicite au compilateur C, qu'un donnée doit être convertie d'un type vers un autre. Cette opération est appelée le transtypage ou la conversion explicite. D'un point de vue syntaxique, elle s'effectue simplement en mettant le type souhaité entre parenthèse et devant la donnée à convertir (typeSouhaité) donnée_à_caster Par exemple, si on considère une variable de a de type char qui est initialisée à 10 et une variable b de type double, nous pouvons écrire char a = 10 ; /* on caste a en double */ double b = (double) a ; Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les expressions complexes et les priorités entre opérateurs 14-Apr-17 Les opérations de base [Title of the course] Les expressions complexes et les priorités entre opérateurs Priorité des opérateurs ( ) − ! ~ ++ −− sizeof * / % + − >> << < > <= => == != & Les différentes opérations que nous avons présenté dans cette partie peuvent être utilisés dans des expressions complexes. A l'instar des expressions mathématiques, les parenthèses permettent de spécifier l'ordre dans lequel il faut interpréter les expressions. A défaut de parenthèse, les opérateurs sont évalués dans l'ordre de la priorité et s'il existe plusieurs opérateurs d'un même niveau de priorité alors l'expression est simplement évalué de selon l'ordre de précédence (l'ordre dans lequel on associe les opérateurs et les opérandes) qui est la plus part du temps de gauche à droite. Le tableau de priorité des expressions est le suivant : parenthèse ( ) gauche à droite opérateur unaire - ! ~ ++ -- sizeof droite à gauche multiplicatif * / % gauche à droite additif + - gauche à droite décalage >> << gauche à droite relationnel < > <= >= gauche à droite inégalité/égalité == != gauche à droite ET logique & gauche à droite XOR logique ^ gauche à droite OU logique | gauche à droite ET relationnel && gauche à droite OU relationnel || gauche à droite affectation = droite à gauche | && || = Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Annexes 1.3.1, 1.3.2 et 1.3.3 Note sur cette partie 14-Apr-17 Les opérations de base [Title of the course] Note sur cette partie Annexes 1.3.1, 1.3.2 et 1.3.3 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les structures de contrôle 14-Apr-17 [Title of the course] Langage C – Niveau 1 Les structures de contrôle Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Plan de la partie Voici les chapitres que nous allons aborder: 14-Apr-17 Les structures de contrôle [Title of the course] Plan de la partie Voici les chapitres que nous allons aborder: L’intérêt des structures de contrôle « if … else … » et l’opérateur conditionnel (?) « switch … case …» et le break « while » « do … while » « for » et l’opérateur séquentiel (,) Le break, le continue et les boucles Les labels et l’instruction goto Note sur cette partie Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
L’intérêt des structures de contrôle 14-Apr-17 Les structures de contrôle [Title of the course] L’intérêt des structures de contrôle Exécution séquentielle Restrictif Structures de contrôle Sauts dans le programme Types de structures de contrôle Sauts Conditionnels Boucles Saut Inconditionnels Les connaissances que nous avons acquises jusqu'à présent nous permettent de déclarer des variables de différents types et des constantes de manipuler ces données aux moyens d'opérateurs L'exécution de ces différentes instructions (déclaration, affectation, évaluation d'expression) s'effectue de manière séquentiel ce qui est assez limitatif pour programmer des applications. Le langage C est donc doté d'autres instructions, appelées structures de contrôle, qui permettent de casser cette exécution séquentiel en effectuant des sauts dans le programme. Ces structures de contrôle peuvent être classés en trois grandes catégories : les sauts conditionnels ( if ... else , switch ... case ); les boucles (while , do ... while , for) ; les sauts inconditionnels (goto, continue, break). Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« if … else … » et l’opérateur conditionnel (?) 14-Apr-17 Les structures de contrôle [Title of the course] « if … else … » et l’opérateur conditionnel (?) if … else … if (condition) instruction1; else instruction2; condition : vrai (!0) ou faux (0) instruction1 : Exécutée si condition vraie instruction2 : Exécutée si condition fausse La structure « if ... else » est l'implantation en C de la structure « si ... alors ... sinon » en algorithmique. Sa syntaxe est la suivante : if (condition) instruction1 ; /* si condition vraie */ else instruction2 ; /* si condition fausse */ Cette structure comporte plusieurs éléments : condition est un test (une expression relationnelle) qui sera considérée comme fausse si elle retourne 0 et comme vraie si elle retourne un résultat non nul. instruction1 est exécutée si la condition est vraie (cette instruction n'est pas précédée d'un « then » car il est sous-entendu) ; instruction2 est exécutée si la condition est fausse. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« if … else … » et l’opérateur conditionnel (?) 14-Apr-17 Les structures de contrôle [Title of the course] « if … else … » et l’opérateur conditionnel (?) Mode de fonctionnement de la structure if…else… Début oui condition !=0 instruction1 non instruction2 Fin Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« if … else … » et l’opérateur conditionnel (?) 14-Apr-17 Les structures de contrôle [Title of the course] « if … else … » et l’opérateur conditionnel (?) Exemple : if … else int a = 10; if (a > 5) // Test 1 { printf ("a > 5"); // Si 1er test positif } else if (a < 5) // Test 2 printf ("a < 5"); // Si test 1 nég. et // test 2 positif else printf ("a == 5"); // Si tests 1 et 2 nég. Pour illustrer l'utilisation de cette structure, nous pouvons considérer le cas du code ci-dessous qui affiche un message différent selon le résultat du test effectué sur la variable a Remarque : printf est une instruction dont nous détaillerons le fonctionnement un peu plus tard. A ce niveau, vous devez simplement retenir qu'une chaîne de caractères placée entre guillemets et entre parenthèses est affichée à l'écran grâce à la fonction printf et que l'utilisation de cette fonction nécessite l'écriture de « #include <stdio.h> » au début du code. La structure ne peut contenir qu'une seule instruction que ce soit dans la section « then » (qui est sous-entendu) que dans la section « else ». Si vous placez plus d'une instruction entre le « if » et le « else », le compilateur retournera un message d'erreur. Si vous souhaitez exécuter plusieurs instructions dans la section « then » ou la section « else », vous devez les placer dans un bloc entre accolades : La section « else » est facultative, autrement dit si aucune instruction ne doit être exécutée lorsque la conditon est fausse, il suffit simplement d'écrire les instructions ci-dessous : if (condition) instruction; ou { instruction1; instruction2; ... } Il est possible d'imbriquer des structures « if ... else », les unes dans les autres selon les besoin du programme. On peut alors obtenir ce type de structure où on peut remarquer que la seconde structure « if ... else » est vue comme une seule instruction par la première structure « if ... else » qui l'englobe Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« if … else … » et l’opérateur conditionnel (?) 14-Apr-17 Les structures de contrôle [Title of the course] « if … else … » et l’opérateur conditionnel (?) L’opérateur conditionnel (?) N’est pas une structure de contrôle Dans certains cas, peut remplacer une structure if...else La structure « if ... else » est l'implantation en C de la structure « si ... alors ... sinon » en algorithmique. Sa syntaxe est la suivante : if (condition) instruction1 ; /* si condition vraie */ else instruction2 ; /* si condition fausse */ Cette structure comporte plusieurs éléments : condition est un test (une expression relationnelle) qui sera considérée comme fausse si elle retourne 0 et comme vraie si elle retourne un résultat non nul. instruction1 est exécutée si la condition est vraie (cette instruction n'est pas précédée d'un « then » car il est sous-entendu) ; instruction2 est exécutée si la condition est fausse. (condition) ? (valeur si vrai) : (valeur si faux); Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« if … else … » et l’opérateur conditionnel (?) 14-Apr-17 Les structures de contrôle [Title of the course] « if … else … » et l’opérateur conditionnel (?) Exemple : opérateur conditionnel int a = 10; int b = 20; int min = (a < b) ? a : b; // Si a < b, l’opérateur renvoie a, sinon b // ici min = 10 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« switch … case … » et le break 14-Apr-17 Les structures de contrôle [Title of the course] « switch … case … » et le break switch … case … variable : entier CONSTANTE_i : définies lors de la compilation déterminent sur quelle instruction brancher default : cas par défaut switch (variable) { case CONSTANTE_1: instruction1; break; case CONSTANTE_2: instruction2; default: instruction3; } La structure switch ... of est la traduction en langage C de la structure « cas ... parmi » de l'algorithmique. Sa syntaxe est la suivante : switch (variable) { case CONSTANTE_1 : instruction1; instruction2; ... case CONSTANTE_2 : instructionN1; instructionN2; default : instructionM1; instructionM2; } Cette structure prend en paramètre une variable qui est obligatoirement de type entier (char, unsigned char, ... unsigned long long). Cette variable est successivement testée (comparée) avec différentes constantes (soit des constantes définies par #define), soit des constantes écrite « en dur » dans le code) afin de déterminer sur quel ensemble d'instructions se brancher. Si aucune correspondance n'est établie, le branchement s'effectue alors sur les instructions correspondant au cas par défaut (default), s'il est défini. Nous remarquons que lorsqu'un cas correspond, le branchement s'effectue sur la première instruction correspondant au traitement de ce cas, puis toutes les instructions suivantes jusqu'à la fin de la structure switch sont exécutées. Cela peut être très intéressant lorsqu'on veut associer le même traitement à plusieurs cas de figure, cela évite ainsi de retaper plusieurs fois les même instructions. Pour se rendre compte de ce phénomène, nous pouvons exécuter le code ci-dessous et modifier la valeur de la variable val. #include <stdio.h> main () unsigned int val = 0; /* variable à modifier */ switch (val) case 0 : printf ("val = 0\n"); case 1 : printf ("val = 1\n"); default : printf ("val est un entier\n"); printf ("instruction qui suit le switch\n"); Cependant, la plupart du temps, nous souhaitons implanter un traitement distinct pour chaque cas. Pour cela, nous devons utiliser le mot clé break, une instruction de saut inconditionnel qui provoque le branchement directement à la fin de la structure switch (sur l'instruction qui suit la structure de contrôle switch. La nouvelle syntaxe de la structure switch est alors la suivante : break; Remarques : il n'est pas nécessaire de placer un break après la dernière instruction de la section « default ». il n'est pas obligatoire de placer des break dans tous les cases : on les place en fonction de nos besoins. Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« switch … case … » et le break 14-Apr-17 Les structures de contrôle [Title of the course] « switch … case … » et le break Début Mode de fonctionnement de la structure switch…case… valeur == CONSTANTE_1 oui instruction1 non break valeur == CONSTANTE_2 oui instruction2 La structure switch ... of est la traduction en langage C de la structure « cas ... parmi » de l'algorithmique. Sa syntaxe est la suivante : switch (variable) { case CONSTANTE_1 : instruction1; instruction2; ... case CONSTANTE_2 : instructionN1; instructionN2; default : instructionM1; instructionM2; } Cette structure prend en paramètre une variable qui est obligatoirement de type entier (char, unsigned char, ... unsigned long long). Cette variable est successivement testée (comparée) avec différentes constantes (soit des constantes définies par #define), soit des constantes écrite « en dur » dans le code) afin de déterminer sur quel ensemble d'instructions se brancher. Si aucune correspondance n'est établie, le branchement s'effectue alors sur les instructions correspondant au cas par défaut (default), s'il est défini. non instruction3 Fin Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« switch … case … » et le break 14-Apr-17 Les structures de contrôle [Title of the course] « switch … case … » et le break Exemple : switch … case switch (a) // Variable à tester { case 1: case 2: // Instructions à exécuter si a = 1 ou 2 break; case 3: // Instructions à exécuter si a = 3 // case 4 + b: Erreur car 4 + b pas constant default: // Instructions à exécuter autrement } Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« while » La boucle while while (condition) instruction; condition : 14-Apr-17 Les structures de contrôle [Title of the course] « while » La boucle while while (condition) instruction; condition : vrai (!0) ou faux (0) instruction : Tant que condition vraie La boucle « while » est la correspondance en C de la boucle « tant que » en algorithmique. Sa syntaxe est la suivante : while (expression relationnelle) instruction ; La boucle while exécute que l'instruction qui est située juste en dessous d'elle tant que l'expression relationnelle est vraie (on parle alors de condition d'arrêt). L'expression est donc évaluée au moins une fois mais l'instruction peut ne jamais être exécutée. Si on souhaite exécuter plusieurs instructions dans la boucle, nous devons les placer dans un bloc (entre des accolages) afin d'obtenir une instruction composée. Nous obtenons alors l'ensemble d'instruction ci-dessous : { instruction1 ; /* Dans le while */ instruction2 ; /* Dans le while */ } instruction3 ; /* Pas dans le while */ Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« while » Mode de fonctionnement de la structure while 14-Apr-17 Les structures de contrôle [Title of the course] « while » Mode de fonctionnement de la structure while Début oui condition != 0 instruction non La structure switch ... of est la traduction en langage C de la structure « cas ... parmi » de l'algorithmique. Sa syntaxe est la suivante : switch (variable) { case CONSTANTE_1 : instruction1; instruction2; ... case CONSTANTE_2 : instructionN1; instructionN2; default : instructionM1; instructionM2; } Cette structure prend en paramètre une variable qui est obligatoirement de type entier (char, unsigned char, ... unsigned long long). Cette variable est successivement testée (comparée) avec différentes constantes (soit des constantes définies par #define), soit des constantes écrite « en dur » dans le code) afin de déterminer sur quel ensemble d'instructions se brancher. Si aucune correspondance n'est établie, le branchement s'effectue alors sur les instructions correspondant au cas par défaut (default), s'il est défini. Fin Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« while » Exemple : int i = 0; while (i < 10) // Condition à tester 14-Apr-17 Les structures de contrôle [Title of the course] « while » Exemple : int i = 0; while (i < 10) // Condition à tester { printf("%d\n", i); // Ecrit i à l’écran i++; } // Ecrit à l’écran les chiffres 0 à 9 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« do … while » La boucle do…while do instruction; while (condition); 14-Apr-17 Les structures de contrôle [Title of the course] « do … while » La boucle do…while do instruction; while (condition); condition : vrai (!0) ou faux (0) instruction : Exécutée au moins une fois Et tant que condition vraie La boucle « do ... while » correspond à la boucle « répéter jusqu'à » en algorithmique. Sa syntaxe est la suivante : do instruction ; while (expression relationnelle) ; La boucle do ... while n'accepte qu'une seule instruction entre le do et le while. Cette instruction est exécutée au moins une fois avant que l'expression ne soit évaluée. Si on souhaite exécuter plusieurs instructions dans la boucle, nous devons comme précédemment les placer dans un bloc (entre des accolages) afin d'obtenir une instruction composée. Nous obtenons alors l'ensemble d'instruction ci-dessous : { instruction1 ; /* Dans le while */ instruction2 ; /* Dans le while */ } Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« do … while » Mode de fonctionnement de la structure do…while 14-Apr-17 Les structures de contrôle [Title of the course] « do … while » Mode de fonctionnement de la structure do…while Début instruction oui condition != 0 non Fin Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« do … while » Exemple : int i = 11; do { 14-Apr-17 Les structures de contrôle [Title of the course] « do … while » Exemple : int i = 11; do { printf("%d\n", i); // Ecrit i à l’écran i++; } while (i < 10); // Condition à tester // Ecrit à l’écran le chiffre 11 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« for » et l’opérateur séquentiel (,) 14-Apr-17 Les structures de contrôle [Title of the course] « for » et l’opérateur séquentiel (,) La boucle for for (initialisation; condition; modification) instruction; Variable d'itération initialisation : affectation de valeur à la variable condition : vrai (!0) ou faux (0) modification : Modification de la variable d’itération La boucle « for » correspond à la boucle « pour » en algorithmique. Sa syntaxe est la suivante : for (initialisation; condition; modification) instruction ; Son fonctionnement s'appuie généralement sur une variable d'itération : initialisation correspond à l'affectation d'une valeur de départ à cette variable ; conditon est une expression qui teste, par exemple, si la variable n'a pas atteint un certain seuil (tant que la condition est vraie, on reste dans la boucle for) ; modification est simplement une opération qui change la valeur de la variable d'itération (cela peut être un simple ++ pour effectuer une incrémentation) . Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« for » et l’opérateur séquentiel (,) 14-Apr-17 Les structures de contrôle [Title of the course] « for » et l’opérateur séquentiel (,) Mode de fonctionnement de la structure for Début initialisation oui condition != 0 instruction non modification Fin Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« for » et l’opérateur séquentiel (,) 14-Apr-17 Les structures de contrôle [Title of the course] « for » et l’opérateur séquentiel (,) Exemple : int i; for (i = 10; i < 100; i += 10) { printf("%d\n", i); // Ecrit i à l’écran } // Ecrit à l’écran les chiffres de 10 à 90 // avec un pas de 10 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
« for » et l’opérateur séquentiel (,) 14-Apr-17 Les structures de contrôle [Title of the course] « for » et l’opérateur séquentiel (,) L’opérateur séquentiel (,) initialisation et modification peuvent contenir plusieurs instructions Séparées par des virgules (,) int i, j; for (i = 1, j = 2; (i < 4)&&(j < 10); i++, j += 2) printf ("i=%u et j=%u\n", i, j); Les sections « Initialisation » et « modification » ne comportent généralement qu'une instruction. Si on souhaite placer plusieurs instructions, nous devons les séparer par une virgule (,) car le point-vigule est déjà utilisé pour séparer les 3 sections de la structure de contrôle for. Nous pouvons par exemple utiliser la virgule pour initialiser et incrémenter deux variables à chaque tour. Nous pouvons également utiliser une expression relationnelle complexe (utilisant i et j) comme condition d'arrêt de la boucle. #include <stdio.h> main () { unsigned int i; unsigned int j; for (i=1,j=2 ;(i<4)&&(j<10); i++,j+=2) printf ("i=%u et j=%u\n", i, j); } Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Le break, le continue et les boucles 14-Apr-17 Les structures de contrôle [Title of the course] Le break, le continue et les boucles L’instruction break et les boucles Permet de quitter la boucle prématurément int i, j = 0; for (i = 0; i < 10; i++) { if (j > 4) // on quite la boucle break; j++; } La boucle « do ... while » correspond à la boucle « répéter jusqu'à » en algorithmique. Sa syntaxe est la suivante : do instruction ; while (expression relationnelle) ; La boucle do ... while n'accepte qu'une seule instruction entre le do et le while. Cette instruction est exécutée au moins une fois avant que l'expression ne soit évaluée. Si on souhaite exécuter plusieurs instructions dans la boucle, nous devons comme précédemment les placer dans un bloc (entre des accolages) afin d'obtenir une instruction composée. Nous obtenons alors l'ensemble d'instruction ci-dessous : { instruction1 ; /* Dans le while */ instruction2 ; /* Dans le while */ } Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Le break, le continue et les boucles 14-Apr-17 Les structures de contrôle [Title of the course] Le break, le continue et les boucles L’instruction continue et les boucles Permet de passer à l’itération suivante dans une boucle int i, j = 0; for (i = 0; i < 10; i++) { if (j == 4) continue; // la suite ne sera pas // exécutée si j == 4 j++; } Nous pouvons aussi combiner la structure for avec une structure « if ... else » et une instruction continue, si on souhaite interrompre le traitement d'une itération, lorsqu'une condition particulièrese produit. Nous pouvons par exemple implanter un code tel que celui ci-dessous (l'explication reste valable dans le cas d'un boucle while ou d'une boucle do ... while) : #include <stdio.h> main () { int i; int j=0; for (i=0; i<10; i++) j++; if (j>4) printf ("on passe a l'iteration suivante car j>4\n"); continue; } printf ("iteration %u : j vaut %u\n", i, j); Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Les labels et l’instruction goto 14-Apr-17 Les structures de contrôle [Title of the course] Les labels et l’instruction goto Label : étiquette identifiant une instruction goto permet de « sauter » inconditionnellement vers un label Utilisation fortement déconseillée // boucle infinie mon_label: instruction_1; instruction_2; goto mon_label; Nous pouvons aussi combiner la structure for avec une structure « if ... else » et une instruction continue, si on souhaite interrompre le traitement d'une itération, lorsqu'une condition particulièrese produit. Nous pouvons par exemple implanter un code tel que celui ci-dessous (l'explication reste valable dans le cas d'un boucle while ou d'une boucle do ... while) : #include <stdio.h> main () { int i; int j=0; for (i=0; i<10; i++) j++; if (j>4) printf ("on passe a l'iteration suivante car j>4\n"); continue; } printf ("iteration %u : j vaut %u\n", i, j); Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
14-Apr-17 Les structures de contrôle [Title of the course] Note sur cette partie Annexes 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.4.8, 1.4.9 et 1.4.10 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Résumé du module Représentation des données en C 14-Apr-17 Langage C - Niveau 1 [Title of the course] Résumé du module Représentation des données en C Structures de contrôle Historique des langages de programmation Opérateurs de base Présentation des environnements de développement Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Pour aller plus loin… Si vous voulez approfondir vos connaissances: 14-Apr-17 Langage C - Niveau 1 [Title of the course] Pour aller plus loin… Si vous voulez approfondir vos connaissances: Publications Modules de cours Langage C – Niveau 2 Langage C – Niveau 3 Langage C – Niveau 4 Langage C – Niveau 5 Langage C – Niveau 6 Le langage C : Norme ANSI Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Vous avez suivi avec succès le module de cours 14-Apr-17 [Title of the course] Félicitations Vous avez suivi avec succès le module de cours Langage C - Niveau 1 Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.
Fin Langage C - Niveau 1 14-Apr-17 [Title of the course] Copyright © 2004-2005 NameOfTheOrganization. All rights reserved.