Programmation en Langage C Laurent Signac https://deptinfo-ensip.univ-poitiers.fr 5 octobre 2018 Programmation en C 2 Table des matières I Codage 5 1 Changement de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2 Nombres négatifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 3 Virgule flottante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 II Premiers pas 9 1 Environnement de programmation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2 Programme minimal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 4 Tests, boucles et fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 IIILe C, plus en détails 17 1 Éléments de syntaxe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2 Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3 Opérateurs et expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4 Entrées sorties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 5 Instructions et expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 6 Instructions et structures de contrôle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 7 Fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 8 Fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 9 Pointeurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 10 Tableaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 11 Chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 12 Retour sur les fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 13 Stuctures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 14 Énumérations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 15 Champs de bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 16 Unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 17 Allocation dynamique de mémoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 18 Préprocesseur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 IVExercices 45 3 Programmation en C Notations Danscesupportdecours,lesprogrammessontgénéralementencadrésettypographiésenutilisantunepolicemachine à écrire. Sauf si une indication contraire est donnée, le langage utilisé est le langage C. Objectif L’objectifdececoursestd’acquérirdesbasesenprogrammationC.Lapartiealgorithmiqueayantétévueenpremière année (avec la langage Python), nous nous concentrerons ici sur les possibilités offertes par le C. Par la suite, vous pourrez être amenés à utiliser le C, entre autres : 1. pour des questions d’efficacité des programmes (un programme écrit en C est généralement bien plus rapide qu’un programme écrit en Python, bien qu’il soit souvent plus long à écrire). 2. pour des raisons d’environnement : sur un micro-contrôleur, le C est souvent le seul langage supporté par la plate-forme de développement, etc... Ressources Le langage C est suffisamment ancien et répandu pour que les ressources ne manquent pas. Dans les ressources en ligne, nous pouvons citer : — OpenClassrooms(exsiteduzéro)http://fr.openclassrooms.com/informatique/cours/apprenez-a-programmer-en-c En ce qui concerne les ouvrages, très nombreux, citons par exemple : — Le langage C, norme Ansi, de B. Kerninghan et D. Ritchie — Programmer en Langage C, de C. Delannoy — Méthodologie de le programmation en C, de A. Braquelaire — LeCen20h,deE.BerthomieretD.Schang(celivreestunframabookquevouspouveztéléchargerlibrement). Licence CetravailestmisàdispositionsouslicenceCreativeCommonsby sa(paternité,partagesouslesmÃamesconditions). http://creativecommons.org/licenses/by-sa/3.0 4 Chapitre I Codage 1 Changement de base L’écriture d’un nombre en base b est formée à partir de b symboles, appelés chiffres. Les 10 chiffres de la base 10 sont par exemple : 0,1,2,3,4,5,6,7,8 et 9. Si l’écriture d’un nombre en base b est : c c ...c c (les c sont les chiffres), sa valeur sera : n n−1 1 0 i v(c )×bn+v(c )×bn−1+...+v(c )×b1+v(c )×b0 n n−1 1 0 où v(c ) est la valeur associée au chiffre (symbole) c . La valeur du symbole 9 en base 10 est par exemple neuf. i i Généralement, pour une base b inférieure à 10, on reprend les même chiffres qu’en base 10, avec les mêmes valeurs (maisonn’utilisequelesbpremierschiffres).Pourunebasebsupérieureà10,onajouteauxchiffresordinairesd’autres symboles, comme des lettres. La base 16 utilise par exemple les 16 chiffres suivantes : 0,1,2,...,9,A,B,C,D,E,F. La valeur de B, par exemple, sera alors onze. Voici quelques exemples d’interprétation des nombres. La base est indiquée en indice à la fin du nombre. En l’absence de cet indication, c’est la base 10 qui est utilisée. 1011010| =1×26+0×25+1×24+1×23+0×22+1×21+0×20 =90 2 5A| =5×161+10×160 =90 16 Blague... Pourquoi les informaticiens confondent Halloween et Noël? Parce que OCT31 est égal à DEC25. Pour passer de la base 10 à la base 2, on peut procéder par divisions entières successives (par 2). Voici comment trouver l’écriture binaire de 90 : 90 ÷2 = 45 reste 0 45 ÷2 = 2 reste 1 22 ÷2 = 11 reste 0 11 ÷2 = 5 reste 1 5 ÷2 = 2 reste 1 2 ÷2 = 1 reste 0 1 ÷2 = 0 reste 1 La séquence des restes successifs, lue du dernier au premier reste donne : 1011010 qui est l’écriture en base 2 de 90. On peut procéder de même en base 16 (en faisant des divisions par 16). Les restes sont alors entre 0 et 15, ce qui correspond bien aux valeurs des chiffres de la base 16. On peut coder de la même manière les nombres non entiers. Chaque chiffre placé après la virgule est associé à une puissance négative de la base : 101,011| =1×22+0×21+1×20+0×2−1+1×2−2+1×2−3 =5+0,25+0,125=5,375 2 Lepassagedelabase10àlabase2,pourlapartiefractionnaire,estréaliséparmultiplicationssuccessives(onreporte la partie fractionnaire de chaque résultat sur la ligne suivante, et les parties entières des résultats obtenus forment 5 Programmation en C l’écriture en base 2). Voici comment écrire 0,6875 en base 2 : 0,6875 ×2= 1,375 0,375 ×2= 0,75 0,75 ×2= 1,5 0.5 ×2= 1 Nous prenons les parties entières des résultats dans l’ordre où elles sont obtenues : 1011. Donc 0,6875=0,1011| . 2 Développement binaires infinis Notonsquesil’écritured’unnombrenonentierenbase2estfinie,ceseraaussilecasenbase10(carlespuissances négatives de 2 ont toutes une écriture décimale finie). En revanche, si l’écriture décimale est finie, l’écriture en base 2 ne le sera pas forcément (elle sera alors périodique). Par exemple : 0,2 ×2= 0,4 0,4 ×2= 0,8 0,8 ×2= 1,6 0,6 ×2= 1,2 0,2 ×2= ... En conséquence : 0,2=0,00110011... Base 2 et base 16 Labase2etlabase16sonttrèsliées(car16estjustementunepuissancede2).Ainsi,àchaquegroupede4chiffres binaires (valeur de 0 à 15) correspond exactement un chiffre hexadécimal. Le passage de la base 2 à la base 16 est donc très simple : 1011010101| = 10 1101 0101| =2D5| 2 2 16 |{z} |{z} |{z} 2 13 5 Blague... Il y a 10 sortes de gens dans le monde. Ceux qui connaissent le binaire et les autres. 2 Nombres négatifs Lesnombresnégatifssontreprésentésenbinaireenutilisantlaméthodeducomplémentàdeux,quipermetderéaliser simplement des opérations arithmétiques directement sur le codage. Pour représenter un nombre avec la méthode du complément à 2, on choisit auparavant le nombre de bits maximum qui seront occupés par le code. Les valeurs typiques sont multiples de 8. Coder les nombres en complément à 2 sur 8 bits revient à partager les 256 codes possibles en deux parties. Ceux dont le bit de poids fort est 0 représenteront les nombres positifs de 0 à 127 (codage immédiat en base 2 avec les 7 bits restants). Ceux dont le bit de poids fort est 1 représenteront les nombres négatifs de -128 à -1. Danslecasd’unnombrenégatifn,onobtientlecomplémentà2denencalculantlareprésentationbinairedunombre 256−|n|. Cette représentation est obtenue rapidement en écrivant sur 8 bits la représentation binaire de la valeur absolue de n, puis en inversant les 0 et les 1, puis en ajoutant 1 : Exemple de codage en complément à deux Nous souhaitons coder le nombre -66 en complément à deux sur 8 bits. On commence par écrire sa valeur absolue en binaire, sur 8 bits : 01000010 Puis on échange les 0 et les 1 : 10111101 Puis on ajoute 1 (attention aux éventuelles retenues) : 10111110 6 Notes de cours, Ensip, Mee2 Le résultat est le codage en complément à 2 sur 8 bits de −66. On remarque que c’est aussi l’écriture binaire de 256−66=190. 3 Virgule flottante Nousavonsvuqu’ilétaitpossibledereprésenterlesnombresàvirguleenbinaire.Cependant,l’utilisationtrèsfréquente descalculsàl’aidedenombresnonentiers,etlesoucisdecodercesnombresenunminimumdebitsadonnénaissance au codage en virgule flottante. Un nombre à virgule flottante est codé par trois nombres binaires appelés signe, mantisse et exposant, qui ont tous une taille maximum finie, en nombre de chiffres. La norme en vigueur pour le codage en virgule flottante est la norme Ieee754 que nous allons détailler. Un nombre décimal N à stocker doit d’abord être écrit (en binaire) sous la forme (−1)S ×1.m×2e. En d’autres termes, on écrit N en binaire (avec une virgule), puis on place cette virgule juste après le premier 1, et on en déduit l’exposant : 11001.111101= 1.100111101×24 0.001101= 1.101×2−3 Les nombres à coder sont donc : la partie décimale m, la valeur de l’exposant et le signe (0 pour un nombre positif et 1 pour un nombre négatif). Selon que les nombres sont en simple (32 bits) ou double (64 bits) précision, c’est la taille du codage de m, et la taille du codage de l’exposant qui varient. En simple précision, on utilise 8 bits pour coder l’exposant, et 23 bits pour m. En double précision on utilise 11 bits pour l’exposant et 52 pour m. De plus, l’exposant n’est pas codé directement. On lui ajoute 127 en simple précision et 1023 en double précision avant de le coder (pour obtenir un nombre positif). Ainsi, en simple précision, l’exposant -127 sera codé par 0, l’exposant 0 par 01111111 et l’exposant 128 par 11111111. Danslasuite,noussupposeronsquelecodageestensimpleprécision.Lesnombrenormaliséssontceuxpourlesquellesle codagedel’exposant(Edanslasuite1)vérifie0<E <255.LenombrereprésentévautalorsN =(−1)S×2E−127×1.m. Les nombres dénormalisés sont ceux pour lesquels E est nul alors que m non. Cette distinction permet de représenter des nombres plus petits que 2−126 ×1.m en spécifiant qu’un nombre dénormalisé vaut : 2−126 ×0.m. Si E = 0 et m=0,lecodereprésente0.Enfin,siE =255etm6=0,lecodenereprésentepasunnombre2 etsiE =255etm=0, la valeur codée est (−1)S∞. Le plus petit nombre non nul positif vaut : 2−126×0.0···01=2−149 ≈1.4013×10−45 | {z } 22 fois Le plus grand nombre positif vaut : 2127×1.1···1=2128−2104 ≈3.4×1038 | {z } 23 fois Entre deux nombres, il y a un «trou». Par exemple : 011111110 0···0=2127 | {z } 23 fois et le nombre suivant est : 011111110 0···01=2127+2104 | {z } 22 fois Par conséquent, entre ces deux nombres successifs, il y a un trou de dimension 2104 (!) sans aucun nombre. En résumé, le codage en simple précision permet de représenter de manière approchée les nombres entre −3.4×1038 et 3.4×1038, tout en atteignant des valeurs aussi petites (en valeur absolue) que 1.4×10−45. Il est important de retenir : — que c’est le codage le plus utilisé pour les nombres non entiers; — qu’ilreprésentelesnombresdemanièreapprochée,etqu’envirguleflottante,lescalculsnesont(pratiquement) jamais exacts. 1. Ànepasconfondreavece.Onaensimpleprécision:E=e+127. 2. NaN:not a number. 7 Programmation en C Flops Une indication de vitesse des processeurs donnée en flops (ou un de ses multiples) fait référence au nombre d’opérations en virgule flottantes par seconde (FLoating point Operations Per Second). L’ordinateur le plus rapide du monde (depuis novembre 2016, c’est le TaihuLight) a une vitesse estimée de 93,59 PetaFlops (1015) soit plus de 93 millions de milliards d’opérations en virgule flottante par seconde. Un ordinateur domestique atteint des vitesses de quelques dizaines de GigaFlops (109 Flops) 8 Chapitre II Premiers pas Dans ce chapitre, nous n’allons pas entrer dans le détail de chaque construction du C, mais présenter les éléments essentiels qui permettent de commencer à programmer. Nous entrerons dans les détails au chapitre suivant. 1 Environnement de programmation Actuellement, les salles sont équipées avec l’environnement wxDevC++. Il existe des alternatives intéressantes : — Code Blocks : http://www.codeblocks.org/ — Orwell DevC++ : http://orwelldevcpp.blogspot.com.au/ — Visual Studio Express (attention, le compilateur n’est plus MingW dans ce cas) Certainspréféreronsinstallerlecompilateurd’unepart(http://www.mingw.org/wiki/Getting_Started),etutiliser un autre éditeur comme : Notepad++, Geany ou Scite. Pourlesystèmegnu/Linux,lecompilateurestgénéralementgcc(ilestprobablementdéjàinstallésurvotredistribution outoutaumoinsfacilementinstallable).Lesenvironnementsdedéveloppementnemanquentpas:Emacs,Code Blocks, Geany,... Le contenu des programmes est le même quel que soit l’Edi1 que vous choisissez... 1.1 Utilisation de wxDevC++ Créer un nouveau programme avec wxDevC++ consiste à démarrer un nouveau projet (Fichiers/Nouveau Projet (fig.II.1). Au début, le type d’application à sélectionner sera Console Application. Après avoir donné un nom au projet (de préférence sans espace et sans accent), wxDevC++ ouvre une fenêtre (fig. II.2)contenantlefichierprincipalduprojet(quis’appellepardéfautmain.c).Aupremierenregistrement,nousaurons la possibilité de renommer ce fichier main.c avec un nom plus évocateur2 (fig. II.3). Nous pouvons modifier ce programme principal (fig.II.4), puis demander à wxDevC++ de construire un exécutable (menu Exécuter/Tout reconstruire). La compilation et l’édition de liens doivent se dérouler sans aucune erreur. Le programme peut alors être testé par le biais du menu Exécuter/Exécuter (fig.II.5) . 1.2 Programmer sous Linux Les différentes distributions Linux offrent un excellent confort de développement, une fois l’apprentissage de départ effectué. Un simple éditeur, comme Geany permet, sans configuration particulière, de commencer à programmer (fig. II.6). Le principe est toujours le même : construire le projet (compilation et édition de lien), puis tester (fig. II.7). 1. Un Edi (Ide en anglais) est un Environnement de Développement Intégré : un logiciel qui permet d’éditer du code et propose un accèsdirectauxoutilsdecompilation,test,analyse... 2. Iln’estpasabsurdedereprendrelenomduprojet. 9 Programmation en C Figure II.1 – Ouverture d’un nouveau projet Figure II.2 – Fichier C principal 10
Description: