COURS DE LANGAGE C. DIAO Oumar. Université de Rennes 1. Master 1

Dimension: px
Commencer à balayer dès la page:

Download "COURS DE LANGAGE C. DIAO Oumar. [email protected]. Université de Rennes 1. Master 1"

Transcription

1 COURS DE LANGAGE C DIAO Oumar [email protected] Université de Rennes 1 Master 1 théorie de l'information & cryptographie analyse numérique & modélisation Année universitaire

2 Table des matières Table des matières 1 Généralité du langage C Introduction Historique du langage C Fonctionnement du langage C Rappel sur les langages de programmation Compilation du langage C Exemple de compilation sous Linux Les mots-clés de C Les commentaires Les types de base Les entiers Les otants Les caractères Structure d'un programme en C Directives au préprocesseur Déclarations de variables Les fonctions Exemple d'un programme en C Les bases de la programmation en C Opérateurs de base Opérateurs arithmétiques Opérateurs relationnels Opérateurs booléens Opérateurs bit à bit Opérateur d'adresse Opérateur de conversion de type Opérateurs d'aectation Règles de priorité Principales fonctions d'entrées-sorties standard Fonction printf Fonction scanf Fonctions getchar et putchar Structure de contrôles Instruction if...else Instruction switch Instruction for Instruction while Instruction do...while Instruction break Instruction continue Instruction goto DIAO O. Cours de langage C

3 Table des matières 3 Les types composés Les tableaux Tableau unidimentinel Tableau multidimentinel Les structures Les champs de bits Les unions Les énumérations Les types synonymes avec typedef Fonction et types composés Les pointeurs Notion de pointeurs Déclaration d'un pointeurs Opérations sur les pointeurs Pointeurs et tableaux Allocation dynamique de la mémoire Pointeurs et fonctions Structures auto-référencées Gestion des chiers Ouverture et fermeture de chiers Ouverture d'un chier : fopen Fermeture d'un chier : fclose Lecture et écriture par caractères sur chier Lecture par caractères : fgetc Ecriture par caractères : fputc Relecture d'un caractère : ungetc Lecture et écriture par lignes sur chier Lecture par lignes : fgets Ecriture par lignes : fputs Entrées et Sorties formatées sur chiers Entrée formatée : fscanf Sortie formatée : fprintf Entrées-sorties binaires : fread et fwrite Positionnement dans un chier rewind, fseek et ftell Interaction entre C et les autres langages Interaction avec le système Exécution d'une commande ou d'un programme Programmation modulaire et automatisation Interaction avec Maple Bibliothèque standard #include <assert.h> : diagnostiques d'erreurs #include <complex.h> : gestion des nombres complexes #include <ctype.h> : manipulation de caractères #include <errno.h> : gestion des erreurs #include <fenv.h> : environnement à virgule ottante Gestion des erreurs ou exceptions DIAO O. Cours de langage C

4 Table des matières Gestion des arrondis Gestion des environnements #include <float.h> : paramétrage des nombres ottants #include <inttypes.h> : autres types entiers de taille xée #include <iso646.h> : alias d'opérateurs logiques et binaires #include <limits.h> : valeur limite des entiers #include <locale.h> : paramètres régionaux #include <math.h> : fonctions mathématiques #include <setjmp.h> : sauts non locaux #include <signal.h> : gestion des signaux #include <stdarg.h> : nombre variable d'arguments #include <stdbool.h> #include <stddef.h> #include <stdint.h> : version allégée de inttypes.h #include <stdio.h> : entrée/sortie standard #include <stdlib.h> : fonctions utilitaires Conversion de nombres Génération de nombres pseudoaléatoires Arithmétique sur les entiers Allocation dynamique de la mémoire Contrôle de processus Gestion de l'environnement et des signaux Trier un tableau et rechercher un élément #include <string.h> : chaînes de caractères (strings) Constantes et types Fontions de string.h #include <tgmath.h> : fonctions mathématiques génériques #include <time.h> : date et heure Fonctions de manipulation du temps Fonctions de conversion de date #include <wchar.h> et #include <wctype.h> : manipulation de caractères étendus DIAO O. Cours de langage C

5 1 Généralité du langage C 1.1 Introduction Le langage C est conçu pour de multiples utilisations comme : la programmation embarquée, le calcul numérique, les jeux vidéos, l'écriture de systèmes d'exploitation, etc... Il permet de gérer directement les ressources systèmes comme la mémoire. C'est pourquoi, on le qualie parfois de langage de bas niveau dans le sens où il peut être directement converti en langage machine (langage binaire). Il a beaucoup inuencé l'écriture de nombreux langages comme le C++, le java, le PHP. 1.2 Historique du langage C Le langage C est crée dans les années 70 par Denis Ritchie et Ken Thompson des Laboratoires Bell. A l'origine, le C est utilisé pour écrire, sur un DEC PDP-7, le système Unics (Uniplexed Information and Computing System) qui sera dénommé UNIX. Le C est dérivé du langage BCPL (Basic Combined Programming Language) de Martin Richards. Le C était limité à l'usage interne de Bell jusqu'au jour où Brian Kernighan et Denis Ritchie publièrent une première dénition du langage dans un ouvrage intitulé The C Programming Language. Grâce à sa puissance, le langage C devint rapidement très populaire. A partir des années 80, il fut standardisé et normalisé en 1989 par l'ansi (American National Standards Institute), en 1990 & 1999 par l'iso (International Organization for Standardization) et en 95 par l'iec (International Electrotechnical Commission). Le BCPL est un langage non typé, contrairement au langage C qui fournit diérents types de données (entier, nombre réel, caractère, etc.). 1.3 Fonctionnement du langage C Rappel sur les langages de programmation Pour un langage de programmation, il sera nécessaire d'opérer une opération la traduction en langage machine. Selon la méthode utilisée, on distingue deux types de traducteurs en langage machine : a. l'interpréteur qui traduit les programmes instructions par instructions (Bash, DOS) ; b. le compilateur qui traduit les programmes dans leur ensemble (C, C++, java) Compilation du langage C Pour le langage C, la compilation d'un chier source (extension.c) peut se décomposer en 4 phases : 5 DIAO O. Cours de langage C

6 1.4 Les mots-clés de C 1. La précompilation : il s'agit du préprocesseur qui eectue des transformations purement textuelles ; 2. La compilation proprement dite : il reconnaît les mots clés du langage, analyse la structure du programme (sa conformité avec la norme) et traduit le chier généré par la précompilation en code assembleur ; 3. L'assemblage qui traduit le code assembleur en code machine ou chier binaire ; 4. L'édition des liens permet de réunir tous les éléments d'un programme Exemple de compilation sous Linux Sous Linux, le programme pour compiler est cc (ou gcc). Par exemple pour compiler le chier file.c, on tape la commande suivante : gcc Wall file.c o outfile.exe Les options de gcc 1 : Wall active les messages d'avertissement supplémentaires (warnings). o permet de spécier un chier de sortie qu'on peut exécuter en tapant./outfile.exe. 1.4 Les mots-clés de C Un certain nombre de mots sont réservés pour le langage C. La liste exhaustive des 32 mots-clés du langage C est : auto const double float int short struct unsigned break continue else for long signed switch void case default enum goto register sizeof typedef volatile char do extern if return static union while On peut classer les diérents mots-clés en catégories, selon leur fonction : le stockage : auto, register, static, extern, typedef le typage : char, double, enum, float, int, long, short, signed, struct, union, unsigned, void le contrôle : break, case, continue, default, do, else, for, goto, if, switch, while Remarque : le point-virgule ; désigne la n d'une commande : déclaration ou instruction du langage. Une commande est une suite de texte qui ordonne à la machine d'eectuer une tâche bien dénie. Par exemple, si on écrit le texte intnombre; on ordonne à la machine (par l'intermédiaire du compilateur) de créer une variable (chose qui peut changer au cours de l'exécution) de type int et de l'appelé nombre. 1. Pour avoir toutes les options de gcc, on fait man gcc. 6 DIAO O. Cours de langage C

7 1.5 Les commentaires 1.5 Les commentaires Les commentaires permettent de documenter les chiers sources du langage C. Ajouter des commentaires au chier source est un bon moyen pour le rendre plus facilement lisible par d'autres, ou par vous-même plus tard. La première manière d'insérer des commentaires dans un chier source de C consiste à placer du texte entre les caractères /* d'un côté, et */ de l'autre. Dès que le compilateur rencontre /*, alors il ignore les lignes qui suivent jusqu'à rencontrer */, autrement dit les commentaires ne peuvent pas être imbriqués et surtout, il ne faut pas oublier de fermer les commentaires. Une autre manière de mettre du texte en commentaire vient à l'origine du langage C++. Elle a été ociellement intégrée au langage C en 1999 et fonctionne dans la plupart des compilateurs. Cependant certains compilateurs ne l'autorisent pas et vous devez éviter de l'utiliser si vous souhaitez que votre programme puisse être compilé sur toutes sortes de machines. Cette deuxième méthode permet de commenter tout ce qui se trouve sur une ligne, à droite d'un endroit donné. Tout ce qui suit les caractères // est en eet ignoré, jusqu'à la n de la ligne. Dans le domaine général de la programmation, une bonne habitude à prendre est de découper chaque chier source selon plusieurs niveaux de commentaires : 1. le chier : nom de l'auteur, nom du chier, le copyright, date de création, dates de modications ainsi que la raison d'être du chier ; 2. la procédure : pour indiquer les paramètres et la raison d'être de la procédure 3. déclarations ou instructions : pour exprimer leur raison d'être. Les commentaires peuvent aussi être très utiles en cours de développement, en particulier pour les fonctions qui ne sont pas terminées. Par exemple, vous pouvez insérer des commentaires aux endroits où il reste des choses à faire, à améliorer, ou à modier. Plutôt que de remettre simplement quelque-chose à plus tard, au risque de l'oublier, mettez une note en commentaire à l'endroit concerné. Une notation usuelle pour indiquer une chose restant à faire consiste à commencer le commentaire par le texte "TODO:". 1.6 Les types de base Le langage C est un langage typé, autrement dit tout objet (variable, constante, fonction) est d'un type précis. Le type d'un objet dénit la façon dont il est représenté en mémoire. En C, il y'a 3 types de bases : les entiers, les réels (ou otants) et les caractères Les entiers Le mot clé désignant les entiers est int. Par exemple : int a,b = 2; (ou bien en deux instructions int a,b; a = 2 ;) identie l'objet a comme un entier valant 2 et l'objet b comme un entier sans initialisation. En C, notons qu'un entier peut être exprimé dans trois bases diérentes : ˆ Base 10 (décimale) : c'est l'écriture usuelle ou l'entier est représenté par une suite de chires unitaires (de 0 à 9) ne devant pas commencer par le chire 0. ˆ Base 8 (octale) : on commence par le chire 0 suivi de chires octaux (de 0 à 7). 7 DIAO O. Cours de langage C

8 1.6 Les types de base ˆ Base 16 (hexadécimale) : on commence par 0x ou 0X suivis de chires hexadécimaux (de 0-9 et/ou de a-f). Les entiers peuvent être aectés de deux types d'attributs : un attribut de précision (short ou long) et un attribut de représentation (unsigned). On peut combiner les attributs de précision et l'attribut de représentation et avoir par exemple un unsigned long int. En résumé, on dispose donc de six types d'entiers : int : entier relatif codé sur 16 bits ou bien sur 32 bits (selon les compilateurs) short int : entier relatif codé sur 16 bits long int : entier relatif codé sur 64 bits unsigned int : entier naturel unsigned short int : entier naturel unsigned long int. : entier naturel Selon le compilateur utilisé, il est possible de spécie un long long int sur 64 bits. Lors de l'écriture d'un nombre, on peut spécier explicitement le type en ajoutant un suxe : ˆ le suxe l ou L pour le type long ; ˆ le suxe ll ou LL pour le type long long ; ˆ le suxe u ou U pour le type unsigned. entier long, on ajoute le suxe l ou L Les otants En langage C, on distingue trois types de otants (ou réel) selon leur précision : float représenté sur 32 bits (4 octets) double représenté sur 64 bits (8 octets) long double représenté sur 80 bits (10 octets) Un réel est un nombre à virgule, il peut toutefois être représenté de diérentes façons : ˆ un entier décimal : 895 ˆ un nombre comportant un point (et non une virgule) : ˆ une fraction : 27/11 ˆ un nombre exponentiel, c'est-à-dire un nombre (éventuellement à virgule) suivi de la lettre e (ou E), puis d'un entier correspondant à la puissance de 10 (signé ou non, c'est-à-dire précédé d'un + ou d'un -) : 2.75e-2 ou 35.8E+10 Par défaut, un nombre réel est représenté avec le format du type double. On peut cependant inuer sur la représentation interne d'un ottant en lui ajoutant un des suxes f ou F (float) et l ou L (long double) Les caractères Le mot-clé permettant de désigner un caractère est char. Un caractère est en fait un entier codé sur 8 bits et interprété selon le code ASCII. Par exemple : char c1 = 'a' ; // c1 est une variable de type char valant la lettre a char c2 = 65 ; // c2 est une variable caractère équivalent au code ASCII de 65 (A) 8 DIAO O. Cours de langage C

9 1.7 Structure d'un programme en C Pour désigner un caractère imprimable, il sut de le mettre entre simple quotte ou apostrophes ' (sauf les caractères antislash et apostrophe). Par exemple 'A' et '$' désignent respectivement le a majuscule et le symbole dollar. Pour désigner l'antislash et l'apostrophe, on utilise respectivement '\\' et '\. Les caractères nom-imprimables disposent d'une notation simple : \n : nouvelle ligne \f : saut de page \t : tabulation horizontale \v : tabulation verticale \b : retour arrière \r : retour chariot 1.7 Structure d'un programme en C Généralement, un programme en C se présente de la façon suivante : [ directives au préprocesseur ] [ déclarations de variables ] [ fonctions secondaires ] fonction main. Pour pouvoir s'exécuter un programme en C doit nécessairement contenir la fonction main, c'est le point d'entrée du programme. En C, nous appellerons nécessairement des fonctions prédénies. Ces fonctions prédénies sont contenues dans des chiers spéci- ques appelés library les (chiers bibliothèques). Ces chiers bibliothèques vont être inclut grâce à la directive #include du préprocesseur Directives au préprocesseur Le préprocesseur est un programme exécuté lors de la première phase de compilation (sous Linux, c'est le programme cpp). Le préprocesseur eectue des modications textuelles sur le chier source à partir de directives. Les diérentes directives du préprocesseur, introduites par le caractère #, ont pour but : d'incorporer des chiers grâce à la directive #include, de dénir des constantes grâce à la directive #define. Pour inclure un chier de la bibliothèque standard (c'est à dire les chiers d'extension.h du répertoire /usr/include/), on utilise la syntaxe : ˆ Directive #include. #include < library_file > Les bibliothèques standards importants sont (nous reviendrons plus en détails sur les bibliothèques) : <math.h> : fonctions mathématiques de base (sqrt, cos, log, pow, ceil, floor) <stdio.h> : pour les entrées/sorties de base (printf, scanf, getchar, putchar) Cependant, pour inclure un chier utilisateur, on utilise la syntaxe : #include nom_fichier 9 DIAO O. Cours de langage C

10 1.7 Structure d'un programme en C ˆ Directive #define. La directive : Cette directive permet généralement de dénir des constantes. #define moi professeur demande au préprocesseur de substituer toute occurrence de moi par la chaîne professeur Déclarations de variables En langage C, tout objet doit être d'abord créer avec de pouvoir être utilisé. Une variable est un objet qui peut changer de valeur au cours de l'exécution du programme. Déclarer une variable correspond à sa création, dès lors on ordonne au système de réserver un emplacement mémoire à la variable. Pour créer une variable, nous devons indiquer obligatoirement son type (le C est un langage typé) et son nom appelé aussi identiant (c'est le nom qui identie de manière unique une variable). L'identiant d'une variable doit être signicatif pour la clarté du programme. Attention, conformément à la norme du langage C, un identiant doit être formé de lettres minuscules ou majuscules (de a à z, ou de A à Z), de chires, et de caractères soulignés (le symbole "_", appelé underscore en anglais). Il ne doit en outre pas commencer par un chire, ni contenir d'espaces, de lettres accentuées ou tout autre caractère spécial. Il n'est pas permis qu'un identiant soit un mot clé, car un mot clé est déjà réservé et reconnu par le système. La syntaxe de création d'une variable est de la forme : type nom_variable [= <valeur> ] ; Par exemple, unsigned int a,b=7; ou long double c; sont des déclarations des variables entiers positifs a et b (qui est initialisé à 7) et d'une variable réel c. Toute déclaration d'une variable, comme toute instruction, se termine par un point virgule Les fonctions Répéter plusieurs fois les mêmes instructions au sein d'un même programme est une chose qu'il faut éviter au maximum. Parce que d'une part, l'écriture devient vite fastidieux et d'autre part cela rend le programme plus dicile à lire et à maintenir. Pour éviter la répétition d'un bloc d'instructions dans le même programme, l'outil le plus adapté (et même indispensable) est une fonction. Une fonction est constituée d'une suite d'instructions permettant d'éviter la récriture de ce bloc d'instructions plusieurs fois dans un même programme. Chaque fonction permet de réaliser une certaine tâche et se constitue de la forme suivante : type_résultat nom_fonction ( liste-de-déclarations-de-paramètres ) { liste-de-déclarations-de-variables-locales liste-d'instructions Les noms que l'on peut utiliser comme identiants de fonctions sont les mêmes que ceux possibles pour les identiants de variables. Comme pour le choix des noms de 10 DIAO O. Cours de langage C

11 1.7 Structure d'un programme en C variables, il est important de bien choisir les noms des fonctions, pour qu'ils expriment très clairement ce que fait la fonction Exemple d'un programme en C Voici un petit programme qui ache un message de bienvenue. #include <stdio.h> int main (void) { printf(''soyez le bienvenu \n''); return 0; // car le type de main est un entier. La seule chose indispensable dans notre programme est la fonction main. Cependant, comme on utilise une fonction externe (car non inclut dans le chier source), à savoir printf, alors nous avons besoin du chier bibliothèque où cette fonction est dénie. Ce chier bibliothèque est en l'occurrence stdio.h que l'on trouve dans le répertoire /usr/include/. La fonction printf permet l'impression (c-a-d la sortie) du texte Soyezlebienvenu à l'écran et place le curseur à la ligne grâce à \n. 11 DIAO O. Cours de langage C

12 2 Les bases de la programmation en C 2.1 Opérateurs de base Opérateurs arithmétiques Comme tous les langages, C dispose d'opérateurs arithmétiques unaires (i.e. portant sur un seul opérande) et d'opérateurs arithmétiques binaires (i.e. portant sur deux opérandes). Les opérateurs arithmétiques sont résumés dans le tableau 1. Les opérateurs arithmétiques sont dénis que pour deux opérandes ayant le même type, et ils fournissent un résultat de même type. Par exemple 5/2 donne 2 et non 2.5. Cependant les conversions implicites permettent de calculer deux opérandes de types diérents ou même des opérandes de types char. Par exemple 5.0/2 donne 2.5. Binaire Unaire Opérateur Traduction Exemple Résultat + addition x + y l'addition de x et y soustraction x y la soustraction de x et y * produit x * y la multiplication de x et y / division x / y le quotient de x par y % modulo x % y le reste de la division euclid. de x par y + signe positif +x la valeur de x signe négatif -x l'opposé de x ++x x vaut x incrémentation ou ++x incrémente x avant de l'évaluer x++ x++ incrémente x après son évaluation x x vaut x 1 décrémentation ou x décrémente x avant de l'évaluer x x décrémente x après son évaluation Table 1 Principaux opérateurs arithmétiques Priorité des opérateurs arithmétiques. Les opérations arithmétiques se font de la gauche vers la droite. Cependant la multiplication, la division et le modulo sont plus prioritaires que l'addition et la soustraction. Les opérateurs unaires restent plus prioritaires que les opérateurs binaires. Voir le tableau 3 pour plus de détails sur les règles de priorités. Exemple d'incrémentation. Si n vaut 5, alors : Pré incrémentation : x = ++n ; Résultat : x = 5 et n = 6. Post incrémentation : x = n++ ; Résultat : x = 6 et n = 6. Remarque sur la puissance. L'opérateur d'élévation à la puissance n'existe pas en C. Pour calculer une puissance, on peut utiliser la fonction pow(a,b) de la bibliothèque math.h. Cependant, quand la puissance n'est pas très grande, on peut faire appel à des produits successifs. Par exemple, pour calculer x 3, on fait x*x*x. Exercice 1 Écrire un programme qui permet de résoudre une équation du second degré dans R (utiliser la bibliothèque standard math.h). Vous pouvez créer une fonction permettant de calculer le discriminant et une fonction permettant d'acher le résultat. 12 DIAO O. Cours de langage C

13 2.1 Opérateurs de base Opérateurs relationnels Les opérateurs relationnels permettent de comparer deux variables. Le résultat de toute comparaison est de type int (en C, il n'y a pas de type booléen) qui renvoie la valeur 0 (false) ou 1 (grue). Les diérents opérateurs relationnels sont détaillés dans le tableau 2. Opérateur Traduction Exemple Résultat > supérieur x > y 1 si x est strictement supérieur à y et 0 sinon >= supérieur ou égal x >= y 1 si x est supérieur ou égal à y et 0 sinon < inférieur x < y 1 si x est strictement inférieur à y et 0 sinon <= inférieur ou égal x <= y 1 si x est inférieur ou égal à y et 0 sinon == égalité x == y 1 si x est égal à y et 0 sinon!= inégalité x!= y 1 si x est diérent y et 0 sinon Table 2 Les opérateurs relationnels Règle de priorité des opérateurs relationnels. Les opérateurs >,>=,< et <= (d'égale priorité) sont plus prioritaires que les opérateurs == et!= (voir le tableau 3 pour plus de détails sur les règles de priorités) Opérateurs booléens Le langage C dispose de trois opérateurs logiques classiques : le et logique noté && le ou logique noté la négation logique noté! Comme C ne dispose pas de type logique, alors les opérateurs logiques produisent un résultat numérique (de type int) où le 1 représente vrai et le 0 représente faux. Cependant, les opérateurs logiques acceptent n'importe quel opérande numérique, y compris les types ottants. Il faut juste noter que toute valeur diérent de 0 est interprétée comme vraie (et 0 est la seule valeur correspond à faux). Exemple : 1. x&&y ne renvoie 1 que si x et y sont tous les deux diérents de x y ne renvoie 0 que si x et y valent 0. L'exemple 1 signie que si x=0, alors inutile de regarder la valeur de y car x&&y=0. L'exemple 2 signie que si x=1, alors inutile de regarder la valeur de y car x y=1. Cette règle permet de simplier des expressions compliquées comme : i<max && ((c=getchar())!= '\n') alors, l'instruction c=getchar() qui lit le caractère saisi au clavier ne sera évaluer que si la condition (i<max) est vrai. Remarque. L'opérateur && est plus prioritaire que l'opérateur. Tous deux sont moins prioritaires que les opérateurs arithmétiques ou relationnels. Ainsi a<b c<d&&e==f équivaut à (a<b) ((c<d)&&(e==f)). Voir le tableau 3 pour plus de détails sur les priorités. Les opérateurs logiques évaluent les opérandes de la gauche vers la droite. 13 DIAO O. Cours de langage C

14 2.1 Opérateurs de base Opérateurs bit à bit Le C fournit six opérateurs, ne concernant que les entiers (char, short, int, long), et réalisant des manipulations au niveau des bits. Ces opérateurs sont : l'opérateur ET bit à bit noté & l'opérateur OU bit à bit noté l'opérateur XOR bit à bit noté l'opérateur NON bit à bit noté l'opérateur de décalage à gauche noté l'opérateur de décalage à droite noté En pratique, les opérateurs ET, OU et XOR consistent à appliquer bit à bit les opérations suivantes : & Les opérateurs et décalent leur opérande de gauche (en ajoutant des 0) du nombre de bits indiqué par leur opérande de droite. Et ce qui dépasse disparaît. Ainsi x 1 décale la valeur de x en base 2 d'un bit vers la gauche, en le remplaçant par un 0, ce qui revient à multiplier par 2. Exemple. Considérons par exemple les entiers a=77 et b=23 de type unsigned char (i.e. 8 bits). En base 2 ils s'écrivent respectivement a= et b= expression base 2 décimale a b a&b a b a b a b b b Remarque : opérateur &. Généralement, on utilise l'opérateur & (ET bit à bit) pour masquer certains bits en les mettant à 0. Par exemple, pour masquer tous les bits d'un entier sauf le troisième et le quatrième bit de poids faible d'un entier x, on fait simplement x&12. En eet, comme 12 2 = 1100 c-a-d le troisième bit et le quatrième bit de 12 sont à 1, donc dans x, seuls le 3ième et le 4ième bits de poids faible seront inchangés, et tous les autres bits de x vont se transformer en 0. Voici une illustration : b= b& DIAO O. Cours de langage C

15 2.1 Opérateurs de base Remarque : opérateur. L'opérateur permet généralement de forcer la valeur de certains bits à 1. Par exemple x 12 force les 3ième et 4ième bits de poids faible à être égal à 1. Donnons une illustration : b= b Remarque sur les décalage. Décaler de n positions à gauche équivaut à multiplier par 2 n et décaler de n positions à droite équivaut à diviser par 2 n Opérateur d'adresse Le C dispose d'un opérateur unaire qui permet d'accéder à l'adresse mémoire d'un objet. Pour un objet donné x, l'opérateur d'accès à l'adresse mémoire de x s'écrit &x Opérateur de conversion de type Lorsqu'un opérateur a des opérandes de types diérents, ils sont convertis automatiquement en un type commun. Généralement, le type le plus petit est promu au type le plus grand. Cependant, on peut forcer la conversion d'un type A vers un type B, on parle alors de cast. Si un objet x est de type A, pour le convertir explicitement en type B, on utilise la syntaxe suivante : (type B) x ; Par exemple a=(float) 5/2; retourne 2.5 alors que 5/2; retourne l'entier Opérateurs d'aectation Nous avons vu que pour déclarer une variable on peut l'initialiser (voir la partie 1.7.2) grâce au signe = (égal). Le signe = est en fait l'opérateur d'aectation d'un objet en C. On peut combiner l'opérateur =, avec l'une des opérateurs de la liste suivante : { + * / % & Ceci permet d'obtenir les opérateurs d'aectation composés dont la liste est la suivante : { += = *= / %= = = &= = = Si on note op un opérateur dans la première liste et si expr 1 et expr 2 expressions dans C, alors : expr 1 op= expr 2 équivaut à expr 1 = expr 1 op expr 2 Par exemple si x et y sont des variables (déjà déclarés), alors Règles de priorité x *= y + 1 équivaut à x = x * (y + 1) Le tableau 3 récapitule les règles de priorités de tous les opérateurs, classés par ordre de priorité décroissante, y compris ceux dont nous n'avons pas encore parlé. 15 DIAO O. Cours de langage C

16 2.2 Principales fonctions d'entrées-sorties standard Catégorie Opérateurs Évaluation référence () [] >. G D unaire + ++! * & (cast) sizeof D G arithmétique * / % G D arithmétique + G D décalage G D relationnel > >= < <= G D relationnel ==!= G D manip. de bits & G D manip. de bits & G D manip. de bits G D manip. de bits G D logique && G D logique G D conditionnel?: G D aectation = += = *= /= %= &= = = = = D G séquentiel, D G Table 3 Les priorités des opérateurs du langage C 2.2 Principales fonctions d'entrées-sorties standard Il s'agit des fonctions de la bibliothèque stdio.h utilisées avec les unités classiques d'entrées-sorties à savoir le clavier et l'écran. Comme nous l'avons signaler, cette bibliothèque doit être inclut au programme grâce à la directive du préprocesseur suivant : #include <stdio.h> Fonction printf La fonction printf est une fonction d'impression formatée, ce qui signie que les données internes du programme sont converties en caractère. Sa syntaxe est la suivante : printf("chaîne de contrôle", expression 1,..., expression n ); La chaîne de contrôle contient le texte à acher et les spécications de format correspondant à chaque expression de la liste. Les spécications de format ont pour but d'annoncer le format des données à visualiser. Elles sont introduites par le caractère %, suivi d'un caractère désignant le format d'impression. Exemple : Implémenter le programme suivant : #include <stdio.h> int main (void) { char ch = 'B'; int x = 1234; int y = 567; printf("le caractère %c a le code %i!\n", ch, ch); printf("%i fois %i donne %li \n", x, y, (long)x*y); printf("%i divise par %i donne %f \n", x, y, (float)x/y); return 0; 16 DIAO O. Cours de langage C

17 2.2 Principales fonctions d'entrées-sorties standard format conversion en écriture %i (resp. %li) int (resp. long int) entier relatif (resp. long ) %u (resp. %lu) unsigned int (resp. long) entier naturel (resp. long ) %o (resp. %lo) unsigned int (resp. long) unsigned en octale (resp. long ) %x (resp. %lx) unsigned int (resp. long) hexadécimale (resp. unsigned) %f (resp. %lf) double (resp. long) réel (resp. long) %e (resp. %le) double (resp. long) réel en exponentielle %g (resp. %lg) double (resp. long) remplace %f et %e (resp. %lf et %le) %c unsigned char caractère %s char* chaîne de caractères Table 4 Les diérents formats d'impression de printf Dans la deuxième expression, lors de la compilation, le premier %i est remplacé par x, le deuxième %i par y et le %li est remplacé par (long)x*y Fonction scanf La fonction scanf est la fonction symétrique à printf ; elle nous ore pratiquement les mêmes conversions que printf, mais en sens inverse. Autrement dit, la fonction scanf permet de saisir des données au clavier et de les stocker aux adresses spéciées (on utilise alors l'opérateur d'adresse & pour les variables numériques) par les arguments de la fonction. Sa syntaxe est la suivante : scanf("chaîne de contrôle", AdrVar 1,..., AdrVar n ); Les données reçues sont mémorisées successivement aux adresses indiquées les AdrVar i. Ces données peuvent être séparer par deux espaces. Exemple : Implémenter le programme suivant : #include <stdio.h> int main (void) { unsigned int jour, annee; // le jour et l'année sous la forme d'entier naturel char mois[10]; // contiendra le mois sous la forme d'une chaine de caractère printf("veuillez saisir la date du jour \n"); scanf("%d %s %d",&jour, mois, &annee); printf("la date saisie est \n"); printf("%i %s %i \n",jour, mois, annee); return 0; Exercice 2 Écrire un programme qui : ˆ Demande le nom de l'utilisateur et lui souhaite une bienvenue personnalisée (Bonjour [nom_utilisateur]!!! par exemple) ; ˆ Demande l'age de l'utilisateur ; ˆ Demande le numéro de téléphone de l'utilisateur ; ˆ Imprime à l'écran toutes les données collectées. 17 DIAO O. Cours de langage C

18 2.3 Structure de contrôles Fonctions getchar et putchar La fonction getchar l'expression : c = getchar(); joue le même rôle que : scanf(''%c'',&c); permet de lire un caractère, de façon non-formatée. En faite, tout en étant plus rapide, puisque getchar, contrairement à scanf, ne fait pas appel au mécanisme d'analyse d'un format. permet l'impression d'un caractère à l'écran. En faite, l'expres- La fonction putchar sion : putchar(c); joue le même rôle que : printf(''%c'',c); Toutefois, l'exécution de putchar est plus rapide, dans la mesure où elle ne fait pas appel au mécanisme d'analyse de format. Les arguments de la fonction putchar sont soient des caractères (c-à-d des nombres entiers entre 0 et 255) ou bien le symbole EOF (End Of File). Exemple d'utilisation : Le programme suivant permet de lire un chier texte et d'imprimer son texte à l'écran : #include <stdio.h> /*imprime le fichier d'entrée sur l'écran */ int main (void){ char c; while ((c = getchar())!= EOF) { putchar(c); return 0; Pour l'exécuter, il sut d'utiliser l'opérateur < de redirection d'unix : prog < name-file. Dans le programme précédent, nous avons introduit l'instruction while qui fait partie des structure de contrôle que nous allons voir dans la prochaine partie. 2.3 Structure de contrôles Comme tout langage de programmation, le C dispose d'instructions de contrôle permettant de réaliser des choix ou de répéter plusieurs fois un ensemble d'instructions données. 18 DIAO O. Cours de langage C

19 2.3 Structure de contrôles Instruction if...else La syntaxe de cette instruction est : if ( condition ) instruction_1 ; else instruction_2 ; La clause else étant facultative. Pour la condition à vériée, le C ne teste que si cette expression vaut 0 (c-a-d faux), car dans tous les autres cas, elle est vraie. Chaque instruction peut être un bloc d'instructions et dans ce cas, le bloc sera contenu entre des accolades {. Exemple. Voici deux conditions équivalentes : // première instruction avec if...else if (a > b) max = a; else max = b; // deuxième instruction équivalente de la première, mais sans else max = b; if (a > b) max = a; Remarque : Dans l'instruction if..else, le then (alors) et le end if (fin si) sont implicites, c-a-d on ne doit pas les noter comme dans on le ferait pour certains langages (maple par exemple). Exercice 3 Un vendeur eectue un pourcentage de remises en fonction du prix TTC : 0% pour un montant TTC inférieur à 1000 euros 1% pour un montant TTC compris entre 1000 et 2000 euros 3% pour un montant TTC compris entre 2000 et 5000 euros 5% pour un montant TTC supérieurs à 5000 euros. Sachant que Le TVA est de 19,5%, écrire un programme permettant de calculer le montant net à payer à partir du prix hors taxe. Exécuter ce programme, pour les prix hors taxes suivants : 500 euros, 2300 euros, 4700 euros Instruction switch L'instruction switch est une suite d'instructions if. Elle permet une prise de décision à choix multiple qui regarde si la valeur d'une expression fait partie d'un certain nombre de cas et eectue alors les instructions de ce cas. Sa syntaxe est : switch ( condition ) { case cas_1 : instructions ; break ; case cas_2 : instructions ; break ;... case cas_n : instructions ; break ; 19 DIAO O. Cours de langage C

20 2.3 Structure de contrôles [ default: instructions ; ] La condition est une expression testée successivement pour chacun des case et lorsque l'expression testée est égale à une des valeurs suivant un case, la liste d'instructions qui suit celui-ci est exécutée. Notons que le mot clé break est essentiel, car elle permet de sortir de switch sans traiter les autres cas. Le mot clé default est facultatif et il indique les instructions à exécuter si la condition n'est jamais égale à un des case. Exemple : Implémenter et exécuter le programme suivant #include <stdio.h> int main(void) { unsigned int n; printf("veuillez choisir un entier naturel \n"); scanf("%i",&i); switch (n) { case 0 : printf("nul \n"); break; case 1 : case 2 : printf("petit \n"); break; case 3 : case 4 : case 5 : printf("moyen \n"); break; default : printf("grand \n"); Exercice 4 Reprendre l'exercice 3 en utilisant l'instruction switch Instruction for L'instruction for permet d'exécuter plusieurs fois la même série de commandes : for permet de réaliser des boucles. Dans sa syntaxe, il sut de préciser le nom de la variable qui sert de compteur, la condition d'arrêt du compteur et l'instruction d'incrémentation. La syntaxe est alors : for ( compteur ; condition ; modification_compteur ) { liste_instructions ; Exemple : Pour acher les nombres compris entre 1 et 10, il sut d'écrire : for (n = 1 ; n <= 10 ; n++) printf("%i",n); Remarque : Le compteur, la condition et le modicateur du compteur sont des expressions facultatives, mais les parenthèses et les points-virgules doivent toujours être présents. Si la condition manque, alors on considère qu'elle est toujours vrai. Ainsi, pour avoir une boucle innie sur une liste d'instructions, on écrit : for ( ; ; ) { liste_instructions ; Exercice 5 Avec la boucle for, écrire une fonction qui calcule le factoriel d'un nombre. 20 DIAO O. Cours de langage C

21 2.3 Structure de contrôles Exercice 6 Écrire un programme qui permet de faire une exponentiation, c-a-d qui calcule a n pour deux entiers a et n. Exercice 7 Écrire un programme qui permet de convertir un nombre, écrit en base décimale, dans une base b quelconque Instruction while Comme for, l'instruction while représente un autre moyen d'exécuter plusieurs fois la même série d'instructions. Sa syntaxe est la suivante : while (condition) { liste_instructions ; Ceci exécute la liste des instructions, tant que la condition est vériée (c-a-d non nulle). Notez qu'une instruction while peut être convertie en une instruction for. En eet, la boucle suivante avec for for (compteur ; condition ; modificateur_compteur ) { instructions ; est équivalente à la boucle suivante avec while compteur ; while ( condition ) { instructions ; modificateur_compteur ; Exemple : avec while : L'exemple fait avec for pour acher les nombres de 1 à 10 peut se faire n = 10 ; while ( n <= 10 ) { printf("%i",n); n++; Exercice 8 Écrire un programme qui contient les diérentes fonctions suivantes : 1. une fonction print_file qui lit et ache un chier. 2. une fonction compter_caracteres qui compte le nombre de caractères d'un chier. 3. une fonction compter_ligne qui compte le nombre de lignes d'un chier. 4. une fonction compter_mots qui compte le nombre de mots d'un chier. 5. une fonction faire_choix qui permet de faire le choix parmi les 4 fonctions précédentes (print_file, compter_caracteres, compter_ligne, compter_mots). Indication : nous avons déjà vu la fonction print_file qu'on peut rappeler : 21 DIAO O. Cours de langage C

22 2.3 Structure de contrôles /*imprime le fichier d'entrée sur l'écran */ void lire_file (void) { char c; while ((c = getchar())!= EOF) { putchar(c); Instruction do...while Contrairement aux instructions for et while qui testent leur condition d'arrêt en tête de boucle, la boucle do...while la teste à la n, après chaque passage dans le corps de la boucle, qui s'exécute au moins une fois. Sa syntaxe est la suivante : do instructions ; while ( conditon ) ; Il faut noter que l'instruction do..while doit avoir un point-virgule à la n. Exemple : Cet exemple impose la saisie d'un nombre entre 1 et 12 (correspondant au 12 mois de l'année) : int a = 0; do { printf("entrez un entier entre 1 et 12 : \n"); scanf("%i",&a); while ( (a > 0) (a < 10) ); Exercice 9 On va reprendre l'exercice 1, mais cette fois-ci il faut prévoir que l'utilisation peut saisir des données incorrectes Instruction break Nous avons déjà vu l'instruction break au sein du bloc régi par une instruction switch. Plus généralement, l'instruction break peut être employer dans n'importe qu'elle boucle for, while ou do...while. Dans ce cas, break permet d'interrompre le déroulement de la boucle et de passer directement à la première instruction qui suit la boucle. Exemple : Implémenter et exécuter cet exemple suivant : #include <stdio.h> int main (void) { int n; for (n = 1 ; n <= 10 ; n++) { printf("debut tour numero %i\n", n) ; printf("bonjour\n") ; if ( n == 3) break ; printf("fin tour numero %i\n", n) ; 22 DIAO O. Cours de langage C

23 2.3 Structure de contrôles printf("après la boucle l'entier vaut %i", n); Instruction continue L'instruction continue est similaire au break, mais elle permet de passer prématurément au tour suivant dans une boucle for, while ou do...while. On ne l'utilise que pour des boucles, donc jamais avec l'instruction switch. Exemple à implémenter. #include <stdio.h> int main () { int a ; do { printf("donner un nombre positif :\n") ; scanf("%d", &a); if (a < 0 ) { printf("svp un nombre positif \n") ; continue; printf("son carré est : %d \n", a*a); while (a); Exercice 10 Cet exemple est une boucle innie, inclure une condition d'arrêt qui demande à l'utilisateur s'il veut continuer et prévoir les erreurs de saisi Instruction goto L'instruction goto permet d'eectuer un branchement ou saut jusqu'à l'instruction étiquette correspondante. Formellement, goto n'est jamais indispensable et en pratique on peut s'en passer. Néanmoins, goto peut servir à sortir directement dans une structure de contrôle avec plusieurs boucles imbriquées. Dans ce cas, l'instruction break ne sut pas à elle seule, car elle ne permet que de sortir de la boucle intérieure. Par exemple : for (... ) for (... ) {... if (catastrophe) goto erreur ; erreur : printf(réparer les dégâts) ; Une étiquette a la même forme que les noms des variables, mais elle est suivie d'un signe deux points. Exercice 11 Écrire un programme se comportant comme une calculette c'est à dire exécutant une boucle sur : 23 DIAO O. Cours de langage C

24 2.3 Structure de contrôles 1. lecture d'une ligne supposée contenir un entier, un opérateur et un entier (ex : ), les opérateurs seront l'addition +, la soustraction -, la multiplication *, la division / et le modulo % ; 2. calcule la valeur de l'expression ; 3. imprime le résultat. 24 DIAO O. Cours de langage C

25 3 Les types composés Nous avons vu que le langage C était un langage typé et qu'il ne contient que trois types de bases à savoir les entiers (int), les réels ou otants (float) et les caractères (char). A partir de ces types prédénis, on peut créer de nouveaux types, appelés types composés, qui permettent de représenter des ensembles de données organisées. 3.1 Les tableaux Comme tout langage de programmation, le C permet de manipuler des tableaux. Un tableau est un ensemble ni d'éléments de même type désignés par un identicateur unique. Les éléments sont stockés en mémoire à des adresses contiguës, chaque élément étant repéré par son indice précisant sa position au sein de l'ensemble. Conventionnellement, en langage C, la première position porte toujours le numéro zéro Tableau unidimensionnel La déclaration d'un tableau unidimensionnel se fait de la façon sui- Déclaration : vante : type identicateur [ nombre-éléments ] où type est un type de base (int, float, char, etc.), identicateur est le nom du tableau et nombre-éléments est la taille du tableau qui est un entier naturel non nul. Les éléments d'un tableau sont toujours numérotés de 0 à nombre-éléments 1. Par exemple, la déclaration int tbl[10]; indique que tbl est un tableau de 10 éléments de type int dont le premier élément a pour indice 0 et le dernier pour indice 9. On accède à un élément du tableau grâce à l'opérateur []. Dans l'exemple précédent, tbl[6] désigne le 7ième élément du tableau tbl. Remarque : La taille d'un tableau doit être connue statiquement par le compilateur, autrement la taille ne saurait être une variable. Initialisation : On peut initialiser un tableau lors de sa déclaration par une liste de constantes de la façon suivante : type identicateur[n] = { const-1, const-2,..., const-n Par exemple, les instructions suivantes #define N 5 int tb[n] = {14, -27, 3, 18, -81 ; indiquent que tb est un tableau avec 5 éléments où tb[0]=14,tb[1]=-27,tb[2]=3,... Le nombre de valeurs d'initialisations d'un tableau peut être inférieur à la taille du tableau. Dans ce cas, les premiers éléments seront initialisés avec les valeurs indiquées, tandis que les autres seront initialisées à zéro. Les instructions suivantes : 25 DIAO O. Cours de langage C

26 3.1 Les tableaux #define N 10 int t[n] = {14,-27; permettent de créer un tableau où les éléments d'indice 0 et 1 sont initialisés respectivement à 14 et -27, les autres éléments (d'indices 2 à 9) seront initialisés à zéro. Chaîne de caractères : Un tableau de caractères est simplement une chaîne de caractère (un mot dans le langage courant). Seulement le compilateur complète toute chaîne de caractères avec le caractère nul ('\0'). Par exemple, pour initialiser une chaîne de caractère nommée tab et contenant le mot bonjour (contenant 7 caractères) on peut écrire : #define N 8 char tab[n] = "bonjour"; Remarque : Lors de l'initialisation d'un tableau, on peut ne pas donner la dimension de celui-ci. Dans ce cas, le compilateur réserve automatiquement le nombre d'octets nécessaires. Exemple : float t1[] = {10, -11, 12, 15, 27; // taille de t1 est 5. char c1[] = "Bienvenu"; // c1 est un tableau de taille 9 Exercice Écrire un programme pour lire et acher un tableau de 10 nombres entiers 2. Écrire une fonction permettant de trier dans l'ordre croissant les valeurs entières d'un tableau de taille quelconque. 3. Appliquer l'algorithme de trie au tableau de 10 nombres entiers. Exercice Écrire un programme qui permet de compter le nombre de chires, de caractère d'espacement et les autres caractères. 2. Écrire un programme qui ache un histogramme des fréquences des diérents caractères qu'il reçoit en entrée Tableau multidimensionnel Déclaration : En C, un tableau multidimensionnel de dimension n est considéré comme étant un tableau dont les éléments sont eux mêmes des tableaux de dimension n 1. Par exemple, les instructions suivantes : #define L 10 #defini C 5 int mat[l][c]; signient que mat est une matrice de L lignes et de C colonnes. Autrement dit, le compilateur allouera une zone mémoire permettant de stocker de manière contiguë L tableaux où chacun contient C entiers. Prenons un exemple facile à écrire : int mat[2][3]; // <==> [[m11 m12 m13],[m21 m22 m23]] int M[4][2][3]; // <==> 4 tableaux de dimension DIAO O. Cours de langage C

27 3.1 Les tableaux Accès aux éléments d'un tableau : On accède à un élément d'un tableau de dimension 2, en indiquant son numéro de ligne et son numéro de colonne. Par exemple pour le tableau précédent mat, on écrit mat[i][j] pour i=1,2 et j=1,2,3. Pour un tableau à 3 dimension comme M, on accède à ses éléments par M[i][j][k] avec i=1,2,3,4, j=1,2 et k=1,2,3. Initialisation : Comme dans les tableaux unidimensionnels, on initialise un tableau multidimensionnel en indiquant ses éléments. Par exemple : /* initialisé un tableau de dimension 2 */ int mat[2][3] = {{-4, 6, 20, // 1ier tab de dim 1 avec 3 éléments {7, -1, 3 // 2e tab de dim 1 avec 3 éléments ; /* initialisé un tableau de dimension 3 */ int M[4][2][3] = { { {1,-2,3,{0,-1,4 // 1ier tableau de dim 2 { {0,6,-1,{1,3,-7 // 2e tableau de dim 2 { {-3,0,0,{0,0,-1 // 3e tableau de dim 2 { {0,-1,0,{-2,0,1 // 4e tableau de dim 2 ; // fin de l'initialisation avec ";" Fonction et tableaux : Un tableau peut être l'argument d'une fonction. Par exemple, pour un tableau à une dimension : void imp_tab(int tab[], int size_tab){ // tab[] est un tableau, on n'a pas besoin de spécifier sa taille int i; for (i=0;i<size_tab;i++) printf("%d",tab[i]); Pour un tableau à deux dimensions, on donne l'exemple suivant : #define P 10 void mat_id (int mat[][p]){ // on doit obligatoirement spécifier le deuxième indice du tableau int i,j; for (i=0;i<n;i++) for (j=0;j<n;j++) if (i==j) tab[i][j] = 1; else tab[i][j] = 0; Attention : Une fonction ne peut pas retourner un tableau. Exercice Écrire une fonction permettant d'acher une matrice carrée d'ordre Écrire une fonction permettant de calculer la somme de deux matrices carrées d'ordre Écrire une fonction permettant de calculer le produit de deux matrices carrées d'ordre Tester les fonctions précédentes grâce au main. 27 DIAO O. Cours de langage C

28 3.2 Les structures 3.2 Les structures Nous avons vu qu'un tableau était une liste d'élément du même type. Par exemple, nous ne pouvons pas créer un tableau tab de deux éléments {a,b où a est un entier et b un caractère. En langage C, cela est rendu possible grâce aux structures. Une structure est un regroupement d'éléments de types diérents sous un même identicateur. On peut assigner la structure en C à une table dans une base de donnée. Par exemple, la base de donnée des ches de paies : chaque employé est décrit par un ensemble d'attributs tels que son nom, son adresse, son numéro de sécu, son salaire, etc. A leur tour, certains de ces attributs peuvent être des structures. Déclaration d'une structure. Avant de déclarer une structure, il faut d'abord la créer. La création d'une structure peut se faire de la façon suivante : struct identificateur { type_1 membre_1; type_2 membre_2;... type_n membre_n; ; Cette instruction va créer une structure par son identicateur et ses membres. Par exemple, pour créer une structure employer dans une che de paie, on écrit : struct employer { unsigned int numero_employer; char name[20]; char adresse[50]; float salaire; Ceci va créer l'identicateur employer comme étant une structure composée de 4 membres (ou champs), dont le premier est le numéro de l'employer, le second est un tableau de 20 caractères nommé nom, le troisième est un tableau contenant son adresse et le dernier contient son salaire. Dans le jargons du langage C, on dit que employer est une étiquette de structure. Une fois une structure créer, on peut déclarer des variables de types structures sous la forme suivante : struct employer a1; Ceci signie que a1 est une variable dont le type est employer. Remarque : Pour déclarer et initialiser une structure, on écrit : struct employer a1 = { 19,"Jean Pierre", "112 av. G. Leclerc", On peut noter que la création, la déclaration et l'initialisation d'une structure contiennent toujours le mot clé struct. 28 DIAO O. Cours de langage C

29 3.2 Les structures Accès aux éléments d'une structure : L'accès à chaque élément d'une structure se fait par l'indication de son nom au sein de la structure. Autrement dit, on accède aux diérents membres (ou champs) d'une structure grâce à l'opérateur point. Par exemple, pour la structure employer que nous avons déjà déni et pour l'employer a1 que nous avons déjà créer, on accède au nom de l'employer par : a1.nom. Pour accéder à son numéro, on écrit a1.numero_employer. Et a1.salaire permet d'accéder à l'objet 4 de la structure. Tableaux de structures Un tableau de structures est un tableau contenant des structures, c-a-d des types qu'on a créer. Comme pour la création, la déclaration et l'initialisation, le mot clé struct doit apparaître dans la déclaration d'un tableau de structure. Par exemple, un tableau contenant 10 structures personnes qu'on a créé se déclare de la façon suivante : struct employer tab[10]; Dans cet exemple, tab est un tableau où ses éléments sont des structures. Exercice 15 Il faudra implémenter un programme qui va : 1. Créer la structure Point qui dénit un point du plan. 2. Créer la fonction CalculePoint permettant de calculer le point P 3 = (x 3, y 3 ) où x 3 = x 1x 2 y 1 y 2 et y 3 = x 1y 2 + y 1 x x 1 x 2 y 1 y 2 1 x 1 x 2 y 1 y 2 3. Créer la fonction AffichePoint pour acher un point. 4. Tester votre programme dans une fonction main. Exercice 16 Implémenter un programme qui va : 1. Créer la structure Complexe pour les nombres complexes et la fonction AfficheComplexe permettant d'acher un nombre complexe. 2. Créer la fonction AdditionComplexe permettant de calculer la somme de deux nombres complexes. 3. Créer la fonction ProduitComplexe permettant de calculer le produit de deux nombres complexes. 4. Tester votre programme dans une fonction main où on demandera à l'utilisateur de saisir les complexes. Exercice Construire la structure Date contenant la date du jour (jour, mois, année) sous la forme de 1 Jan Construire la structure Employer contenant : nom, prénom, date de naissance, date d'embauche, salaire. 3. Construire une fonction qui demande à l'employer de saisir ses informations. 4. Dans une fonction main, souhaiter le bienvenu à l'employer. 29 DIAO O. Cours de langage C

30 3.3 Les champs de bits 3.3 Les champs de bits Nous avons vu que le langage C dispose d'opérateurs bits à bits permettant de manipuler des bits en langage machine. Cette manipulation en langage machine se fait avec les entiers. Normalement, en mémoire un entier occupe 32 bits (voir même 16 ou 64 bits selon le compilateur et la machine). Cependant, dans les structures, le langage C permet de forcer le nombre de bits que va occuper un entier : champ de bits. Un exemple typique d'utilisation est la table des interrupteurs mémoires d'un ordinateur. En C, pour dénir un champ de bit dans une structure, il sut juste de préciser le nombre de bits du champ d'une structure : type [membre] : nb_bits ; Par exemple, imaginons le registre suivant : Non (inutilisé) drapeau masque OK Table 5 Exemple d'aectation de bits dans un registre mémoire Ce registre peut se décrire de la manière suivante : struct registre { unsigned int Non : 2; /* codé sur 2 bits */ unsigned int : 6; /* inutilisé */ unsigned int drapeau : 4; unsigned int masque : 3; unsigned int OK : 1; /* codé sur 1 bit donc OK vaut 0 ou 1 */ ; Remarques : Si on déclare un registre R;, alors l'instruction R.OK += 2; ne modie pas la valeur de OK. Il faut noter aussi qu'un champ de bit n'est pas une adresse, donc on ne peut pas lui appliquer l'opérateur &. 3.4 Les unions L'union, en langage C, permet de faire partager un même emplacement mémoire par des variables de types diérents. La construction d'une union est la même que la construction d'une structure, on remplace simplement le mot clé struct par le mot clé union. Par exemple : union nombre { int i; float f; ; Dans cet exemple, la déclaration d'une variable N de type union nombre se fait par : union nombre N;. Dans ce cas, N pourra posséder soit une valeur entière, soit une valeur ottante, mais jamais les deux à la fois. 30 DIAO O. Cours de langage C

31 3.5 Les énumérations Accès aux membres d'une union : Comme dans les structures, on accède aux membres d'une union, avec l'opérateur ( ) point. Dans l'exemple précédent, si on désire que le nombre N possède une valeur entière, on écrira : N.i = 10; et si on désire lui faire posséder une valeur ottante, on écrira : N.f = 3.14; Remarque : le membre d'une union peut être une structure avec des champs de bits. Dans l'exemple qui suit, on créer la structure registre et l'union mot, puis on déclare une structure mem dans mot. struct registre { unsigned int Non : 2; /* codé sur 2 bits */ unsigned int : 6; /* inutilisé */ unsigned int drapeau : 4; unsigned int masque : 3; unsigned int OK : 1; /* codé sur 1 bit donc OK vaut 0 ou 1 */ ; union mot { int valeur ; struct registre mem ; // mem est une structure de type registre. ; union mot ABS; // déclaration d'un mot ABS.valeur = 10; // accès au premier membre de l'union ABS ABS.mem.drapeau ; // accès au troisième champ de la structure ABS.mem 3.5 Les énumérations Les énumérations permettent de dénir un type unique pour des variables qui ne sont aectées qu'à un nombre ni de valeurs. La création d'un objet de type énumération se fait avec le mot clé enum suivi de l'identicateur et de la liste des valeurs : enum nom_identicateur {cst_1, cst_2,..., cst_n ; En réalité les objets de types enum sont considérer comme des constantes de type int valeur de 0 à n. Par exemple : enum Jour { LUN, MAR, MER, JEU, VEN, SAM, DIM ; // LUN vaut 0,..., DIM vaut 6 enum Jour j1,j2; // déclaration d'un Jour j1 = MER; // initialisation de j1 à 2 j2 = SAM; // initialisation de j2 à 5 On peut modier le codage par défaut des valeurs de la liste lors de la déclaration du type énuméré, par exemple : enum Jour { LUN=17, MAR=8, MER=29, JEU=10, VEN=9, SAM=3, DIM=0 ; enum Jour j1,j2; // déclaration d'un Jour j1 = MER; // initialisation de j1 à 29 j2 = SAM; // initialisation de j2 à 3 31 DIAO O. Cours de langage C

32 3.6 Les types synonymes avec typedef 3.6 Les types synonymes avec typedef La déclaration typedef permet de dénir des types synonymes. Elle s'applique à tous les types du langage C. Son utilisation se fait avec le mot clé typedef : Par exemple, typedef type synonyme ; typedef float vecteur[3]; // création d'un nouveau type vecteur comme étant un tableau de 3 réels. /* Dans ce cas, les deux déclarations suivantes sont équivalentes */ float v[3], w[3]; vecteur v, w; // donc v et w sont des tableaux de 3 réels. typedef est très utile avec les types composés comme les structures. Par exemple : struct enreg { int numero ; int qte ; float prix ; ; /* Si on n'utilise pas typedef, on déclarera un type "enreg" par : */ struct enreg art1, art2; /* Avec typedef, on peut éviter d'écrire "struct enreg" à chaque fois */ typedef struct enreg ENREG; ENREG art1, art2; On voit que l'identicateur ENREG est utilisé comme une abréviation de struct enreg. 3.7 Fonction et types composés Nous avons vu que pour le langage C un tableau peut être l'argument d'une fonction, mais jamais la valeur de retour d'une fonction. Nous allons voir aussi qu'une structure peut être aussi bien l'argument d'une fonction ou la valeur de retour d'une fonction. Par exemple : #include <stdio.h> // structure Point de nombre entier struct point { int abs; // abscisse du point int ord; // ordonnée du point ; // un typedef pour simplifier l'écriture typedef struct point Point; // affichage d'un point 32 DIAO O. Cours de langage C

33 3.8 Les pointeurs void printpoint(point P){ printf("(%d, %d)",p.abs,p.ord); // fabpoint prend deux entiers pour construire un point Point fabpoint (int x, int y) { Point tmp; tmp.abs = x; tmp.ord = y; return tmp; // on retourne une structure // addpoint additionne deux points Point addpoint(point p1, Point p2) { p1.abs += p2.abs; p1.ord += p2.ord; return p1; // fonction main de test int main (){ int a,b,c,d; Point P,Q,R; printf("entrez les coord de point P\n"); scanf("%i %i",&a,&b); printf("entrez les coord de point Q\n"); scanf("%i %i",&c,&d); P = fabpoint(a,b); Q = fabpoint(c,d); R = addpoint(p,q); printf("la somme du point "); printpoint(p); printf(" et du point "); printpoint(q); printf(" est le point\t"); printpoint(r); printf("\n"); return 0; Ce qui possible avec les structures est possible avec les unions et les champ de bits. Exercice 18 Avec l'exemple précédent, créer une structure rect qui désigne un rectangle en indiquant ses points de la diagonale. Créer la fonction PrintRect permettant d'acher les quatre sommets du rectangle. Créer la fonction pt_in_rect permettant de vérier si un point est dans un rectangle. 3.8 Les pointeurs Dans cette partie, nous allons abordé une notion très importante en langage C Notion de pointeurs En langage C, une variable est destinée à contenir une valeur du type avec lequel elle a été créé (ou déclaré). Physiquement cette variable est stockée quelque part en mémoire centrale. Cette mémoire est constituée de plusieurs blocs (ou clusters en anglais), chaque 33 DIAO O. Cours de langage C

34 3.8 Les pointeurs cluster étant la plus petite unité de stockage d'un système de chiers. Chaque cluster a une taille xe en octets et est identié de manière unique par un numéro qu'on appelle adresse du cluster désignant son emplacement. La taille et l'adresse d'un cluster dépend évidemment du type de hardware et du système d'exploitation utilisé. Néanmoins, l'adresse d'un cluster permet de retrouver les informations qui y sont stockées. Donc, pour retrouver une variable stockée en mémoire, il sut de connaître l'adresse du bloc où elle est stockée. En langage C, un pointeur est variable qui contient, non pas une valeur, mais l'adresse d'une autre variable. Physiquement, un pointeur est un bloc contenant l'adresse d'un cluster (ou la première adresse d'une suite consécutive de clusters) ; l'adresse du cluster contenu dans le pointeur peut changer, et pointer, selon le moment, sur une autre adresse. Accès à l'adresse d'une variable : Nous avons vu que pour accéder à l'adresse d'une variable, nous utilisons l'opérateur d'adresse & (nous avons surtout utilisé cet opérateur avec scanf). Par exemple, #include <stdio.h> int main(void){ int i; printf("l'adresse de i est %d \n",&i); printf("donner une valeur pour l'entier i\n"); scanf("%d",&i); printf("la valeur de i est %d \n",i); printf("l'adresse de i est %p \n",&i); return 0; On constate qu'au court d'une exécution, l'adresse de la variable i ne change pas, mais que cette adresse change à chaque exécution. On remarquera qu'en C, l'adresse d'un objet est un entier (dont le format interne dépend de l'architecture) quelque soit le type de l'objet considéré. Avec la fonction printf, l'utilisation de %p évite les warnings liés à l'achage des adresses. Accès au contenu d'une adresse : Pour accéder au contenu d'une adresse, on utilise l'opérateur unaire * (étoile). On verra que l'opérateur étoile permettra d'accéder au contenu des pointeurs. Exemple : #include <stdio.h> int main(void){ int i; printf("l'adresse de i est %d \n",&i); printf("le contenu de l'adresse de i est %d \n",*(&i)); printf("donner une valeur pour l'entier i\n"); scanf("%d",&i); printf("la valeur de i est %d \n",i); printf("l'adresse de i est %d \n",&i); printf("le contenu de l'adresse de i est %d \n",*(&i)); return 0; L'instruction *(&i) donne le contenu de l'adresse de i, autrement dit la valeur de i. 34 DIAO O. Cours de langage C

35 3.8 Les pointeurs Déclaration d'un pointeurs La création ou la déclaration d'un pointeur se fait avec l'opérateur unaire * : Exemple : type *nom_pointeur ; int *pi; //pi est un pointeur vers un int long int* psi, *cp; //psi et cp sont des pointeurs vers un long int double* sp, ab; // sp est un pointeur vers un double // ab n'est pas un pointeur Opérateurs de manipulation des pointeurs : Nous avons vu deux opérateurs unaires de manipulation d'adresse, à savoir & et *. Par exemple : int main() { int i = 14; int *p; // p est un pointeur p = &i; // p pointe sur l'adresse de i printf("*p = %d \n", *p); // affiche la valeur du contenu de p. printf("p = %d \n", p); // == printf("&i = %d\n",&i) affiche l'adresse de i printf("&p = %d \n", &p); //affiche l'adresse de p Pointeurs génériques : En langage C, un pointeur est une variable qui possède alors un type déterminé. Cependant, ce typage des pointeurs peut s'avérer gênant dans certaines circonstances, par exemple quand on veut qu'un seul pointeur pointe sur diérents objets susceptibles de variés. Dans ces cas, il est très judicieux d'utiliser un pointeur générique (qui peut changer de type à chaque moment). Pour cela, on crée le pointeur avec le type void. Dans l'exemple qui suit nous allons créer un seul pointeur générique p, qui prendra l'adresse d'un caractère c, d'un entier i et d'un réel f. #include <stdio.h> int main (void) { void *p; // pointeur générique char chaine[10]; int i; float f; // trois variables de types différents printf("veuillez entrez des caracteres\t"); scanf("%s",&chaine); printf("\nveuillez entrez un entier\t"); scanf("%i",&i); printf("\nveuillez entrez un nombre réel\t"); scanf("%f",&f); p = &chaine; // p prend l'adresse "chaine" printf("\nl'adresse du caractere %c est %p",chaine,p); p = &i; // p prend l'adresse de l'entier i printf("\nl'adresse de l'entier %i est %p",i,p); p = &f; // p prend l'adresse du réel f printf("\nl'adresse du reel %f est %p\n",f,p); return 0; 35 DIAO O. Cours de langage C

36 3.8 Les pointeurs Signalons qu'une variable de type void (comme le pointeur générique) ne peut pas intervenir dans les opérations arithmétiques et logiques. Autrement dit si p et q sont des pointeurs génériques, alors on ne pourra pas calculer p+i, p-i ou p-q avec i un entier, on ne pourra pas aussi comparer p et q avec les opérateurs de comparaison. Cependant, nous allons voir que certaines opérations arithmétiques et logiques vont être possibles avec les pointeurs non génériques Opérations sur les pointeurs La valeur d'un pointeur étant un entier, on peut lui appliquer un certain nombre d'opérateurs arithmétiques classiques. Les seules opérations arithmétiques valides sur les pointeurs sont : l'addition d'un entier à un pointeur (i.e. p+i), et le résultat est un pointeur de même type que le pointeur de départ (i.e. type de p) ; la soustraction d'un entier à un pointeur (i.e. pi). Le résultat est un pointeur de même type que le pointeur de départ (i.e. type de p) ; la diérence de deux pointeurs pointant tous deux vers des objets de même type (i.e. p1 p2). Le résultat est un entier. la comparaison de deux pointeurs pointant vers des objets de même type (i.e. p1==p2; p1<p2; p1<=p2; etc. Attention : La somme de deux pointeurs n'est pas autorisée. Remarque : Pour un entier i et un pointeur p sur un objet de type T (donc déclaré par l'instruction : T *p ;). Alors p+i (respectivement pi) désigne un pointeur sur un objet de type T. Sa valeur est égale à celle de p incrémentée (respectivement décrémentée) de i*taille(t) = i*sizeof(t). De même si p1 et p2 sont deux pointeurs de même type T. La diérence p1p2 est un entier dont la valeur est égale à (p1p2)/sizeof(t). Exemple : #include <stdio.h> int main() { int i = 2; int *p1, *p2; p1 = &i; p2 = p1 + 1; printf("adresse p1 = %i \t Adresse p2 = %i\n", p1,p2); printf("diff des adresses : %lu \t sizeof(int)=%u\n",p2 - p1,sizeof(int)); printf("diff des deux pointeurs p2-p1 = %i!\n",p2-p1); return 0; Exercice 19 Déclarer deux entiers i,j et deux pointeurs a et b. Pointer a vers i et b vers j. Calculer alors *a**b et *a/*b que l'utilisateur va saisir. 36 DIAO O. Cours de langage C

37 3.8 Les pointeurs Remarque : Avec les pointeur, on peut également utiliser les opérateurs ++ et. Ces deux opérateurs d'incrémentation et de décrémentation sont très utiles pour parcourir les tableaux ou des chaînes de caractères. Exemple : #include <stdio.h> int tab[5] = {1, 2, 6, 0, 7; int main() { int *p; printf("\n Affichage dans l'ordre croissant des indices :\n"); for (p = &tab[0]; p <= &tab[n-1]; p++) printf(" %d \n",*p); printf("\n Affichage dans l'ordre decroissant des indices :\n"); for (p = &tab[n-1]; p >= &tab[0]; p--) printf(" %d \n",*p); Exercice 20 On considère le tableau d'entier suivant : {1,2,0,10,0,12,7,98,0,5,4,9. Écrire une procédure permettant d'imprimer les indices des éléments nuls du tableau Pointeurs et tableaux L'utilisation des pointeurs permet de manipuler facilement les tableaux. Tableaux à une dimension La déclaration int a[10]; dénit un tableau a de taille 10, c'est à dire un bloc de 10 objets consécutifs baptisés a[0], a[1],...,a[9]. La notation a[i+1] représente le i-ème élément du tableau. Si pa est un pointeur sur un entier (déclarer par int *pa;), alors l'aectation pa = &a[0]; fait pointer pa sur le premier élément du tableau a ; autrement dit pa contient l'adresse de a[0]. Dans ce cas, la valeur de a[0] peut être obtenu avec *pa. Remarque : Si un pointeur P pointe sur un certain élément du tableau, alors, par dénition, P+1 pointe sur l'élément suivant, P+i pointe sur i-ème élément après P et P-i pointe sur le ième élément avant P. Donc, dans notre exemple, comme le pointeur pa pointe sur a[0], alors pa+1 pointe sur l'élément a[1], pa+2 pointe sur l'élément a[2] et pa+i pointe sur l'élément a[i]. Alors, pour connaître le contenu de a[i], on peut juste utiliser : *(pa+i) ; Nous voyons ainsi la relation très étroite entre l'indexation d'un tableau et les calculs sur les pointeurs. Par dénition, la valeur d'une variable ou d'une expression de type tableau est l'adresse du premier élément du tableau. Par conséquent, après l'aectation pa = &a[0]; le pointeur pa et le tableau a ont la même valeur. Puisque le nom d'un tableau est synonyme de l'adresse de l'élément initial, alors l'aectation précédente peut également s'écrire : 37 DIAO O. Cours de langage C

38 3.8 Les pointeurs pa = a; Dans ce cas, on remarque que la valeur de a[i] peut être obtenu avec *(pa+i) ou bien de façon équivalente avec *(a+i). De même l'adresse de l'élément a[i] peut s'obtenir avec &a[i] ou bien de façon équivalente avec pa+i ou bien a+i. Cependant, les instructions a=pa; et a++; sont incorrectes (car si t1 et t2 sont des tableaux, alors l'écriture t1 = t2; est incorrecte), même si les instructions pa=a; et pa++; sont correctes. En résumer, un tableau à une dimension (ou indice) est un pointeur constant, c'est à dire non modiable au cours d'une exécution. Cependant, le principal inconvénient des tableaux à une dimension est que la taille doit être toujours xe. Nous verrons qu'avec les pointeurs, il sera possible de créer des tableaux dont la taille est une variable. Remarque : Comme un pointeur est une variable entière désignant l'adresse d'une autre variable, on peut alors créer un tableau de pointeurs, c-a-d un tableau contenant les adresses d'autres variables. Par exemple, si on veut créer un tableau nommé pt contenant 5 pointeurs de type double (au lieu de créer 5 pointeurs p1,p2,p3,p4,p5 de type double), on écrit l'instruction : double* pt[5]; // au lieu de : double *p1, *p2, *p3, *p4, *p5; Tableaux multidimensionnels Par dénition, un tableau de dimension n est un tableau dont ses éléments sont des tableaux de dimension n 1. Et comme, pour les tableaux à une dimension, l'identicateur (ou nom) d'un tableau à plusieurs dimension représente toujours son adresse de début. Par exemple, la déclaration int mytab[5][3]; fait pointer l'identicateur mytab sur l'adresse du premier élément, c-a-d &mytab[0][0]. Or d'après la dénition d'un tableau, pour tout indice i allant de 0 à 4, mytab[i] est un tableau ayant 3 éléments. Donc pour tout indice i allant de 0 à 4, mytab[i] est un pointeur constant vers l'adresse du premier élément de mytab[i], c-a-d &mytab[i][0]. L'exemple précédent peut se généraliser et donc un tableau multidimensionnel est considéré comme un tableau de pointeurs ou de façon plus formelle comme un pointeur de pointeurs (c-a-d un pointeur dont ses éléments sont des pointeurs). Physiquement, c'est simplement des clusters contenant les adresses d'autres clusters. L'avantage majeur de cette considération est que la taille de tableau peut être une variable. Seulement, il faudra lui réserver de la place en mémoire. Par exemple : int **mytab; // mytab est un tableau d'entiers à deux dimensions char ***mt3; // mt3 est un tableau de caractères à 3 dimensions float ****t4; // t4 est un tableau de float à 4 dimensions struct Complexe **Cpl; /* Cpl est un tableau de structure complexe cependant, il faut que struct Complexe aiet été déclarer auparavant */ Les 4 tableaux de l'exemple précédent n'ont pas de taille xe. Il faudra nécessairement les réserver une place en mémoire pour pouvoir les manipuler. 38 DIAO O. Cours de langage C

39 3.8 Les pointeurs Allocation dynamique de la mémoire Nous avons vu que les pointeurs permettent de manipuler facilement des tableaux, surtout si la taille de ces tableaux n'est pas connu d'avance. Seulement, comme nous l'avons souligner plus haut, quand on crée un pointeur à la place d'un tableau, il faudra lui réserver de la place en mémoire. Et plus généralement, quand on crée un pointeur à la place d'un objet, il faudra lui réserver de la place mémoire. Sans cela, on ne peut pas manipuler le pointeur. Cette opération consistant à réserver de l'espace mémoire à un objet pointé se nomme allocation dynamique. En langage C, les fonctions permettant la gestion dynamique de la mémoire sont dans la bibliothèque stdlib.h. Les principales fonctions permettant d'allouer de la mémoire sont malloc et calloc. Ces deux fonctions demanderont de l'espace mémoire au système quand elles en auront besoin. Fonction malloc : La syntaxe de cette fonction est la suivante : void * malloc(nbre_octets); // nombre d'octets de l'objet Cette fonction retourne un pointeur générique (i.e. de type void). Pour initialiser des pointeurs vers des objets qui ne sont pas de type void, il faudra convertir le type de sortie de la fonction malloc à l'aide d'un cast. Par exemple, si on veut convertir le pointeur générique malloc en un type T (avec T=int, float, double, char, ect.), on utilise la syntaxe suivante : (T *)malloc(sizeof(t)). Exemple : #include <stdlib.h> #include <stdio.h> int main() { int *p; p = (int*)malloc(sizeof(int)); //allocation dynamique *p = 14; *(p + 1) = 10; printf("p = %lx \t *p = %i \t p+1 = %lx \t *(p+1)=%i\n",p, *p, p+1, *(p+1)); return 0; La fonction malloc permet également d'allouer un espace pour plusieurs objets contigus en mémoire. Dans ce cas, on multiple le nombre d'octets par le nombre d'objets. Par exemple, l'instruction (int*)malloc(3*sizeof(int)); va allouer 3 int. Fonction calloc : La fonction calloc a le même rôle que la fonction malloc, mais sa syntaxe est diérente : void * calloc(nbre_objets, nbre_octets); Hormis la syntaxe, la diérence fondamentale entre malloc et calloc, est que la fonction calloc permet d'initialiser l'objet pointé à zéro. Donc la fonction calloc permet de réserver le nombre d'objets fois le nombre d'octets et d'initialiser à zéro. Autrement dit calloc est plus pratique et plus rapide que malloc. Par exemple, si p est un pointeur de type int, alors l'instruction p = (int *)calloc(n, sizeof(int)); est sémantiquement équivalente à : p = (int *)malloc(n * sizeof(int)); for (i = 0; i < N; i++) *(p+i) = 0; 39 DIAO O. Cours de langage C

40 3.8 Les pointeurs Fonction free : L'un des principaux intérêts de la gestion dynamique de la mémoire, c'est de pouvoir récupérer des emplacements dont on n'a plus besoin. Ceci va se réaliser grâce à la fonction free de la bibliothèque stdlib.h. La fonction free doit être associer à toute instruction de type malloc ou calloc. Sa syntaxe est : free(nom-du-pointeur) ; Notons que la fonction free n'est pas obligatoire, sauf si le programme est trop gourmand en ressource mémoire. Pointeurs et tableaux dynamiques : L'équivalence entre pointeur et tableau permet de réaliser des tableaux dynamiques c'est à dire des tableaux dont la taille n'est pas connue au moment de la compilation mais uniquement lors de l'exécution, lorsque le tableau commence à exister. Pour cela, il sut de : 1. remplacer la déclaration du tableau par celle d'un pointeur ; 2. allouer l'espace à l'exécution, avant toute utilisation du tableau, par un appel de malloc ou calloc ; 3. dans le cas d'un tableau local, libérer l'espace à la n de l'utilisation avec free. Par exemple, pour un tableau statique dont la taille est inconnu d'avance, voilà un programme qui ache le triangle de Pascal jusqu'à la n-ième ligne (les coecients de la n-ième ligne sont dénis récursivement à partir des coecients de la n 1-ligne par : Cn p = C p 1 n 1 + C p n 1 #include <stdio.h> #define N_MAX 1000 // N_MAX indispensable avec un tableau statique de taille inconnue void TrianglePascal (int N){ int n, p, i; int tab[n_max]; for (n = 0; n<=n; n++){ tab[0] = tab[n] = 1; for (p=n-1; p>0; p--) tab[p] += tab[p - 1]; for (i=0; i<=n; i++) printf("%d ",tab[i]); printf("\n"); Avec cette fonction, on ne peut pas donner le triangle de Pascal à un ordre supérieur à N_MAX (pour voir cela essayer pour de petites valeurs de N_MAX). Nous allons utiliser les pointeurs pour dénir un tableau dynamique pour la même fonction TrianglePascal : #include <stdio.h> #include <stdlib.h> // à cause de calloc void TrianglePascal (int N) { int n, p, i; int *tab; tab = calloc(n+1,sizeof(int)); if (tab == NULL) return; 40 DIAO O. Cours de langage C

41 3.8 Les pointeurs for (n = 0; n<=n; n++){ tab[0] = tab[n] = 1; for (p=n-1; p>0; p--) tab[p] += tab[p - 1]; for (i=0; i<=n; i++) printf("%d ",tab[i]); printf("\n"); free(tab); /* à ne pas oublier car tab est une variable locale */ Une fonction de teste pour ce deux versions du triangle de Pascal peut être : int main (void){ int a; printf("veuillez entrer la valeur de a\n"); scanf("%d",&a); printf("le triangle de Pascal est : \n"); TrianglePascal(a); return 0; Pointeurs et fonctions Rappel sur les fonctions : La structuration de programme en des sous-programmes se fait en langage C à l'aide de fonctions. Nous avons vu que la création de fonction se fait de la façon suivante : type_résultat nom_fonction ( liste-de-déclarations-des-arguments ) { liste-de-déclarations-de-variables-locales liste-d'instructions En C, toute fonction peut appeler d'autres fonctions et celles-ci peuvent elle-mêmes en appeler. On appelle ceci des appels imbriqués : un appel de fonction se fait à l'intérieur d'un autre appel, qui lui-même se fait à l'intérieur d'un autre appel, etc. Le C ne dénit pas de limite sur le nombre d'imbrications d'appels de fonctions. Pour pouvoir appeler une fonction, il est nécessaire qu'elle soit déclarée ailleurs dans le programme, plus précisément avant l'appel (dans la plus part des compilateurs). En eet, la plus part des compilateurs C lit le chier source.c d'un programme dans l'ordre du texte et a besoin d'avoir rencontré la déclaration d'une fonction pour pouvoir traiter son appel. Cependant, écrire toujours écrire le contenu des fonctions avant de les appeler peut devenir assez dicile lorsque l'on écrit des programmes qui en contiennent beaucoup. Dès lors, pour s'assurer que le compilateur connaît les fonctions que l'on veut utiliser, au moment de leur appel, la déclaration des fonctions peut être séparée en deux parties : d'une part le prototype de la fonction, d'autre part son bloc d'instructions. Le prototype d'une fonction est la partie qui dénit comment on l'utilise : le type de retour de la fonction, son identiant et les paramètres qu'elle prend en entrée. Autrement, le prototype d'une fonction est la déclaration de celle-ci sans son corps. Cela se fait de la manière suivante : type_résultat nom_fonction ( arguments ) ; 41 DIAO O. Cours de langage C

42 3.8 Les pointeurs Dans ce cas, une fois le prototype d'une fonction déni et lu par le compilateur, il devient possible d'appeler cette fonction dans le reste du programme. Le reste de la déclaration de la fonction (c-a-d son implémentation), peut être donné bien plus tard. L'implémentation répète obligatoirement le contenu du prototype, suivi cette fois du bloc d'instructions correspondant. Par exemple, on peut dénir le prototype d'une fonction permettant de calculer la valeur absolue d'un réel de la manière suivante : double valeurabsolue (double reel); Dans ce cas la fonction peut être déni ailleurs de la manière suivante : double valeurabsolue (double reel){ double resultat = reel; if (reel < 0) resultat = -reel; return resultat; Remarque 21 Il ne faudra pas oublier le point-virgule en n du prototype et aussi de dénir la fonction ailleurs dans le corps du programme. Notons que le type de résultat d'une fonction peut être une structure, une union, un pointeur, mais le type de retour ne peut pas être un tableau, une chaîne de caractères ou une fonction. Cependant, il est possible de renvoyer un pointeur qui pointera sur un tableau, ou sur une chaîne de caractères ou bien sur une fonction. Fonctions récursives : Une fonction peut contenir plusieurs instruction return et seule la première instruction return rencontrée permet de sortir du programme. Par exemple, la fonction valeurabsolue précédente peut s'écrire sous la forme de : double valeurabsolue (double reel){ if (reel > 0) return reel; else return -reel; Une fonction récursive est une fonction qui s'appelle elle-même, c-a-d elle se trouvera dans le corps de la fonction. Ces fonctions sont utilisées la plupart du temps avec les suites numériques. Regardons l'exemple de fonction factoriel : int fact(int n){ if (n == 0) return 1; else return n*fact(n-1); // appel récursif Exercice Donner une fonction permettant de calculer une valeur de la suite (u n ) n N avec u 0 = a (à saisir par l'utilisateur) et u n+1 = 3u n Donner une fonction permettant de calculer une valeur de la suite de Fibonacci (f n+2 = f n+1 + f n avec f 0 = 0 et f 1 = 1.). 42 DIAO O. Cours de langage C

43 3.8 Les pointeurs Fonction et pointeurs : Comme une fonction ne peut pas retourner un tableau, une chaîne de caractères ou une fonction, on peut créer alors des pointeurs qui pointeurs sur ces objets impossibles à retourner. Par exemple, la déclaration du prototype suivant double (* myexpo)(double a, int n); spécie que myexpo est un pointeur sur une fonction à deux arguments fournissant un résultat de type double. Dans ce cas, si fct est une fonction ayant le prototype suivant : double fct(double a, int n); Donc on peut écrire l'aectation suivante : myexpo = fct. Attention : Pour pointer sur une fonction, les parenthèses ont leur importance, en eet si l'on écrit simplement double * myexpo(double a, int n);, alors la fonction myexpo retourne un pointeur et alors ne pointe plus sur une fonction. Dans ce cas, ce qu'on peut écrire est : double * myexpo(double a, int n); // on retourne un pointeur double* x; // x n'est pas une fonction *x = myexpo(4.2,3); Remarque : Les arguments d'une fonction peuvent être des pointeurs. Par exemple : #include <stdio.h> void add(int a, int b, int *c) { /* c repère l'entier où on veut mettre le résultat */ *c = a + b; printf("%d + %d = %d \n",a,b,*c); int main() { int i=10,j=14,k; /* on passe les valeurs de i et j comme premiers paramètres */ /* on passe l'adresse de k comme troisième paramètre */ add(i,j,&k); return 0; Remarque : Les arguments d'une fonction peuvent être aussi des pointeurs de fonctions. Par exemple : #include <stdio.h> #include <stdlib.h> enum {FAUX, VRAI; /* operateur_binaire prend deux entiers a et b renvoie f(a,b) ou f est soit la somme, la diffférence, le produit, etc. */ int operateur_binaire(int a, int b, int (*f)(int, int)){ return (*f)(a,b); int somme(int a, int b) { return a+b; int difference(int a, int b){ return a-b; int produit(int a, int b) { return a*b; 43 DIAO O. Cours de langage C

44 3.8 Les pointeurs int division(int a, int b){ int c; if (b==0) printf("error: denominator is null\n"); else c = b/a; return c; int modulo(int a, int b){ return a%b; int main(){ int a, b, c; char op; int imp = VRAI; // indique l'imprimession du résultat printf("choisir a op b\n"); scanf("%d %c %d",&a,&op,&b); switch (op){ case '+' : c = operateur_binaire(a,b,somme); break; case '-' : c = operateur_binaire(a,b,difference); break; case '*' : c = operateur_binaire(a,b,produit); break; case '/' : c = operateur_binaire(a,b,division); break; case '%" : c = operateur_binaire(a,b,modulo); break; default : printf("erreur d'operateur\n"); imp = FAUX; if (imp) printf("%d %c %d = %d",a,op,b,c); return 0; Dans cet exemple, la fonction operateur_binaire a pour arguments un pointeur vers une fonction qui est soit somme, différence, etc.. Noter l'appelle de la fonction somme par la fonction operateur_binaire. La fonction atoi() est une fonction de la bibliothèque stdlib.h, elle permet de convertir une chaîne de caractères en un entier. Arguments de la ligne de commande fonction main : Dans tout programme en C, il y a une fonction main qui ne prend pas d'argument, c-a-d dont l'argument est de type void. Dans ce cas, si le programme à besoin d'un chier externe, on utilise une redirection de commande avec le Shell de Linux ou aussi d'autres bibliothèques. Cependant, avec le langage C, il est possible de spécier un chier externe sans utiliser une redirection. Pour cela, le prototype de la fonction main doit être déclarer de la façon suivante : int main (int argc, char * argv[]); // argc et argv sont obligatoires // argc signifie argument count // argv signifie argument vector Par exemple, la fonction suivante ressemble beaucoup à la fonction echo du script bash de Linux. #include <stdio.h> /* affichage des arguments de la ligne de commande */ int main (int argc, char *argv[]){ 44 DIAO O. Cours de langage C

45 3.8 Les pointeurs int i; printf("nom du programme : %s\n", argv[0]); for (i=1; i < argc ; i++) printf("%s",argv[i]); printf("\n"); return 0; Quand on enregistre le chier avec myecho.c et que le programme exécutable soit myecho.exe, alors, depuis la console, on tape simplement : myecho.exe je choisi ce que je met ici sans les guillemets pour acher Nom du programme : myecho.exe je choisi ce que je met ici sans les guillemets Exercice Structures auto-référencées Nous avons vu que les tableaux, considéré comme des listes, permettent de stocker un nombre xé d'éléments de même type. Dès lors, il sera dicile d'insérer des éléments à l'intérieur d'un tableau, sauf si on crée un autre tableau, dont la taille est plus grande que le premier tableau. Nous avons vu aussi que les pointeurs peuvent être considérer comme des tableaux "dynamiques", c-a-d des tableaux dont la taille n'est connu qu'au moment de son utilisation. Notons que pour pouvoir être utilisé comme un tableau "dynamique", nous devons nécessairement allouer de l'espace mémoire au tableau "dynamique", grâce à malloc ou calloc. Dès lors, il sera aussi dicile d'insérer des éléments à l'intérieur d'un tableau "dynamique" (ou pointeur), sauf si on réallue de la mémoire nécessaire au pointeur. Avec ces deux objets (tableaux et pointeurs), insérer des éléments nécessite une réservation supplémentaire de mémoire. Pour des équipements disposant de peu de mémoire ou des programmes trop "longs", cela peut être coûteux d'insérer des éléments dans un tableau. Ce problème est lié au fait que la taille maximale des tableaux (statiques et dynamiques) soit connue au moment de son utilisation. Pour résoudre ce problème, on utilise un autre représentation des tableaux, appelée représentation chaînée. Dans cette représentation, nous n'avons besoin que de connaître le premier élément du tableau et l'élément qui suit ce premier élément. Plus généralement, nous avons besoin de connaître un élément quelconque du tableau et l'adresse de l'élément suivant. En langage C, pour construire de tel objet, on utilise des structures auto-référencées, c-a-d des structures récursives (au moins un des champs contient un pointeur vers une structure de même type). Dans ce cas, chaque structure contient des données et au moins l'adresse de la structure suivante. Comme le nombre d'éléments doit être ni, alors le dernier élément devra pointer sur l'élément vide, représenté en C par la constante NULL. Selon le nombre de champs pointant sur la structure de même type, on parle de : ˆ liste chaînée, si la structure contient, en plus des données, un seul pointeur vers la structure suivante ; 45 DIAO O. Cours de langage C

46 3.8 Les pointeurs ˆ liste double chaînée, si la structure contient, en plus des données, un pointeur vers la structure suivante et un autre vers la structure précédente ; ˆ arbre, si la structure contient, en plus des données, plusieurs pointeurs pointant chacun vers une branches. Listes chaînées. C'est une structure contenant nécessairement un seul pointeur vers la structure de même type. Sa syntaxe général est de la forme : struct nom_de_la_liste { [des déclarations de types]; struct nom_de_la_liste *psuivant; Exemple sur les polynômes Un polynôme (en mathématique) est tout objet mathématique qui peut s'écrire sous la forme de P [X] = a n X n +a n 1 X n a 1 X+a 0, c'est la somme de plusieurs monômes. Ainsi, pour créer un polynôme, nous allons créer une structure monome contenant un champ degree, un champ valeur et un champ struct monome *suivant permettant la récursivité. Dès lors, un polynôme devient un tableau "dynamique" de structure monome. Le programme suivant permet de créer la structure monome, créer un Polynome comme étant un tableau "dynamique" de monome. En plus, nous créons une fonction RandomPoly, Degree et PrintPoly permettant respectivement de donner un polynôme de façon aléatoire, de déterminer le degré d'un polynôme et d'acher un polynôme. Dans la fonction main, on créera le polynôme P (X) = X 4 + 2X 1. #include <stdio.h> #include <stdlib.h> struct monome { unsigned int degree; // donne le degré du monôme int valeur; // la valeur du monôme struct monome *suivant; // le monôme suivant ; typedef struct monome Monome; // on utilise un synonyme typedef Monome* Polynome; // un polynome est un tableau de monome Polynome allouerpoly(unsigned int n){ return (Polynome)calloc(n+1,sizeof(Monome)); // generation d'un polynome Polynome RandomPoly( unsigned int n ){ int i; Polynome P; P = allouerpoly(n); srand(time(null)); for (i=0;i<=n;i++){ (P+i)->degree = i; (P+i)->valeur = rand(); (P+i)->suivant = P+i+1; 46 DIAO O. Cours de langage C

47 3.8 Les pointeurs if (i==n) {(P+i)->suivant = NULL; return P; // Degree d'un polynome int Degree(Polynome P){ int m,i,k=0; for (; ;k++) if((p+k)->suivant == NULL) {break; m = k; for (i=0;i<k+1;i++){ if ((P+i)->suivant!= NULL) if((p+i)->degree > m) m = (P+i)->degree; return m; void PrintPoly(Polynome P){ int i,d; d = Degree(P); // verifier si le coefficient dominant veut 1 ou -1 if ((P+d)->valeur!= 1) { if ((P+d)->valeur > 0) printf("%d*x^%d",(p+d)->valeur,(p+d)->degree); else if ((P+d)->valeur == -1) printf("-x^%d",(p+d)->degree); else printf("-%d*x^%d",-(p+d)->valeur,(p+d)->degree); else printf("x^%d",(p+d)->degree); // Affichage sur le signe et la valeur du coefficient for(i=d-1;i>=0;i--){ if ((P+i)->suivant!= NULL) if ((P+i)->valeur!= 0) if ((P+i)->valeur > 0){ if ((P+i)->degree == 0) printf(" + %d",(p+i)->valeur); else { if((p+i)->degree!= 1) { if((p+i)->valeur!= 1) printf(" + %d*x^%d",(p+i)->valeur,(p+i)->degree); else printf(" + X^%d",(P+i)->degree); else { if((p+i)->valeur!= 1) printf(" + %d*x",(p+i)->valeur); else printf(" + X"); 47 DIAO O. Cours de langage C

48 3.8 Les pointeurs else { if ((P+i)->degree == 0) printf(" - %d",-(p+i)->valeur); else { if((p+i)->degree!= 1){ if((p+i)->valeur!= -1) printf(" - %d*x^%d",-(p+i)->valeur,(p+i)->degree); else printf(" - X^%d",(P+i)->degree); else { if((p+i)->valeur!= -1) printf(" - %d*x",-(p+i)->valeur); else printf(" - X"); printf("\n"); main (){ Polynome P,Q; int n,dp = 4; P = allouerpoly(dp); P->degree = 0; P->valeur = -1; P->suivant = P+1; (P+1)->degree = 1; (P+1)->valeur = 2; (P+1)->suivant = Q+2; (P+2)->degree = 4; (P+2)->valeur = -1; (P+2)->suivant = NULL; printf("donnez un entier n\t"); scanf("%d",&n); Q = RandomPoly(n); printf("\n\nun polynome aleatoire de degre %d est \n",n); PrintPoly(Q); printf("le polynome P(X)=-X^4+2X-1 est \n"); PrintPoly(P); Exercice 24 Créer les fonctions AddPoly et MultiPoly permettant respectivement d'addition et de multiplier deux polynômes. Pouvez-vous créer les polynômes dans Z/pZ, où p > 1 est un entier naturel? Listes doubles chaînées. Nous aurons une structure contenant nécessairement deux pointeurs récursifs. La syntaxe d'une liste double chaînée est de la forme : struct nom_de_la_liste { [des déclarations de types]; struct nom_de_la_liste *psuivant; 48 DIAO O. Cours de langage C

49 3.8 Les pointeurs struct nom_de_la_liste *pprecedent; Listes multi-chaînées : arbres 49 DIAO O. Cours de langage C

50 4 Gestion des chiers Les programmes écrits jusqu'ici lisaient tous à l'entrée standard (clavier) et écrivaient tous sur la sortie standard (écran). Cependant, comme beaucoup d'autres langages, le C ore la possibilité de lire et d'écrire des données dans un chier. Les chiers que l'on manipule se trouve en général dans la mémoire de masse (disque dur, clé usb, etc.). Avant de lire ou d'écrire dans un chier, il faut d'abord ouvrir ce chier à l'aide de la fonction fopen de la bibliothèque standard stdio.h. Dès l'ouverture d'un chier, le compilateur charge le chier dans le buer (mémoire tampon).ainsi, dès l'ouverture d'un chier, on dispose de certaines informations relatives au chier, notamment son adresse dans le buer, la position de la tête de lecture, ses attributs, etc. Pour le langage C, toutes ses informations sont rassemblées dans une seule structure de la bibliothèque standard stdio.h, dont le synonyme (avec typedef) utilisé est FILE *. Après les traitements d'un chier, il faut libérer l'espace occupé dans le buer par le chier, ce qui se fait grâce à la fonction fclose. Ceci s'avère nécessaire car la plupart des systèmes d'exploitation limitent le nombre de chiers qu'un programme (ici le compilateur) peut ouvrir simultanément. 4.1 Ouverture et fermeture de chiers Ouverture d'un chier : fopen Lorsqu'on désire manipuler un chier (extérieur au compilateur), il est nécessaire de l'ouvrir à l'aide de la fonction fopen. La syntaxe de cette fonction est : fopen("nom-de-fichier","mode"); Cette fonction retourne un pointeur de type FILE et a 2 arguments qui sont des chaînes de caractères (des pointeurs de type char) : un nom de chier et un mode (ou attribut) d'accès. En langage C, on distingue deux types de chiers informatiques : un chier texte et un chier binaire. Un chier texte est un chier dont le contenu représente uniquement une suite de caractères imprimables, d'espaces et de retours à la ligne. Tandis qu'un chier binaire est un chier dont le contenu est formé de bits qui ne peuvent pas être représenté par simple suites de caractères imprimables. Généralement, les chiers textes sont créés avec un éditeur de texte comme gedit, notepad, emacs, etc. Les diérents modes ou attributs possibles sont : "r" (read) "w" (write) "a" (append) "r+" "w+" "a+" ouvre d'un chier texte en lecture. crée un chier texte en écriture ou bien écrase le contenu précédent si le chier existe. ajoute (ouvre ou crée) un chier texte et se positionne en écriture à la n du chier. ouvre un chier texte en mode mis à jour (c-a-d lecture/écriture). crée un chier texte en lecture/écriture ou si le chier existe il l'écrase le contenu ouvre un chier texte en lecture/écriture et se positionne à la n du chier. Table 6 Les diérents modes des chiers avec fopen 50 DIAO O. Cours de langage C

51 4.2 Lecture et écriture par caractères sur chier Quand le chier est un chier binaire, alors on ajoute un b comme "rb", "wb", "ab", "r+b", "w+b", "a+b". Remarque : Si fopen ne s'exécute pas normalement, alors il renvoie la valeur NULL. Voies de communication standard : Quand un programme est lancé par le système, alors le programme ouvre trois chiers correspondants aux trois de modes de communication standard : input, output et error. Dans la bibliothèque standard, il y a trois constantes prédénies correspondants aux trois chiers, à savoir stdin,stdout et stderr respectivement Fermeture d'un chier : fclose La fonction fclose permet de fermer le chier déjà ouvert et de libérer le buer. Son prototype est : int fclose(file *stream); Autrement dit, fclose reçoit en entrée, un pointeur de type FILE (qui n'est rien d'autres d'un ot de données) et retourne un entier. En cas d'erreur de fermeture, fclose retourne EOF, sinon elle retourne zéro. Exemple : Ouverture et fermeture d'un chier #include <stdio.h> int main() { FILE *fp1,fp2; fp1 = fopen("donnees.txt","r"); if(fp1 == NULL){ printf("impossible d'ouvrir le fichier donnee en lecture\n"); fp2 = fopen("donnees.txt","a"); if (fp2 == NULL) { printf("le fichier va etre creer\n"); fclose(fp2); // on rompt le lien entre fp2 et donnnees.txt 4.2 Lecture et écriture par caractères sur chier Lecture par caractères : fgetc Nous avons vu que la fonction getchar permet de lire un caractère saisi dans l'entré standard. La fonction fgetc permet de lire un caractère du chier spécié par un pointeur stream de type FILE et retourne le caractère lu comme un unsigned char (converti en entier) ou bien EOF en cas d'erreur. Son prototype est : Par exemple : int fgetc(file *stream); 51 DIAO O. Cours de langage C

52 4.2 Lecture et écriture par caractères sur chier #include <stdio.h> #include <stdlib.h> // à cause de la fonction exit int main (int argc, char *argv[]){ int c; // c contiendra le caractère FILE *fp; // fp contiendra notre fichier if (argc == 1) { printf("erreur: %s pas de fichier specifie\n",argv[0]); exit (1); int i; for (i = 1; i < argc; i++){ fp = fopen(argv[i],"r"); if (fp == NULL) { printf("erreur:%s n'existe pas\n",argv[i]); exit(1); else { while ((c = fgetc(fp))!= EOF) // utilisation de fgetc printf("%c",c); fclose(fp); return 0; Remarque : la fonction fgetc ne peut pas évaluer stream plus d'une fois, autrement dit, elle peut admettre des paramètres sous la forme d'un tableau de type FILE. Pour pouvoir faire cela, le langage C dispose d'un macro qui est getc ayant le même prototype que la fonction fgetc, mais qui peut évaluer un tableau de FILE *. Par exemple : int i,c; FILE * TAB_FILE[10]; c = getc(tab_file[i++]); // ceci n'est pas possible avec fgetc Écriture par caractères : fputc Comme putchar, la fonction fputc permet d'écrire un caractère dans un chier. Le prototype de cette fonction est : int fputc (int c, FILE *stream); Cette fonction écrit le caractère c de type int dans le chier spécié par le pointeur stream de type FILE. En cas d'erreur, fputc renvoie EOF. Exemple, le programme suivant copie le premier chier dans le deuxième chier. #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *f_in, *f_out; int c; f_in = fopen(argv[1],"r"); // Ouverture du fichier f_in en lecture f_out = fopen(argv[2],"w"); // Ouverture du fichier f_out en écriture if (f_in == NULL) { printf("\nerreur: Impossible de lire %s\n",argv[1]); return(exit_failure); 52 DIAO O. Cours de langage C

53 4.2 Lecture et écriture par caractères sur chier if (f_out == NULL) { printf("\nerreur: Impossible d'ecrire dans %s\n",argv[2]); return(exit_failure); // Recopie du contenu de ENTREE dans SORTIE while ((c = fgetc(f_in))!= EOF) fputc(c, f_out); // Fermeture des flots de donnees fclose(f_in); fclose(f_out); return(exit_success); On notera l'utilisation des constantes EXIT_SUCCESS (valant 0) et EXIT_FAILURE (valant 1), dénies dans la librairie stdlib.h et qui sont les paramètres privilégiés de la fonction exit Relecture d'un caractère : ungetc Le prototype de la fonction ungetc est : int ungetc(int c, FILE *stream); La fonction ungetc remet le caractère c (convertit en int) dans le ot stream, où il sera retrouver à la prochaine lecture ; cependant, on ne peut pas remettre EOF. La fonction ungetc retourne le caractère remis, ou bien EOF en cas d'erreur. Par exemple, le programme suivant lit le chier d'entrée et à chaque fois qu'il retrouve le caractère #, il le remplace par le caractère /. #include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { FILE *fi,*fo; int c; fi = fopen(argv[1],"r"); fo = fopen(argv[2],"w"); // Ouverture du fichier f_out en écriture if (fi == NULL) { printf("\nerreur: Impossible de lire %s\n",argv[1]); return(exit_failure); if (fo == NULL) { printf("\nerreur: Impossible d'ecrire dans %s\n",argv[2]); return(exit_failure); while ((c = fgetc(fi))!= EOF) { if (c == '#') ungetc('/',fi); fputc(c,fo); fclose(fi); fclose(fo); return 0; 53 DIAO O. Cours de langage C

54 4.3 Lecture et écriture par lignes sur chier 4.3 Lecture et écriture par lignes sur chier Avec le langage C, on peut lire et écrire lignes par lignes et non caractères par caractères Lecture par lignes : fgets La fonction de lecture par ligne est fgets et son prototype est : char *fgets(char *s, int n, FILE *stream); La fonction fgets lit au plus n 1 caractères du ot *stream et les place dans le tableau de caractères s. Lors que fgets rencontre une n de ligne, elle termine le tableau par le caractère \0 avant de le retourner ; et en cas d'erreur, elle retourne NULL Écriture par lignes : fputs La fonction d'écriture par ligne est fputs et son prototype est : int fputs(char *s, FILE *stream); Cette fonction écrit la chaîne de caractères sur le ot stream, et retourne une valeur non négatif (positif ou null) si l'écriture se passe normalement, et retourne EOF en cas d'erreur. 4.4 Entrées et Sorties formatées sur chiers Entrée formatée : fscanf Comme scanf, la fonction fscanf permet de lire les données dans un chier de type FILE. Son prototype est : int fscanf(file *stream, char *format,...); On met de suspension dans les arguments de fscanf pour indiquer que cette fonction admet un nombre variable de paramètres. Elle lit les données du ot stream d'après les spécications incluses dans format (identique à celui de scanf) et aecte les valeurs converties aux arguments suivants (qui doivent être des pointeurs ou désigner par leurs adresses comme avec scanf). En cas d'erreur, fscanf retourne EOF ou une valeur négative, sinon elle retourne le nombre d'objets convertis et aectés Sortie formatée : fprintf Comme la fonction printf, la fonction fprintf permet d'écrire dans un chier. Son prototype est : int fprintf(file *stream, char *format,...); Comme dans les arguments de fscanf, les trois points de suspension désignent un nombre variable d'arguments. La fonction fprintf convertit ses arguments d'après les spécications du format (identique à celui de printf et écrit le résultat sur le ot stream. En cas d'erreur, fprintf retourne EOF ou une valeur négative, sinon elle retourne le nombre d'objets convertis et aectés. Exemple 54 DIAO O. Cours de langage C

55 4.5 Entrées-sorties binaires : fread et fwrite #include <stdio.h> int main () { char str [80]; float f; FILE * pfile; pfile = fopen ("myfile.txt","w+"); //si myfile.txt n'existe pas, on le créé. fprintf (pfile, "%f %s", , "PI"); rewind (pfile); // pour se positionner au début du fichier fscanf (pfile, "%f", &f); fscanf (pfile, "%s", str); fclose (pfile); printf ("I have read: %f and %s \n",f,str); return 0; 4.5 Entrées-sorties binaires : fread et fwrite Comme un chier binaire est une copie de son code machine en mémoire, alors on utilise diérentes fonctions pour lire et écrire dans des chiers binaires. Les deux fonctions pour lire et écrire dans un chier binaire sont fread et fwrite. Leurs prototypes sont : size_t fread(void *ptr, size_t size, size_t nobj, FILE *stream) size_t fwrite(void *ptr, size_t size, size_t nobj, FILE *stream) où : ptr est un pointeur donnant l'adresse du début de données à transférer. S'il s'agit d'un tableau, alors on indique simplement son identicateur (son nom sans l'opérateur d'adresse &), par contre si c'est une structure on doit utiliser l'opérateur d'adresse &. size est la taille des objets à transférer. nbre est le nombre d'objets à transférer. stream est le ot de donnée de type FILE * La fonction fread lit sur le ot stream au plus nobj objets de taille size et les place dans le tableau ptr. Si tout fonctionne bien, fread retourne le nombre d'objets eectivement lus. Si ce nombre est inférieur au nombre de blocs demandés, c'est soit qu'on a atteint la n du chier, soit il y a erreur. Pour éviter des erreurs de lecture, il faut déterminer l'état du ot avec les fonctions feof et ferror de la bibliothèque errno.h. Les fonctions feof et errno ont pour prototypes : int feof(file *stream); int ferror(file *stream); La fonction feof retourne une valeur non nulle (c-a-d vraie) si l'indicateur de n de chier EOF est rencontré, tandis la fonction ferror retourne une valeur non nulle (c-a-d vraie) si l'indicateur d'erreur associé au chier est positionné. La fonction fwrite écrit nobj objets de taille size du tableau ptr sur le ot stream. Si tout se passe bien, elle retourne le nombre d'objets eectivement écrits. Si ce nombre est inférieur au nombre prévu, cela signie qu'une erreur est survenue lors de l'exécution. 55 DIAO O. Cours de langage C

56 4.6 Positionnement dans un chier rewind, fseek et ftell Exemple : le programme suivant écrit un tableau d'entiers avec fwrite dans le chier donné en argument, puis lit ce chier avec fread et imprime les éléments du tableau. #include <stdio.h> #include <stdlib.h> #define NB 100 int main(int argc, char *argv[]) { FILE *f_in, *f_out; int *tab1, *tab2; int i; tab1 = (int*)malloc(nb * sizeof(int)); // allocation de tab1 tab2 = (int*)malloc(nb * sizeof(int)); // allocation de tab2 for (i = 0 ; i < NB; i++) tab1[i] = i; /* ecriture du tableau dans f_out */ f_out = fopen(argv[1], "w"); if (f_out == NULL) { printf("\nimpossible d'ecrire dans %s\n",argv[1]); return(exit_failure); fwrite(tab1, NB * sizeof(int), 1, f_out); fclose(f_out); /* lecture dans f_in */ f_in = fopen(argv[1], "r"); if (f_in == NULL) { printf("\nimpossible de lire dans %s\n",argv[1]); return(exit_failure); fread(tab2, NB * sizeof(int), 1, f_in); fclose(f_in); for (i = 0 ; i < NB; i++) printf("%d\t",tab2[i]); printf("\n"); return(exit_success); Les éléments du tableau sont bien achés à l'écran, Par contre, on constate que le contenu du chier sortie n'est pas lisible avec les programmes Linux (more, less, cat, etc.) même si sa taille n'est pas nulle (avec la commande Linux ls -l). Ceci s'explique par le fait que le chier de sortie n'est pas encodé, il est simplement un chier de données. 4.6 Positionnement dans un chier rewind, fseek et ftell Les diérentes fonctions d'entrées-sorties permettent d'accéder à un chier en mode séquentiel : les données du chier sont lues ou écrites les unes à la suite des autres. Il est également possible d'accéder à un chier en mode direct, c'est-à-dire que l'on peut se positionner à n'importe quel endroit du chier. Fonction rewind : Son prototype est : Pour se placer en début de chier, on utilise la fonction rewind. 56 DIAO O. Cours de langage C

57 4.6 Positionnement dans un chier rewind, fseek et ftell int rewind(file *stream); Cette positionne le pointeur de stream au début du chier pour la lecture ou l'écriture. Par exemple, le programme suivant : #include <stdio.h> int main () { int n; FILE * fp; char buffer [27]; fp = fopen ("myrewindfile.txt","w+"); for ( n='a' ; n<='z' ; n++) fputc (n, fp); rewind (fp); fread (buffer,1,26,fp); fclose (fp); buffer[26]='\0'; puts (buffer); return 0; Fonction fseek : Cette fonction permet de se positionner à n'importe qu'elle endroit d'un chier. Son prototype est : int fseek(file *stream, long deplacement, int origine); où : * stream est le ot de données. deplacement est la nombre d'octets que le curseur va se déplacer. origine est le commencement du déplacement La fonction fsek déplace le curseur de deplacement d'octets relativement à origine, avec origine qui peut valoir SEEK_SET (début), SEEK_CUR (position courante) ou SEEK_END (n du chier). En cas d'erreur, fseek retourne une valeur non nulle. Par exemple, le programme suivant : #include <stdio.h> int main (){ FILE * fp; fp = fopen ("exemple.txt", "w" ); fputs ("Ceci est unes iple exemple!", fp ); fseek (fp, 11, SEEK_SET ); fputs (" sim", fp ); fclose ( fp ); return 0; créera un chier exemple.txt qui contiendra Ceci est un simple exemple! Fonction ftell : Cette fonction permet de savoir la position du curseur dans un chier. Son prototype est : int ftell(file *stream); La fonction ftell retourne la position courante du curseur dans le chier, en nombre d'octets depuis le début du chier. EN cas d'erreur, elle retourne -1L. 57 DIAO O. Cours de langage C

58 5 Interaction entre C et les autres langages 5.1 Interaction avec le système Exécution d'une commande ou d'un programme Avec le langage C, il est possible d'exécuter une commande externe (ou programme du système) grâce à la fonction mystes de la bibliothèque stdlib.h. Le prototype de cette commande est : int system (const char * string); Cette fonction exécute la commande contenue dans la chaîne de caractères spéciée par *string (son contenu dépendant du système d'exploitation). Par exemple, pour lister le contenu du répertoire /home d'un système Linux, on implémente simplement le programme suivant : #include <stdio.h> // pour printf #include <stdlib.h> // pour system main(){ printf("affichage du repertoire /home\n"); printf("\n \n"); system("ls /home"); printf("\n \n"); Notons que dans cet exemple, on peut enlever les instructions avec printf et donc la bibliothèque stdio.h. Si nous utilisons le système Windows et que nous voulons lister les chiers du dossier C:\Sers, alors le programme précédent devient : #include <stdio.h> // pour printf #include <stdlib.h> // pour system main(){ printf("affichage du repertoire C:\\Users\n"); // car le caractère '\' est donné par '\\' printf("\n \n"); system("dir C:\\Users"); printf("\n \n"); Dès lors, nous avons plusieurs possibilités avec la fonction mystes, comme exécuter tout programme du système. Nous allons donner un exemple d'exécution du logiciel maple. Les utilisateurs d'autres logiciels comme matlab, magma, sage, pari GP, etc. peuvent adapter l'exemple donné avec maple. Exemple d'exécution du logiciel maple grâce à mystes. Supposons que nous voulons donner la liste des nombres premiers entre deux entiers m et n avec n m. Nous allons alors créer, grâce au langage C, un chier nommé imprimes.m contenant toutes les commandes de maple et qui va être exécuter par ce dernier. 58 DIAO O. Cours de langage C

59 5.1 Interaction avec le système #include <stdio.h> // pour printf #include <stdlib.h> // pour system main(){ long int m, n; FILE *fp; fp = fopen("myprimes.m","w"); if (fp == NULL){ printf("\nerreur : Impossible d'ecrire dans le fichier\n"); exit(0); printf("donner deux nombres entiers\t"); scanf("%ld %ld",&n, &m); long int temp = 0; if (n < m){ temp = n; n = m; m = temp; fprintf(fp,"m := %ld: n := %ld: L:=[]:\n",m,n); fputs("for i from m to n do\n",fp); fputs("if isprime(i) = true then L := [op(l),i];\n",fp); fputs("end if;end do;\n",fp); fputs("print(l);\nquit;\n",fp); fclose(fp); // fin d'écriture du fichier myprimes.m // début d'exécution du logiciel maple system("maple myprimes.m > File.Primes.out"); Supposons que notre chier source s'appelle maple.exemple.c et que le chier compilé s'appelle Maple.Primes.exe (grâce à cc maple.exemple.c o Maple.Primes.exe). Alors, le répertoire courant contiendra nécessairement les chiers suivants : maple.exemple.c, Maple.Primes.exe, myprimes.m et File.Primes.out. Le chier de sortie File.Primes.out, créer grâce à une redirection de maple, contiendra la liste des nombres premiers compris entre les entiers m et n saisi au clavier. Remarque : D'autres fonctions du langage C peuvent être utiliser pour exécuter des commandes, notamment les fonctions : execl, execlp, execle, execv et execvp de la bibliothèque <unistd.h>. Pour plus d'information sur ces fonctions, faire man execl Programmation modulaire et automatisation Il est possible en C de séparer son programme en plusieurs chiers.c et de les compiler indépendamment les uns des autres, pour les réunir ensuite en un même programme. Si vous écrivez un gros projet, cela permet de le séparer en plusieurs parties et de travailler indépendamment sur chaque partie. Le même chier source.c peut ensuite être utilisé dans plusieurs programmes, qui appellent les fonctions qui y sont dénies. Pour éviter au compilateur de relire un chier.c à chaque fois qu'un autre chier fait appel à une fonction qu'il contient, on utilise des chiers supplémentaires. Ces chiers, nommés chiers d'en-tête, contiennent les prototypes de fonctions se trouvant dans d'autres chiers sources. On leur donne en général l'extension ".h" (h pour header, qui signie en-tête en anglais). 59 DIAO O. Cours de langage C

60 5.2 Interaction avec Maple 5.2 Interaction avec Maple Nous avons vu qu'on peut exécuter des commandes maple (ou matlab, magma, sage, pari GP, etc.). Cependant, cela ne permet pas d'avoir un code utilisable en C. Grâce à maple, on peut transformer un code sous maple en un code du langage C. Pour cela, maple contient un package nommé CodeGeneration. Ce package peut transformer un code maple en C, Fortran, java, matlab, VisualBasic, etc. Donc, pour pouvoir traduire un code maple en C, il faut d'abord inclure le package CodeGeneration avec : > with(codegeneration); Dès lors, pour générer un code maple en C, il faut juste taper, à la suite : > C(MyProg); # où MyProg est notre programme. Par exemple, on va transformer le programme qui le calcul du PCGD de maple vers C : > with(codegeneration); > MyGCD := proc(a,b) local A,B,R; A:=a:B:=b: while B <> 0 do R:=B: B:=A mod B: A:=R: end do: return R: end proc: > C(MyGCD); # cela donnera int eucl_iter (double a, double b) { int A; int B; int R; A = (int) a; B = (int) b; while (B!= 0) { R = B; B = A % B; A = R; return(r); pour avoir des entiers, il faut faire > C(MyGCD, defaulttype = integer); 60 DIAO O. Cours de langage C

61 6 Bibliothèque standard Tout compilateur C est fourni avec de nombreuses fonctions déjà programmées, que l'on peut utiliser dans nos programmes. Ces ensembles de fonctions destinées à être utilisées dans des programmes sont en général appelées bibliothèques de fonctions. La bibliothèque de fonctions fournie avec votre compilateur est ainsi appelée la bibliothèque standard. Cette bibliothèque standard contient de nombreuses fonctions prédénies que nous allons voir dans cette partie. Selon, les normes considérées, les chiers de la bibliothèque standard change considérablement, à chaque nouvelle norme, on ajoute ou enlevé des chiers bibliothèques. Ainsi la norme ANSI 89 dénit les 15 chiers bibliothèques suivants : assert.h float.h math.h stdarg.h stdlib.h ctype.h limits.h setjmp.h stddef.h string.h errno.h locale.h signal.h stdio.h time.h A ces fonctions de la bibliothèque standard, la norme ANSI/ISO 99 en ajoute les 9 fonctions suivantes : complex.h iso646.h tgmath.h fenv.h stdbool.h wchar.h inttypes.h stdint.h wctype.h Certaines plateformes ajoutent d'autres chiers bibliothèques selon leur besoin, c'est le cas notamment de : mysql.h, windows.h, crypt.h, etc. Pour obtenir de l'aide sur une bibliothèque en particulier, on peut utiliser la commande man de Linux, par exemple : man assert donne tous les détails de la bibliothèque assert.h. Notons, enn que pour pouvoir utiliser les fonctions d'un chier bibliothèque, il faudra l'inclure grâce à la commande include avant toute utilisation, par exemple pour include le chier assert.h, on écrit dans l'entête de notre chier source la directive #include <assert.h> 6.1 #include <assert.h> : diagnostiques d'erreurs Cette bibliothèque fournit une seule fonction dont le prototype est : void assert(int expression); Si expression est fausse, le programme est stoppé sur une terminaison anormale. 6.2 #include <complex.h> : gestion des nombres complexes Cette bibliothèque permet de manipuler aisément les nombres complexes, il permet de déclarer un type complexe de la forme : double complex a=7+3*i; // a est un complexe, 7 = réel(a) et 3 = imag.(a) double complex b=4-6*i; double complex p = a*b; // produit de deux complexes double complex s = a+b; // somme de deux complexes double complex d = a/b; // division de deux complexes 61 DIAO O. Cours de langage C

62 6.3 #include <ctype.h> : manipulation de caractères Le prototype des principales fonctions accessibles avec cette bibliothèque sont : Prototype double cabs(double complex); double carg(double complex); double cimag(double complex); double creal(double complex); double complex conj(double complex); double complex cexp(double complex); Description valeur absolue d'un nombre complexe argument d'un nombre complexe partie imaginaire d'un nombre complexe partie réelle d'un nombre complexe conjugué d'un nombre complexe écriture exponentielle d'un complexe 6.3 #include <ctype.h> : manipulation de caractères Pour manipuler des caractères, on dispose avec cette bibliothèque, des fonctions de testes et des fonctions de conversions. Le prototype des fonctions de testes de la bibliothèque ctype.h est : Prototype Description : teste si c est int isalnum(int c) une lettre ou un chire int isalpha(int c) une lettre int isascii(int c) (Linux) un caractère ASCII (0,..,127) int isblank(int c) un espace ou une tabulation int iscntrl(int c) un caractère de contrôle (ASCII : 0,..,0x1F et 0x7F) int isdigit(int c) est un chire décimal int isgraph(int c) un caractère imprimable sauf l'espace int islower(int c) une lettre minuscule int isprint(int c) un caractère imprimable y compris l'espace int ispunct(int c) un signe de ponctuation int isspace(int c) un espace, un saut de page, une n de ligne, un retour chariot, une tabulation int isupper(int c) une lettre majuscule int isxdigit(int c) un chire hexadécimal Quand le teste est faux, ces fonctions précédentes retournent la valeur zéro. On dispose de deux fonctions de conversion de caractères : int toascii(int c) int tolower(int c) int toupper(int c) (Linux) convertir c en caractère ASCII convertir c en minuscule convertir c en majuscule 6.4 #include <errno.h> : gestion des erreurs La bibliothèque errno.h ne contient qu'une seule variable globale : extern int errno; La valeur de cette variable est un numéro de la dernière erreur détecter par le système. Donc, cette valeur n'est signicative que s'il y a eu une erreur, c-a-d si sa valeur de retour est 1. Dans ce cas, errno indique quel type d'erreur s'est produit. La liste des valeurs 62 DIAO O. Cours de langage C

63 6.5 #include <fenv.h> : environnement à virgule ottante valides est trop longue, et elle est disponible avec man errno. Avec cette bibliothèque et la bibliothèque stdio.h, on peut gérer facilement les erreurs grâce aux fonctions suivantes : Prototype void clearerr(file *stream) int feof(file *stream) int ferror(file *stream) void perror(char *s) Description remet à zéro les indicateurs d'erreur et de EOF teste si l'indicateur de n de chier est atteint teste si l'indicateur d'erreur est positionné imprime la chaîne s et un message pour errno 6.5 #include <fenv.h> : environnement à virgule ottante Cette bibliothèque contient onze fonctions permettant de paramétrer, en ottante : 1. la gestion des exceptions, c-a-d des erreurs (débordement, division par zéro, etc.) ; 2. la gestion des arrondis ; 3. la gestion des environnements. Quand cette bibliothèque est présente dans un chier source.c, on aura sûrement besoin de l'option lm quand on utilise gcc Gestion des erreurs ou exceptions En virgule ottante, les erreurs ou exceptions sont représentées de deux manières : soit par un unique bit ou soit par une structure. La gestion des erreurs ou exceptions passe par 6 constantes symboliques et 5 fonctions de la bibliothèque fenv. Les constantes symboliques sont : FE_DIVBYZERO : division par 0 ; FE_INEXACT : le résultat de l'opération n'est pas exact ; FE_INVALID : résultat indéni ; FE_OVERFLOW : dépassement de capacité ; FE_UNDERFLOW : sous-dépassement de capacité ; FE_ALL_EXCEPT : désigne toutes les constantes précédentes. Les prototypes des 5 fonctions permettant la gestion des exceptions sont : 1. int feclearexcept(int exc) : eace toutes les exceptions de exc ; 2. int fegetexceptflag(fexcept_t *flp, int exc) : stocke exc dans *flp ; 3. int feraiseexcept(int exc) : déclenche l'exception dans les bits de exc ; 4. int fesetexceptflag(const fexcept_t *flp, int exc) : xe l'état de exc en employant *flp (*flp étant le résultat d'un appel préalable de fegetexceptflag) ; 5. int fetestexcept(int exc) : renvoie les bits correspondants à exc. 63 DIAO O. Cours de langage C

64 6.6 #include <float.h> : paramétrage des nombres ottants Gestion des arrondis En virgule ottante, les arrondis sont caractérisés par 4 constantes symboliques : FE_DOWNWARD (arrondi vers la valeur inférieure), FE_TONEAREST (arrondi vers la valeur la plus proche), FE_TOWARDZERO (partie entière), FE_UPWARD (arrondi vers la valeur supérieure). Ces constantes symboliques sont gérées par deux fonctions : int fegetround(void) : lit la méthode d'arrondi courante int fesetround(int rnd-mode) : change le mode d'arrondi par rnd-mode Gestion des environnements L'environnement de travail en virgule ottante peut être manipulé via 4 fonctions de fenv.h sous forme d'un seul objet opaque de type fenv_t. L'environnement par défaut est représenté par la constante FE_DFL_ENV. int fegetenv(fenv_t *evp) : sauvegarde l'environnement courant dans *evp ; int feholdexcept(fenv_t *evp) : eace tous les drapeaux d'exception et bascule en mode non-stop (continuer en présence d'exceptions) ; int fesetenv(const fenv_t *evp) : recharge l'environnement grâce à *evp ; int feupdateenv(const fenv_t *evp) : sauve l'état des exceptions dans une mémoire automatiquement, installe l'environnement de *evp puis déclenche les exceptions sauvegardées. 6.6 #include <float.h> : paramétrage des nombres ottants Cette bibliothèque contient des constantes symboliques qui caractérisent les types réels. Pour le type float, nous avons les constantes suivantes : Constante Minimum Description FLT_DIG 6 précision, en chires décimaux FLT_EPSILON 1E5 le plus petit oat x tel que x! = 1.0 FLT_MAX 1E+37 le plus grand nombre du type oat FLT_MIN 1E37 le plus petit nombre du type oat FLT_RADIX 2 base de la représentation exponentielle FLT_ROUNDS mode d'arrondi Pour le type double, nous avons les constantes suivantes : Constante Minimum Description DBL_DIG 10 nombre de chires signicatifs d'un double DBl_EPSILON 1E9 le plus petit double x tel que x!= 1.0 DBL_MAX 1E+37 le plus grand nombre du type double DBL_MIN 1E37 le plus petit nombre du type double 64 DIAO O. Cours de langage C

65 6.7 #include <inttypes.h> : autres types entiers de taille xée 6.7 #include <inttypes.h> : autres types entiers de taille xée Un type int étant généralement codé sur 16 ou 32 bits, cette bibliothèque déni certains types d'entiers dont le codage machine est xée : type int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t intptr_t uintptr_t Description type entier signé sur 8 bits type entier signé sur 16 bits type entier signé sur 32 bits type entier signé sur 64 bits type entier non signé (positif) sur 8 bits type entier non signé (positif) sur 16 bits type entier non signé (positif) sur 32 bits type entier non signé (positif) sur 64 bits entier signé pouvant stocker un pointeur (une adresse) entier non signé pouvant stocker un pointeur (une adresse) 6.8 #include <iso646.h> : alias d'opérateurs logiques et binaires Cette bibliothèque dénit des alias (synonymes) aux opérateurs logiques et binaires Opérateurs logiques Opérateurs binaires && and & bitand or bitor! not xor compl Avec les opérateurs d'aectation &= and_eq = or_eq = xor_eq!= not_eq 6.9 #include <limits.h> : valeur limite des entiers Comme pour la bibliothèque float.h, le chier d'en-tête limits.h dénit des constantes symboliques précisant les intervalles de valeur que peuvent prendre des entiers : 65 DIAO O. Cours de langage C

66 6.10 #include <locale.h> : paramètres régionaux Type Minimum (valeur) Maximum (valeur) char CHAR_MIN (0 ou SCHAR_MIN) CHAR_MAX (UCHAR_MAX ou SCHAR_MAX) signed char SCHAR_MIN ( ) SCHAR_MAX (2 7 1) unsigned char (non déni) (0) UCHAR_MAX (2 8 1) short SHRT_MIN ( ) SHRT_MAX (2 15 1) unsigned short (non déni) (0) SHRT_MAX (2 16 1) int INT_MIN ( ) INT_MAX (2 31 1) unsigned int (non déni) (0) UINT_MAX (2 32 U 1U) long LONG_MIN ( 2 63 L + 1L) LONG_MAX (2 63 L 1L) unsigned long (non déni) (0) ULONG_MAX (2 64 UL 1UL) long long LLONG_MIN ( 2 63 LL + 1LL) LLONG_MAX (2 63 LL 1LL) unsigned long long (non déni) (0) ULLONG_MAX (LLONG_MAX*2ULL + 1) Le chier limits.h dénit aussi la constante CHAR_BIT, valant 8, et correspondant au nombre de bits du type char #include <locale.h> : paramètres régionaux Le C permet de gérer les paramètre régionaux, c-a-d un ensemble de règles linguistiques et culturelles : langue, jeu de caractères, conventions lexicographiques, monnaie etc. Un programme doit être capable de déterminer les paramètres de l'utilisateur et d'agir en conséquence pour être portable dans divers environnements culturels. Le - chier d'en-tête locale.h déclare les types de données, les fonctions et les macros utilisés pour ces tâches. Les prototypes des deux fonctions pour gérer cela sont : struct lconv *localeconv (void); char *setlocale (int category, const char * locale); localeconv : cette fonction renvoie un pointeur sur une struct lconv (dénie dans le chier locale.h) conforme à la localisation en cours. setlocale : cette fonction est utilisée pour indiquer ou demander la localisation courante du programme (pour un programme portable, locale doit valoir C ou POSIX). Le premier argument category doit valoir : LC_ALL : toutes les fonctions utilisant les localisations. LC_COLLATE : agit sur les fonctions strcoll() et strxfrm() de comparaison de chaînes dans l'alphabet local. LC_CTYPE : classication des caractères et conversion de casse. LC_MESSAGES : formats des messages d'information et la saisie des réponses interactives. LC_MONETARY : formats monétaire. LC_NUMERIC : formats numériques, non monétaire. LC_TIME : formats de date et de temps. 66 DIAO O. Cours de langage C

67 6.11 #include <math.h> : fonctions mathématiques 6.11 #include <math.h> : fonctions mathématiques Pour utiliser les fonctions de cette librairie, il faut en plus de l'inclusion de la librairie par la directive #include <math.h> ajouter l'option lm au moment de la compilation avec gcc. Le résultat et les paramètres de toutes ces fonctions sont de type double. fonction action fonction action acos arc cosinus cos cosinus asin arc sinus sin sinus atan arc tangente tan tangente cosh cosinus hyperbolique log logarithme népérien sinh sinus hyperbolique exp exponentielle tanh tangente hyperbolique log10 logarithme en base 10 pow puissance sqrt racine carrée fabs valeur absolue fmod reste de la division ceil partie entière supérieure floor partie entière inférieure 6.12 #include <setjmp.h> : sauts non locaux Nous avons déjà vu l'instruction goto qui permet de réaliser des branchements ou saut au sein d'une même procédure. Pour réaliser des sauts à l'extérieur d'une procédure, il faut utiliser les fonctions setjmp et longjmp de la bibliothèque setjmp.h. Les prototypes de ces fonctions sont : int setjmp(jmp_buf env); void longjmp(jmp_buf env, int val); Plus précisément, les fonctions setjmp et longjmp sont utilisées pour gérer les erreurs et les interruptions rencontrées dans des routines bas-niveau. La fonction setjmp sauvegarde l'état du programme dans env, en vue de son utilisation ultérieure avec la fonction longjmp #include <signal.h> : gestion des signaux Lorsqu'un événement exceptionnel se produit, le système d'exploitation peut envoyer un signal aux processus (c'est généralement le cas en cas d'erreur grave). Grâce au chier d'en-tête signal.h, on peut gérer les signaux envoyés par le système d'exploitation grâce à deux fonctions raise et signal avec des constantes symboliques. Les prototypes de ces fonctions sont : int raise (int sig); void (*signal(int signum, void (*handler)(int)))(int); fonction signal : Lors de l'arrivée d'un signal correspondant au numéro signum, les événements se produisant dépendent de la valeur de handler (qui sont des constantes symboliques de la liste suivante) : SIG_DFT : comportement par défaut déni par l'implémentation ; SIG_IGN : ignorer le signal suivant ; 67 DIAO O. Cours de langage C

68 6.14 #include <stdarg.h> : nombre variable d'arguments SIGABRT : arrêt anormal du programme (utilisation de abort() par exemple) ; SIGFPE : erreur arithmétique (division par zéro, etc.) ; SIGINT : interruption par la touche Ctrl+C ; SIGILL : instruction illégale rencontrée dans le code machine ; SIGSEGV : erreur de segmentation : accès illégal de la mémoire ; SIGTERM : envoie d'une demande d'arrêt au programme. fonction raise : elle envoie le signal sig au programme lui-même ; en cas de réussite, elle retourne la valeur zéro #include <stdarg.h> : nombre variable d'arguments Une fonction peut être appelée avec un nombre variable d'arguments, eux-mêmes de types variables. Le langage C utilise la bibliothèque stdarg.h pour gérer le nombre variable d'argument d'une fonction. Pour cela, le chier stdarg.h déclare un type va_list et dénit trois macros (va_start, va_arg et va_end) permettant de manipuler la liste variable des arguments. Par exemple, soit une fonction fct ayant trois arguments obligatoires, disons a,b, c de types respectifs char,int,float suivi d'un nombre variable d'arguments. Alors, on le prototype de cette fonction est de la forme : int fct(char a, int b, float c,...); // on a supposé que fct retourne un type int Dans ce cas, pour pouvoir manipuler les arguments variables (leur nombre et leur type sont inconnus par fct), il faut obligatoirement utiliser la bibliothèque stdarg.h et utiliser va_list, va_start, va_arg et va_end dans le corps de la fonction fct. Le but de cette partie est de voir comment cela va marcher. Les prototypes de ces trois macros sont : void va_start (va_list ap, last); type va_arg (va_list ap, type); void va_end (va_list ap); va_start : cette macro initialise l'objet ap de type va_list pour les utilisations ultérieures de va_arg et va_end, et doit donc être appelée en premier. Son argument last est le nom (identicateur) du dernier paramètre avant la liste d'argument variable de la fonction appelée. Dans notre exemple avec la fonction fct, on a : last = c. va_arg : cette macro se développe en une expression qui a le type et la valeur de l'argument suivant de l'appel par la fonction : le premier appel à va_arg délivre le premier paramètre, puis chaque nouvel appel à va_arg modie ap et renvoie l'argument suivant. Cette macro admet deux arguments : la variable ap de type va_list et le type du paramètre courant. va_end : cette macro doit être appelée après l'utilisation de toutes les va_arg pour un retour normal de la fonction. 68 DIAO O. Cours de langage C

69 6.15 #include <stdbool.h> Exemple : Le programme suivant permet de calculer une sommation entrée en argument (alors on peut décider que le dernier argument est toujours zéro, sinon on peut spécier le nombre de variable de la fonction comme dans main (int argc, int *argv[]);) : #include <stdio.h> #include <stdarg.h> int sommation(int n,...){ va_list arg; int som,i; som = n; va_start(arg, n); while ( (i = va_arg(arg,int))!= 0 ) // 0 est une condition d'arrêt som = som + i; va_end(arg); return som; int main(){ int a,b,c,d; a = sommation(1,2,0); // 0 est un condition d'arrêt b = sommation(1,3,2,4,0); c = sommation(16,5,3,4,2,1,0); d = sommation(1,2,3,4,5,6,7,8,9,10,0); printf("valeur de a=%d,\t return 0; b=%d,\t c=%d et d=%d \n",a,b,c,d); 6.15 #include <stdbool.h> Cette bibliothèque, introduite en 99, déni la notion un type booléen nommé bool qui peut prendre les valeurs grue=1 ou false=0. Pour son utilisation, il faudra écrire simplement : #include <stdbool> // la déclaration d'une variable booléen se fait par : bool test = true; // ou bien "bool test = 1;" 6.16 #include <stddef.h> Cette bibliothèque, très utile quand on manipule des pointeurs, dénit les macros NULL et offsetof, puis les types ptrdiff_t, wchar_t et size_t : NULL équivaut au pointeur NULL qui ne pointe sur rien ; offsetof ayant pour prototype size_t offsetof(type, membre-designation);, permet de connaître le décalage (en nombre d'octets) entre un champ d'une structure (membre-designation) et le début de cette structure (type) ; ptrdiff_t indique la diérence entre deux pointeurs ; wchar_t est utilisé surtout pour les caractères étendus (wchar.h) ; size_t désigne la taille d'un objet en nombre d'octets. 69 DIAO O. Cours de langage C

70 6.17 #include <stdint.h> : version allégée de inttypes.h 6.17 #include <stdint.h> : version allégée de inttypes.h Cette bibliothèque est une version allégée de la bibliothèque inttypes.h, donc stdint.h contient des macros et variables plus rapides que inttypes.h. Donc stdint.h est généralement adaptée aux environnements embarqués qui peuvent ne pas supporter les fonctions d'entrées/sorties formatées #include <stdio.h> : entrée/sortie standard C'est la bibliothèque la plus importante du langage C, en fait stdio.h représente un tiers de la bibliothèque standard #include <stdlib.h> : fonctions utilitaires Cette librairie contient des déclarations de fonctions traitant la conversion, la génération de nombres pseudo-aléatoires, l'arithmétique sur les entiers, l'allocation de mémoire, le contrôle de processus et la recherche et le tri Conversion de nombres Grâce à stdlib.h, une chaîne de caractères peut être convertit en un nombre. Ceci se fait avec les fonctions atof,atoi et atol : Prototype double atof(char *chaîne); int atoi(char *chaîne); long atol(char *chaîne); Description convertit chaîne en un double convertit chaîne en un int convertit chaîne en un long int On dispose aussi des fonctions strtod, strtol, strtoul, strtoll et de strtoull qui permettent de convertir respectivement en un double, un long int, un unsigned long int, un long long et unsigned long long. Pour se rappeler, il sut de lire : strtod = stringtodouble, strtol = stringtolong, etc Génération de nombres pseudoaléatoires Le chier stdlib.h contient les fonctions rand, srand, random et srandom pour la génération de nombre pseudo-aléatoires. Les prototypes sont : int rand (void); void srand (unsigned int seed); long int random (void); void srandom (unsigned int seed); ˆ rand et random renvoient un entier pseudo-aléatoire entre 0 et RAND_MAX (qui vaut au moins ). La valeur fournit par rand et random dépend du germe du générateur qui vaut par défaut 1, mais on peut modier avec srand ou avec srandom. ˆ srand ou srandom utilisent son argument comme germe pour la génération d'une nouvelle séquence de nombres pseudo-aléatoires. 70 DIAO O. Cours de langage C

71 6.19 #include <stdlib.h> : fonctions utilitaires Arithmétique sur les entiers Le chier stdlib.h permet de faire de la division euclidienne sur les entiers avec les types div_t, ldiv_t et lldiv_t (qui sont des structure ayant deux champs quot pour quotient et rem pour reste) et des fonctions mathématiques : int abs(int n) : valeur absolue d'un entier ; long labs(long n) : valeur absolue d'un long int ; div_t div(int a, int b) : quotient et reste de la division euclidienne de a par b ; ldiv_t ldiv(long a, long b) : idem que div mais pour long int ; lldiv_t lldiv(long long a, long long b) : idem que div mais avec long long Allocation dynamique de la mémoire Nous avons déjà vu les fonctions calloc, malloc et free, il faut y ajouter la fonction realloc de la bibliothèque stdlib.h. Les prototypes et descriptions sont : Prototype void *calloc(size_t n, size_t size) void *malloc(size_t size) void *realloc(void *ptr, size_t size) void free(void *ptr) Description réserve n*size octets de mémoire et initialisation à zéro. réserve size octets de mémoire modie la taille d'une zone préalablement allouée par calloc ou malloc libère une zone mémoire Contrôle de processus La librairie stdlib.h permet de dialoguer avec le système grâce aux fonctions abort, atexit et exit : void abort (void); : terminaison anormale de l'exécution du programme en cours ; int atexit (void (*fonction)(void)); : enregistre la fonction donnée pour que celle-ci soit automatiquement invoquée lorsque le programme se termine normalement avec exit ou par un return de main (réussite = 0 et échec = 1) ; void exit (int st); : termine normalement le programme en cours et renvoie st au processus parent ; Gestion de l'environnement et des signaux Grâce à stdlib.h, on peut dialoguer avec les variables d'environnements (commence par $ sous Linux : faire $+TAB+TAB) et exécuter des commandes propre au système, ceci se fait à l'aide des fonctions getenv, putenv, setenv, unsetenv et mystes : char *getenv (const char *name); : recherche dans la liste des variables d'environnement une chaîne correspondant à celle pointée par name (retourne un pointeur sur la valeur correspondante) ; 71 DIAO O. Cours de langage C

72 6.19 #include <stdlib.h> : fonctions utilitaires int putenv (const char *string); : ajoute ou modie la valeur d'une variable d'environnement (retourne 0 en cas de réussite et 1 sinon) ; int setenv (const char *name, const char *value, int overwrite); : ajoute la variable name = value dans l'environnement si name n'existe pas encore. Si name existe déjà, alors sa valeur est modiée en value si overwrite est non nul ; si overwrite vaut zéro, la valeur de name n'est pas modiée ; void unsetenv (const char *name); eace la variable name de l'environnement ; int mystes (const char * string); : permet d'exécuter la commande indiquée dans string en appelant /bin/sh -c string Trier un tableau et rechercher un élément Avec la librairie stdlib.h, on peut trier un tableau grâce à qsort ou rechercher un élément dans un tableau grâce à bsearch) : void qsort(void *tab, size_t nbr, size_t size, int (*cmp)(const void*, const void*)); : trie dans l'ordre croissant un tableau tab[0],...,tab[nbr1] d'objets de taille size. Le trie utilise une fonction personnelle cmp qui doit renvoyer respectivement une valeur strictement négative, nulle ou strictement positive quand son premier argument est inférieur, égal ou supérieur à son deuxième argument. void *bsearch (const void *key, const void *tab, size_t nbr, size_t size, int (*compar)(const void*, const void*)); : recherche l'élément key dans le tableau trier tab[0],...,tab[nbr1] d'objets de taille size. Exemple : on créer deux fonctions mysearch et mysort permettant de rechercher et de trier un tableau d'entier, remarquer qu'on trie le tableau avant de rechercher un élément. #include <stdio.h> #include <stdlib.h> int cmp (const void * a, const void * b){ return ( *(int*)a - *(int*)b ); void mysearch (int key, int *tb) { int * pitem; qsort(tb, 6, sizeof(int), cmp); // on trie le tableau avant de chercher pitem = (int*) bsearch(&key, tb, 6, sizeof (int), cmp); if (pitem!= NULL) printf ("%d est dans le tableau.\n",*pitem); else printf ("%d n'est pas dans le tableau.\n",key); void mysort (int *tb) { int n; qsort(tb, 6, sizeof(int), cmp); for (n=0; n<6; n++) printf ("%d ",tb[n]); printf("\n"); int main(){ int tab[] = { 40, 80, 100, 70, 20, 25 ; 72 DIAO O. Cours de langage C

73 6.20 #include <string.h> : chaînes de caractères (strings) int k = 40; mysearch(k,tab); mysort(tab); return 0; 6.20 #include <string.h> : chaînes de caractères (strings) La librairie string.h fournit un ensemble de constantes symboliques, de macros, de types et de fonctions permettant de manipuler aisément les chaînes de caractères Constantes et types Dans string.h, nous avons la constante NULL pour le pointeur null et le type size_t qui représentation la valeur de retour de sizeof Fonctions de string.h Selon leur action sur les chaînes de caractères, ces fonctions se divisent en plusieurs groupes qui commencent généralement par mem ou str. Les fonctions mem... agissent sur des blocs d'octets qui ne se terminent pas nécessairement par le caractère NULL, contrairement aux fonctions str... qui ne fonctionnent que sur les chaînes de caractères. ˆ Copier : il s'agit des fonctions strcpy, strncpy, memcpy et memmove qui permettent de manipuler des strings (concaténer, copier et transformer) void *memcpy (void *dest, const void *src, size_t n); : copie n octets depuis la zone mémoire src vers la zone mémoire dest et retourne dest (les zones ne doivent pas se chevaucher) ; void *memmove (void *dest, const void *src, size_t n); : identique à memcpy, mais les zones peuvent se chevaucher ; char *strcpy (char *dest, const char *src); : copie la chaîne src (y compris le \0 nal) dans la chaîne dest et retourne dest ; char *strncpy (char *dest, const char *src, size_t n); : est identique à strcpy, mais seulement les n caractères sont copiés ; ˆ Concaténer : ce sont les fonctions strcat et strncat char *strcat(char *dest, const char *src); : concaténe la chaîne src à la suite de la chaîne dest et retourne la chaîne dest ; char *strncat (char *dest, const char *src, size_t n); : est identique à strcat, mais seulement les n caractères sont concaténés ; ˆ Comparer : il s'agit des fonctions memcmp, strcmp et strncmp int memcmp (const void *ch1, const void *ch2, size_t n); : compare lexicographiquement les n premiers octets des zones mémoire ch1 et ch2 ; int strcmp(const char *ch1, const char *ch2); : compare lexicographiquement les deux chaînes ch1 et ch2 ; int strncmp(const char *ch1, const char *ch2, size_t n); comme strcmp, mais ne compare que les n premiers caractères de ch1 ; 73 DIAO O. Cours de langage C

74 6.21 #include <tgmath.h> : fonctions mathématiques génériques ˆ Rechercher : Pour chercher un caractère ou une chaîne de caractères, on utilise généralement les fonctions : memchr, strchr, strrchr, strpbrk, strspn, strcspn, strstr et strtok void *memchr (const void *ch, int c, size_t n); rechercher le caractère c dans zone mémoire pointée par ch et retourne un pointeur sur la première occurrence de c ou bien NULL. char *strchr(const char *ch, int c); : recherche le caractère c dans la chaîne ch et renvoie un pointeur sur la première occurrence du caractère ou bien NULL. char *strrchr(const char *ch, int c); identique à strchr, mais retourne un pointeur sur la dernière occurrence du caractère ou bien NULL ; char *strpbrk(const char *ch1, const char *ch2); recherche la première occurrence dans la chaîne ch1 de l'un quelconque des caractères de la chaîne ch2 ; size_t strspn(const char *ch1, const char *ch2); : calcule la longueur du segment initial de ch1 qui ne contient que des caractères présents dans ch2 ; size_t strcspn(const char *ch1, const char *ch2); : calcule la longueur du segment initial de ch1 qui ne contient que des caractères absents de ch2 ; char *strstr(const char *ch1, const char *ch2); cherche la première occurrence de la sous-chaîne ch2 au sein de la chaîne ch1 et renvoie un pointeur sur le début de la sous-chaîne ch2 ou bien NULL ; char *strtok(char *ch1, const char *ch2); : recherche dans ch1 des lexèmes (élément lexical) délimité par des caractères appartenant à ch2. Une série d'appel à strtok décompose ch1 en sous-chaînes séparées par un caractère de ch2 ; ˆ Mesurer et transformer des strings : pour mesurer, on utilise strlen et pour transformer, on utilise memset et strxfrm : size_t strlen(const char *ch); : calcule la longueur de ch sans le \0 ; size_t strxfrm (char *dest, const char *src, size_t n); : transforme les n premiers caractères de src dans dest, de façon à ce que le tri lexicographique de la chaîne transformée soit équivalent au tri lexicographique de src. ˆ Remplir et gérer les messages d'erreurs Pour remplit plusieurs caractères d'une chaîne on utilise la fonction memset et pour gérer les messages d'erreurs on utilise strerror void *memset (void *ch, int c, size_t n); : remplit les n premiers octets de la zone de mémoire pointée par ch avec l'octet c et renvoie un pointeur sur la chaîne transformée ch. char * strerror(int code); : renvoie une chaîne (messages) décrivant le code d'erreur fourni dans l'argument code. Cette fonction permet de connaître la signi- cation textuelle d'une valeur de errno #include <tgmath.h> : fonctions mathématiques génériques Cette librairie contient les librairies math.h et complex.h. Donc la librairie tgmath.h contient des macros génériques qui sont utilisables indiéremment avec les fonctions de math.h et les fonctions de complex.h. Par exemple, fabs de tgmath.h remplace indiéremment fabs de math.h et cabs de complex.h. 74 DIAO O. Cours de langage C

75 6.22 #include <time.h> : date et heure 6.22 #include <time.h> : date et heure Cette bibliothèque contient les déclarations de types et les fonctions servant à manipuler la date et l'heure. Dans cette bibliothèque, le temps est représenté par trois objets : un type time_t, un type clock_t et une structure struct tm. Les types time_t et clock_t sont généralement des entiers (int ou long int). Tandis que la structure struct tm est une représentation de l'heure locale (ou la date locale) en année, mois, jour, heure, minute et seconde, elle s'écrit donc : struct tm { int tm_sec; // secondes après la minute (0-59) int tm_min; // minutes après l'heure (0-59) int tm_hour; // heures depuis minuit (0-23) int tm_mday; // jour du mois (1-31) int tm_mon; // mois depuis janvier (0-11) int tm_year; // année depuis 1900 int tm_wday; // jours depuis dimanche (0-6) int tm_yday; // jours depuis le 1ier janvier (0-365) int tm_isdst; // drapeau pour l'heure d'été ; Fonctions de manipulation du temps Il s'agit généralement de clock, difftime, mktime et de time. Leurs prototypes : clock_t clock(void); : retourne la durée d'utilisation du processeur par le programme depuis son exécution ou bien 1 en cas d'erreur ; time_t time(time_t *tp); : retourne dans tp (si tp n'est pas NULL) l'heure actuelle sous forme du nombre de secondes écoulées depuis le 1er Janvier 1970 à 00h 00m 00s GMT ; double difftime(time_t t2, time_t t1); : retourne t2-t1, c-a-d le nombre de secondes écoulées entre t2 et t1 ; time_t mktime(struct tm *tp); : convertit l'heure locale *tp exprimée sous forme struct tm en une heure calendaire sous forme time_t Fonctions de conversion de date Avec la bibliothèque time.h, on peut convertir de heures calendaires en heure locale ou bien en format plus compréhensible : char *asctime (const struct tm *tp); : convertit l'heure locale tp exprimée sous forme struct tm en une chaîne de caractères de la forme : Thu Oct 20 15:30: \n\0 ; char *ctime (const time_t *tp); : convertit l'heure calendaire tp en une chaîne de caractères de la même forme que celle de asctime ctime(tp) équivaut à asctime(localtime(tp)) ; struct tm *gmtime (const time_t *tp); : convertit l'heure calendaire tp en heure locale représentée par la structure struct tm exprimée en temps universel ; struct tm *localtime (const time_t *tp); : convertit l'heure calendaire tp en heure locale représentée par la structure struct tm exprimée en fonction du fuseau horaire de l'utilisateur. 75 DIAO O. Cours de langage C

76 6.23 #include <wchar.h> et #include <wctype.h> : manipulation de caractères étendus size_t strftime(char *s, size_t n, const char *ft, const struct tm *tp); formate les divers champs de la structure tp en fonction du format spécié avec ft (comme avec printf), puis place le résultat dans la chaîne s de taille n. Les formats autorisés dans ft sont : Fmt Description Fmt Description %a abréviation du jour %A nom complet du jour %b abréviation du mois %B nom complet du mois %c date et heure locales %d jour du mois (01 31) %H heure, sur 24 heures (00 23) %I heure, sur 12 heures, (01 12). %j jour dans l'année ( ) %m numéro du mois (01 12) %M minute (00 59) %p AM ou PM %S seconde (00 59) %u jour de la semaine (1 7) %U,%W numéro de la semaine (00-53) %w numéro du jour (0-6) %x représentation locale de la date %X représentation locale de l'heure %y année dans le siècle (00 99) %Y année (sous la forme 2011) %z fuseau horaire %Z nom du fuseau horaire #include <wchar.h> et #include <wctype.h> : manipulation de caractères étendus Ces deux bibliothèques contiennent des fonctions et des déclarations de type étendus. Comme le développement du langage C s'est fait en considérant que le plus petit type est le char codé 8 bits, alors pour avoir des programmes portables, nous avons besoin d'un autre type de donné. Par exemple, nous aurons besoin des caractères codant les caractères chinois, japonais, arabe, etc. pour pouvoir exporté un programme. 76 DIAO O. Cours de langage C

77 Références Références [1] Canteaut Anne. Programmation en langage C. Université de Limoges, [2] Cassagne Bernard. Introduction au Langage C, Norme ISO/ANSI. Université Joseph Fourier de Grenoble, [3] Kernighan Brian W. and Ritchie Dennis M.. The C programming language, seconde edition. Englewood Clis, Prentice Hall,, [4] Mettier Yves C en Action, 2ième édition. Editions ENI - Livre d'informatique en français, [5] Varrette Sébastien and Bernard Nicolas. Cours de programmation avancée, Le Langage C. Université de Luxemburg, DIAO O. Cours de langage C

Programmation en langage C

Programmation en langage C Programmation en langage C Anne CANTEAUT INRIA - projet CODES B.P. 105 78153 Le Chesnay Cedex [email protected] http://www-rocq.inria.fr/codes/anne.canteaut/cours C 2 Table des matières 3 Table des

Plus en détail

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

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3. 1. Structure d un programme C Un programme est un ensemble de fonctions. La fonction "main" constitue le point d entrée pour l exécution. Un exemple simple : #include int main() { printf ( this

Plus en détail

Licence ST Université Claude Bernard Lyon I LIF1 : Algorithmique et Programmation C Bases du langage C 1 Conclusion de la dernière fois Introduction de l algorithmique générale pour permettre de traiter

Plus en détail

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

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation impérative et structures de données simples Introduction au langage C Sandrine Blazy - 1ère année 24 octobre 2007 Cours d Algorithmique-Programmation

Plus en détail

Algorithmique et Programmation, IMA

Algorithmique et Programmation, IMA Algorithmique et Programmation, IMA Cours 2 : C Premier Niveau / Algorithmique Université Lille 1 - Polytech Lille Notations, identificateurs Variables et Types de base Expressions Constantes Instructions

Plus en détail

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP COURS PROGRAMMATION INITIATION AU LANGAGE C SUR MICROCONTROLEUR PIC page 1 / 7 INITIATION AU LANGAGE C SUR PIC DE MICROSHIP I. Historique du langage C 1972 : naissance du C dans les laboratoires BELL par

Plus en détail

Introduction au langage C

Introduction au langage C Introduction au langage C Cours 1: Opérations de base et premier programme Alexis Lechervy Alexis Lechervy (UNICAEN) Introduction au langage C 1 / 23 Les premiers pas Sommaire 1 Les premiers pas 2 Les

Plus en détail

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux. UEO11 COURS/TD 1 Contenu du semestre Cours et TDs sont intégrés L objectif de ce cours équivalent a 6h de cours, 10h de TD et 8h de TP est le suivant : - initiation à l algorithmique - notions de bases

Plus en détail

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

Cours de programmation avancée. Le langage C. Université du Luxembourg 2005 2006 Université du Luxembourg 2005 2006 Cours de programmation avancée. Le langage C Sébastien Varrette Version : 0.4 Nicolas Bernard 2 Table des matières

Plus en détail

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

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java Info0101 Intro. à l'algorithmique et à la programmation Cours 3 Le langage Java Pierre Delisle, Cyril Rabat et Christophe Jaillet Université de Reims Champagne-Ardenne Département de Mathématiques et Informatique

Plus en détail

SUPPORT DE COURS. Langage C

SUPPORT DE COURS. Langage C Dpt Informatique 2010-2011 SUPPORT DE COURS Langage C Semestre 1 par : «CaDePe» Marie-Françoise Canut Marianne de Michiel André Péninou Table des Matières 1 Généralités...8 1.1 Introduction aux langages

Plus en détail

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles [email protected]

Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles florence.henry@obspm.fr Le Langage C Version 1.2 c 2002 Florence HENRY Observatoire de Paris Université de Versailles [email protected] Table des matières 1 Les bases 3 2 Variables et constantes 5 3 Quelques fonctions indispensables

Plus en détail

Recherche dans un tableau

Recherche dans un tableau Chapitre 3 Recherche dans un tableau 3.1 Introduction 3.1.1 Tranche On appelle tranche de tableau, la donnée d'un tableau t et de deux indices a et b. On note cette tranche t.(a..b). Exemple 3.1 : 3 6

Plus en détail

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

Bases de programmation. Cours 5. Structurer les données Bases de programmation. Cours 5. Structurer les données Pierre Boudes 1 er décembre 2014 This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. Types char et

Plus en détail

Programmation système I Les entrées/sorties

Programmation système I Les entrées/sorties Programmation système I Les entrées/sorties DUT 1 re année Université de Marne La vallée Les entrées-sorties : E/O Entrées/Sorties : Opérations d échanges d informations dans un système informatique. Les

Plus en détail

Les chaînes de caractères

Les chaînes de caractères Les chaînes de caractères Dans un programme informatique, les chaînes de caractères servent à stocker les informations non numériques comme par exemple une liste de nom de personne ou des adresses. Il

Plus en détail

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

IN 102 - Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C IN 102 - Cours 1 Qu on le veuille ou non, les systèmes informatisés sont désormais omniprésents. Même si ne vous destinez pas à l informatique, vous avez de très grandes chances d y être confrontés en

Plus en détail

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile Dans ce TP, vous apprendrez à définir le type abstrait Pile, à le programmer en Java à l aide d une interface

Plus en détail

Programmation Structurée en Langage C

Programmation Structurée en Langage C École Centrale Marseille Programmation Structurée en Langage C Stéphane Derrode Mathématique et Informatique Révision 2.5, 2006. Table des matières 1 En guise d'introduction... 7 1.1 Quelques repères

Plus en détail

Initiation à la programmation en Python

Initiation à la programmation en Python I-Conventions Initiation à la programmation en Python Nom : Prénom : Une commande Python sera écrite en caractère gras. Exemples : print 'Bonjour' max=input("nombre maximum autorisé :") Le résultat de

Plus en détail

I. Introduction aux fonctions : les fonctions standards

I. Introduction aux fonctions : les fonctions standards Chapitre 3 : Les fonctions en C++ I. Introduction aux fonctions : les fonctions standards A. Notion de Fonction Imaginons que dans un programme, vous ayez besoin de calculer une racine carrée. Rappelons

Plus en détail

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

Cours d initiation à la programmation en C++ Johann Cuenin Cours d initiation à la programmation en C++ Johann Cuenin 11 octobre 2014 2 Table des matières 1 Introduction 5 2 Bases de la programmation en C++ 7 3 Les types composés 9 3.1 Les tableaux.............................

Plus en détail

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

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme Rappel Ralf Treinen Université Paris Diderot UFR Informatique Laboratoire Preuves, Programmes et Systèmes [email protected] 6 mai 2015 Jusqu'à maintenant : un petit langage de programmation

Plus en détail

Langage C. Patrick Corde. [email protected]. 22 juin 2015. Patrick Corde ( [email protected] ) Langage C 22 juin 2015 1 / 289

Langage C. Patrick Corde. Patrick.Corde@idris.fr. 22 juin 2015. Patrick Corde ( Patrick.Corde@idris.fr ) Langage C 22 juin 2015 1 / 289 Langage C Patrick Corde [email protected] 22 juin 2015 Patrick Corde ( [email protected] ) Langage C 22 juin 2015 1 / 289 Table des matières I 1 Présentation du langage C Historique Intérêts

Plus en détail

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère L'héritage et le polymorphisme en Java Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère En java, toutes les classes sont dérivée de la

Plus en détail

Cours Langage C/C++ Programmation modulaire

Cours Langage C/C++ Programmation modulaire Cours Langage C/C++ Programmation modulaire Thierry Vaira BTS IRIS Avignon [email protected] «v0.1 Rappel Programmation modulaire (1/2) Le découpage d'un programme en sous-programmes est appelée programmation

Plus en détail

INF 321 : mémento de la syntaxe de Java

INF 321 : mémento de la syntaxe de Java INF 321 : mémento de la syntaxe de Java Table des matières 1 La structure générale d un programme 3 2 Les composants élémentaires de Java 3 2.1 Les identificateurs.................................. 3 2.2

Plus en détail

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

UE C avancé cours 1: introduction et révisions Introduction Types Structures de contrôle Exemple UE C avancé cours 1: introduction et révisions Jean-Lou Desbarbieux et Stéphane Doncieux UMPC 2004/2005 Introduction Types Structures de contrôle Exemple

Plus en détail

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

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation : Algorithmique et programmation : STRUCTURES DE DONNÉES A. Structure et enregistrement 1) Définition et rôle des structures de données en programmation 1.1) Définition : En informatique, une structure de

Plus en détail

Conception de circuits numériques et architecture des ordinateurs

Conception de circuits numériques et architecture des ordinateurs Conception de circuits numériques et architecture des ordinateurs Frédéric Pétrot Année universitaire 2014-2015 Structure du cours C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 Codage des nombres en base 2, logique

Plus en détail

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

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu. Seance 2: Complétion du code de jeu. (durée max: 2h) Mot clé const et pointeurs: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu. Implémentez jeu_recupere_piece

Plus en détail

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

Anis ASSÈS Mejdi BLAGHGI Mohamed Hédi ElHajjej Mohamed Salah Karouia Ministère de l Enseignement Supérieur, de la Recherche Scientifique et de la Technologie Direction Générale des Etudes Technologiques Institut Supérieur des Etudes Technologiques de Djerba SUPPORT DE COURS

Plus en détail

Claude Delannoy. 3 e édition C++

Claude Delannoy. 3 e édition C++ Claude Delannoy 3 e édition Exercices Exercices C++ en en langage langage delc++ titre 4/07/07 15:19 Page 2 Exercices en langage C++ AUX EDITIONS EYROLLES Du même auteur C. Delannoy. Apprendre le C++.

Plus en détail

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

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles) 1/4 Objectif de ce cours /4 Objectifs de ce cours Introduction au langage C - Cours Girardot/Roelens Septembre 013 Du problème au programme I passer d un problème exprimé en français à la réalisation d

Plus en détail

Dans le chapitre 1, nous associions aux fichiers ouverts des descripteurs de fichiers par lesquels nous accédions aux fichiers.

Dans le chapitre 1, nous associions aux fichiers ouverts des descripteurs de fichiers par lesquels nous accédions aux fichiers. I Présentation : Dans le chapitre 1, nous avons vu comment utiliser les appels-systèmes de bas niveau pour créer et accéder à des fichiers sur le disque. Nous avons notamment mis en évidence leur dépouillement

Plus en détail

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

UE Programmation Impérative Licence 2ème Année 2014 2015 UE Programmation Impérative Licence 2 ème Année 2014 2015 Informations pratiques Équipe Pédagogique Florence Cloppet Neilze Dorta Nicolas Loménie [email protected] 2 Programmation Impérative

Plus en détail

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51 DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51 PLAN DU COURS Introduction au langage C Notions de compilation Variables, types, constantes, tableaux, opérateurs Entrées sorties de base Structures de

Plus en détail

INITIATION A LA PROGRAMMATION

INITIATION A LA PROGRAMMATION 2004-2005 Université Paris Dauphine IUP Génie Mathématique et Informatique INITIATION A LA PROGRAMMATION PROCEDURALE, A L'ALGORITHMIQUE ET AUX STRUCTURES DE DONNEES PAR LE LANGAGE C Maude Manouvrier La

Plus en détail

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

Programmation C++ (débutant)/instructions for, while et do...while Programmation C++ (débutant)/instructions for, while et do...while 1 Programmation C++ (débutant)/instructions for, while et do...while Le cours du chapitre 4 : le for, while et do...while La notion de

Plus en détail

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

Algorithmes et Programmes. Introduction à l informatiquel. Cycle de vie d'un programme (d'un logiciel) Cycle de vie d'un programme (d'un logiciel) Algorithmes et Programmes Introduction à l informatiquel! Vie d'un programme! Algorithme! Programmation : le langage! Exécution et test des programmes Chapitre : Algorithmes et Programmes 2 Cycle de vie

Plus en détail

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

INTRODUCTION A JAVA. Fichier en langage machine Exécutable INTRODUCTION A JAVA JAVA est un langage orienté-objet pur. Il ressemble beaucoup à C++ au niveau de la syntaxe. En revanche, ces deux langages sont très différents dans leur structure (organisation du

Plus en détail

V- Manipulations de nombres en binaire

V- Manipulations de nombres en binaire 1 V- Manipulations de nombres en binaire L ordinateur est constitué de milliards de transistors qui travaillent comme des interrupteurs électriques, soit ouverts soit fermés. Soit la ligne est activée,

Plus en détail

Introduction au Langage de Programmation C

Introduction au Langage de Programmation C Faculté Polytechnique de Mons Service d'informatique Introduction au Langage de Programmation C Mohammed Benjelloun 1 ère Candidature Année académique 2003-2004 Avant-propos Ces notes permettent de se

Plus en détail

Rappels Entrées -Sorties

Rappels Entrées -Sorties Fonctions printf et scanf Syntaxe: écriture, organisation Comportement Données hétérogènes? Gestion des erreurs des utilisateurs 17/11/2013 Cours du Langage C [email protected] ibrahimguelzim.atspace.co.uk

Plus en détail

Langage Éric Guérin 5 octobre 2010

Langage Éric Guérin 5 octobre 2010 Langage Éric Guérin 5 octobre 2010 Langage C TABLE DES MATIÈRES Table des matières 1 Introduction 7 1.1 Historique........................................... 7 1.2 Architecture matérielle....................................

Plus en détail

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

Algorithmique & Langage C IUT GEII S1. Notes de cours (première partie) cours_algo_lgc1.17.odp. Licence Licence Algorithmique & Langage C Paternité - Pas d'utilisation Commerciale Partage des Conditions Initiales à l'identique 2.0 France Vous êtes libres : * de reproduire, distribuer et communiquer cette

Plus en détail

Chapitre 1 : La gestion dynamique de la mémoire

Chapitre 1 : La gestion dynamique de la mémoire Chapitre 1 : La gestion dynamique de la mémoire En langage C un programme comporte trois types de données : Statiques; Automatiques ; Dynamiques. Les données statiques occupent un emplacement parfaitement

Plus en détail

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

Travaux pratiques. Compression en codage de Huffman. 1.3. Organisation d un projet de programmation Université de Savoie Module ETRS711 Travaux pratiques Compression en codage de Huffman 1. Organisation du projet 1.1. Objectifs Le but de ce projet est d'écrire un programme permettant de compresser des

Plus en détail

Programmation en langage C Eléments de syntaxe

Programmation en langage C Eléments de syntaxe Programmation en langage C Eléments de syntaxe Université Paul Sabatier IUP Systèmes Intelligents L2 Module Informatique de base 2 Initiation à la programmation en langage C Isabelle Ferrané SOMMAIRE I-

Plus en détail

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

Programmation C. J.-F. Lalande. 15 novembre 2012 Programmation C J.-F. Lalande novembre 0 Ce cours est mis à disposition par Jean-François Lalande selon les termes de la licence Creative Commons Attribution - Pas d Utilisation Commerciale - Partage à

Plus en détail

BTS IRIS Cours et Travaux Pratiques. Programmation C. A. Lebret, TSIRIS, Lycée Diderot, 1995/06. en conformité avec le référentiel du BTS IRIS

BTS IRIS Cours et Travaux Pratiques. Programmation C. A. Lebret, TSIRIS, Lycée Diderot, 1995/06. en conformité avec le référentiel du BTS IRIS BTS IRIS Cours et Travaux Pratiques Programmation C A. Lebret, TSIRIS, Lycée Diderot, 1995/06 en conformité avec le référentiel du BTS IRIS Activité Codage et Réalisation Tâches T3.3, T3.4 et T3.5 Temps

Plus en détail

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

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java Langages objets Introduction M2 Pro CCI, Informatique Emmanuel Waller, LRI, Orsay présentation du module logistique 12 blocs de 4h + 1 bloc 2h = 50h 1h15 cours, 45mn exercices table, 2h TD machine page

Plus en détail

Cours d Algorithmique et de Langage C 2005 - v 3.0

Cours d Algorithmique et de Langage C 2005 - v 3.0 Cours d Algorithmique et de Langage C 2005 - v 3.0 Bob CORDEAU [email protected] Mesures Physiques IUT d Orsay 15 mai 2006 Avant-propos Avant-propos Ce cours en libre accès repose sur trois partis pris

Plus en détail

STAGE IREM 0- Premiers pas en Python

STAGE IREM 0- Premiers pas en Python Université de Bordeaux 16-18 Février 2014/2015 STAGE IREM 0- Premiers pas en Python IREM de Bordeaux Affectation et expressions Le langage python permet tout d abord de faire des calculs. On peut évaluer

Plus en détail

Programmation Classique en langage C

Programmation Classique en langage C DI GALLO Frédéric Programmation Classique en langage C Cours du Cycle d Approfondissement CNAM ANGOULEME 2000-2001 DI GALLO Frédéric Page 1 01/04/01 PROGRAMMATION CLASSIQUE : LANGAGE C DI GALLO Frédéric

Plus en détail

length : A N add : Z Z Z (n 1, n 2 ) n 1 + n 2

length : A N add : Z Z Z (n 1, n 2 ) n 1 + n 2 1 Univ. Lille1 - Licence info 3ème année 2013-2014 Expression Logique et Fonctionnelle... Évidemment Cours n o 1 : Introduction à la programmation fonctionnelle 1 Introduction La programmation fonctionnelle

Plus en détail

Chap III : Les tableaux

Chap III : Les tableaux Chap III : Les tableaux Dans cette partie, on va étudier quelques structures de données de base tels que : Les tableaux (vecteur et matrice) Les chaînes de caractères LA STRUCTURE DE TABLEAU Introduction

Plus en détail

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

Programmation en C. École Nationale Supérieure de Techniques Avancées. Pierre-Alain Fouque et David Pointcheval École Nationale Supérieure de Techniques Avancées Programmation en C Pierre-Alain Fouque et David Pointcheval E-mail : [email protected] Web : http://www.di.ens.fr/~fouque/ Table des matières

Plus en détail

Le Langage C Licence Professionnelle Qualité Logiciel Pr. Mouad BEN MAMOUN [email protected] Année universitaire 2011/2012

Le Langage C Licence Professionnelle Qualité Logiciel Pr. Mouad BEN MAMOUN ben_mamoun@fsr.ac.ma Année universitaire 2011/2012 Le Langage C Licence Professionnelle Qualité Logiciel Pr. Mouad BEN MAMOUN [email protected] Année universitaire 2011/2012 2011/2012 Pr. Ben Mamoun 1 Plan du cours (1) 1. Introduction 2. Types, opérateurs

Plus en détail

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions Cours d introduction à l informatique Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions Qu est-ce qu un Une recette de cuisine algorithme? Protocole expérimental

Plus en détail

Compte-rendu de projet de Système de gestion de base de données

Compte-rendu de projet de Système de gestion de base de données Compte-rendu de projet de Système de gestion de base de données Création et utilisation d'un index de jointure LAMBERT VELLER Sylvain M1 STIC Université de Bourgogne 2010-2011 Reponsable : Mr Thierry Grison

Plus en détail

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

Méthodes de programmation systèmes UE n NSY103. Notes de cours. Nombre d'heures : 55h (~18 + 1 cours de 3 heures) Méthodes de programmation systèmes UE n NSY103 Notes de cours Code de l UE : NSY103 Titre de la formation : Méthodes de programmation systèmes Ouvert : Ouvert Type de diplôme : Unité de valeur CNAM. Nombre

Plus en détail

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

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année 2003-2004 Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES Maude Manouvrier La reproduction de ce document par

Plus en détail

Cours Informatique Master STEP

Cours Informatique Master STEP Cours Informatique Master STEP Bases de la programmation: Compilateurs/logiciels Algorithmique et structure d'un programme Programmation en langage structuré (Fortran 90) Variables, expressions, instructions

Plus en détail

Algorithmique et programmation : les bases (VBA) Corrigé

Algorithmique et programmation : les bases (VBA) Corrigé PAD INPT ALGORITHMIQUE ET PROGRAMMATION 1 Cours VBA, Semaine 1 mai juin 2006 Corrigé Résumé Ce document décrit l écriture dans le langage VBA des éléments vus en algorithmique. Table des matières 1 Pourquoi

Plus en détail

TP 1 : 1 Calculs en binaire, octal et hexadécimal

TP 1 : 1 Calculs en binaire, octal et hexadécimal Univ. Lille 1 - Licence Informatique 2ème année 2013-14 Objectifs du TP Ce TP a pour but Codage de l'information TP 1 : 1. de découvrir quelques opérations logiques sur les nombres 2. et quelques formats

Plus en détail

Les structures. Chapitre 3

Les structures. Chapitre 3 Chapitre 3 Les structures Nous continuons notre étude des structures de données qui sont prédéfinies dans la plupart des langages informatiques. La structure de tableau permet de regrouper un certain nombre

Plus en détail

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

MICROINFORMATIQUE NOTE D APPLICATION 1 (REV. 2011) ARITHMETIQUE EN ASSEMBLEUR ET EN C Haute Ecole d Ingénierie et de Gestion Du Canton du Vaud MICROINFORMATIQUE NOTE D APPLICATION 1 (REV. 2011) ARITHMETIQUE EN ASSEMBLEUR ET EN C Programmation en mode simulation 1. DOCUMENTS DE RÉFÉRENCE...

Plus en détail

Programmation impérative

Programmation impérative Programmation impérative Cours 4 : Manipulation des fichiers en C Catalin Dima Organisation des fichiers Qqs caractéristiques des fichiers : Nom (+ extension). Chemin d accès absolu = suite des noms des

Plus en détail

Les fichiers. Chapitre 4

Les fichiers. Chapitre 4 Chapitre 4 Les fichiers Jusqu à maintenant tous les programmes que nous avons conçus travaillaient sur des données qui étaient perdues après chaque session de travail. On peut cependant, c est bien naturel,

Plus en détail

COMPARAISONDESLANGAGESC, C++, JAVA ET

COMPARAISONDESLANGAGESC, C++, JAVA ET REPUBLIQUE DU BENIN *******@******* MINISTERE DE L ENSEIGNEMENT SUPERIEUR ET DE LA RECHERCHE SCIENTIFIQUE(MESRS) *******@******* UNIVERSITE D ABOMEY CALAVI(UAC) *******@******* ECOLE POLYTECHNIQUE D ABPOMEY

Plus en détail

LES TYPES DE DONNÉES DU LANGAGE PASCAL

LES TYPES DE DONNÉES DU LANGAGE PASCAL LES TYPES DE DONNÉES DU LANGAGE PASCAL 75 LES TYPES DE DONNÉES DU LANGAGE PASCAL CHAPITRE 4 OBJECTIFS PRÉSENTER LES NOTIONS D ÉTIQUETTE, DE CONS- TANTE ET DE IABLE DANS LE CONTEXTE DU LAN- GAGE PASCAL.

Plus en détail

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

Initiation. àl algorithmique et à la programmation. en C Initiation àl algorithmique et à la programmation en C Initiation àl algorithmique et à la programmation en C Cours avec 129 exercices corrigés Illustration de couverture : alwyncooper - istock.com Dunod,

Plus en détail

Programmer en JAVA. par Tama ([email protected]( [email protected])

Programmer en JAVA. par Tama (tama@via.ecp.fr( tama@via.ecp.fr) Programmer en JAVA par Tama ([email protected]( [email protected]) Plan 1. Présentation de Java 2. Les bases du langage 3. Concepts avancés 4. Documentation 5. Index des mots-clés 6. Les erreurs fréquentes

Plus en détail

Le langage C. Introduction, guide de reference

Le langage C. Introduction, guide de reference Le langage C Introduction, guide de reference Ce document est une présentation du langage de programmation C, de sa syntaxe et de ses spécificités. Il est destiné essentiellement à servir de mémo-guide

Plus en détail

Chapitre 2 Devine mon nombre!

Chapitre 2 Devine mon nombre! Python 3 : objectif jeux Chapitre 2 Chapitre 2 Devine mon nombre! 2.1. Thèmes abordés dans ce chapitre commentaires modules externes, import variables boucle while condition : if... elif... else la fonction

Plus en détail

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

Notes du cours 4M056 Programmation en C et C++ Vincent Lemaire et Damien Simon Notes du cours 4M056 Programmation en C et C++ Vincent Lemaire et Damien Simon 13 janvier 2015 2 Table des matières Organisation générale du cours 7 1 Notions générales d algorithmique et de programmation

Plus en détail

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

INF111. Initiation à la programmation impérative en C http://ama.liglab.fr/ amini/cours/l1/inf111/ Massih-Reza Amini Initiation à la programmation impérative en C http://ama.liglab.fr/ amini/cours/l1// Massih-Reza Amini Université Joseph Fourier Laboratoire d Informatique de Grenoble 2/52 Introduction Structures de contrôle

Plus en détail

ALGORITHMIQUE ET PROGRAMMATION En C

ALGORITHMIQUE ET PROGRAMMATION En C Objectifs ALGORITHMIQUE ET PROGRAMMATION Une façon de raisonner Automatiser la résolution de problèmes Maîtriser les concepts de l algorithmique Pas faire des spécialistes d un langage Pierre TELLIER 2

Plus en détail

Conventions d écriture et outils de mise au point

Conventions d écriture et outils de mise au point Logiciel de base Première année par alternance Responsable : Christophe Rippert [email protected] Introduction Conventions d écriture et outils de mise au point On va utiliser dans cette

Plus en détail

Introduction à MATLAB R

Introduction à MATLAB R Introduction à MATLAB R Romain Tavenard 10 septembre 2009 MATLAB R est un environnement de calcul numérique propriétaire orienté vers le calcul matriciel. Il se compose d un langage de programmation, d

Plus en détail

Chapitre 2. Classes et objets

Chapitre 2. Classes et objets Chapitre 2: Classes et Objets 1/10 Chapitre 2 Classes et objets Chapitre 2: Classes et Objets 2/10 Approche Orientée Objet Idée de base de A.O.O. repose sur l'observation de la façon dont nous procédons

Plus en détail

Notions fondamentales du langage C# Version 1.0

Notions fondamentales du langage C# Version 1.0 Notions fondamentales du langage C# Version 1.0 Z 2 [Notions fondamentales du langage Csharp] [Date : 25/03/09] Sommaire 1 Tout ce qu il faut savoir pour bien commencer... 3 1.1 Qu est ce qu un langage

Plus en détail

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski [email protected]

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski cegielski@u-pec.fr Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski [email protected] Mars 2002 Pour Irène et Marie Legal Notice Copyright c 2002 Patrick Cégielski Université

Plus en détail

Algorithme. Table des matières

Algorithme. Table des matières 1 Algorithme Table des matières 1 Codage 2 1.1 Système binaire.............................. 2 1.2 La numérotation de position en base décimale............ 2 1.3 La numérotation de position en base binaire..............

Plus en détail

Le langage C. Séance n 4

Le langage C. Séance n 4 Université Paris-Sud 11 Institut de Formation des Ingénieurs Remise à niveau INFORMATIQUE Année 2007-2008 Travaux pratiques d informatique Le langage C Séance n 4 But : Vous devez maîtriser à la fin de

Plus en détail

Informatique Générale

Informatique Générale Informatique Générale Guillaume Hutzler Laboratoire IBISC (Informatique Biologie Intégrative et Systèmes Complexes) [email protected] Cours Dokeos 625 http://www.ens.univ-evry.fr/modx/dokeos.html

Plus en détail

Représentation des Nombres

Représentation des Nombres Chapitre 5 Représentation des Nombres 5. Representation des entiers 5.. Principe des représentations en base b Base L entier écrit 344 correspond a 3 mille + 4 cent + dix + 4. Plus généralement a n a n...

Plus en détail

Manuel d utilisation 26 juin 2011. 1 Tâche à effectuer : écrire un algorithme 2

Manuel d utilisation 26 juin 2011. 1 Tâche à effectuer : écrire un algorithme 2 éducalgo Manuel d utilisation 26 juin 2011 Table des matières 1 Tâche à effectuer : écrire un algorithme 2 2 Comment écrire un algorithme? 3 2.1 Avec quoi écrit-on? Avec les boutons d écriture........

Plus en détail

Java Licence Professionnelle CISII, 2009-10

Java Licence Professionnelle CISII, 2009-10 Java Licence Professionnelle CISII, 2009-10 Cours 4 : Programmation structurée (c) http://www.loria.fr/~tabbone/cours.html 1 Principe - Les méthodes sont structurées en blocs par les structures de la programmation

Plus en détail

COURS D'INFORMATIQUE: LANGAGE C NOTES DE COURS

COURS D'INFORMATIQUE: LANGAGE C NOTES DE COURS MASTER PROFESSIONEL LASERS, MATERIAUX, MILIEUX BIOLOGIQUES COURS D'INFORMATIQUE: LANGAGE C NOTES DE COURS Christine ANDRAUD 2007/08 2 PLAN DU COURS: I. Introduction II. III. IV. Notions de bases Types

Plus en détail

Généralités sur le Langage Java et éléments syntaxiques.

Généralités sur le Langage Java et éléments syntaxiques. Généralités sur le Langage Java et éléments syntaxiques. Généralités sur le Langage Java et éléments syntaxiques....1 Introduction...1 Genéralité sur le langage Java....1 Syntaxe de base du Langage...

Plus en détail

EXCEL TUTORIEL 2012/2013

EXCEL TUTORIEL 2012/2013 EXCEL TUTORIEL 2012/2013 Excel est un tableur, c est-à-dire un logiciel de gestion de tableaux. Il permet de réaliser des calculs avec des valeurs numériques, mais aussi avec des dates et des textes. Ainsi

Plus en détail

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml OCL Object Constraint Language Le langage de contraintes d'uml Plan 1. Introduction 2. Les principaux concepts d'ocl Object Constraint Language 1 Object Constraint Language 2 Exemple: une application bancaire

Plus en détail

1. Introduction... 2. 2. Création d'une macro autonome... 2. 3. Exécuter la macro pas à pas... 5. 4. Modifier une macro... 5

1. Introduction... 2. 2. Création d'une macro autonome... 2. 3. Exécuter la macro pas à pas... 5. 4. Modifier une macro... 5 1. Introduction... 2 2. Création d'une macro autonome... 2 3. Exécuter la macro pas à pas... 5 4. Modifier une macro... 5 5. Création d'une macro associée à un formulaire... 6 6. Exécuter des actions en

Plus en détail

Télécom Nancy Année 2013-2014

Télécom Nancy Année 2013-2014 Télécom Nancy Année 2013-2014 Rapport 1A Ajout du langage C dans la Programmer's Learning Machine GIANNINI Valentin Loria 615, rue du Jardin Botanique 54600, Villers-Lès-Nancy Maître de stage : QUINSON

Plus en détail

Algorithmique avec Algobox

Algorithmique avec Algobox Algorithmique avec Algobox 1. Algorithme: Un algorithme est une suite d instructions qui, une fois exécutée correctement, conduit à un résultat donné Un algorithme doit contenir uniquement des instructions

Plus en détail

Traitement de texte : Quelques rappels de quelques notions de base

Traitement de texte : Quelques rappels de quelques notions de base Traitement de texte : Quelques rappels de quelques notions de base 1 Quelques rappels sur le fonctionnement du clavier Voici quelques rappels, ou quelques appels (selon un de mes profs, quelque chose qui

Plus en détail

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

Compression de Données - Algorithme de Huffman Document de Conception ROLLET Samuel SALLE Jennifer Compression de Données - Algorithme de Huffman Document de Conception Projet d'algorithmique et Structure des Données 1 SOMMAIRE 1. Domaine d application....4 1.1 Objectifs

Plus en détail

Plan du cours. Historique du langage http://www.oracle.com/technetwork/java/index.html. Nouveautés de Java 7

Plan du cours. Historique du langage http://www.oracle.com/technetwork/java/index.html. Nouveautés de Java 7 Université Lumière Lyon 2 Faculté de Sciences Economiques et Gestion KHARKIV National University of Economic Introduction au Langage Java Master Informatique 1 ère année Julien Velcin http://mediamining.univ-lyon2.fr/velcin

Plus en détail