La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Un survol du language C. Le language C Le language C appartient à une famille de languages (Pascal, Cobol, Fortran, etc.) où un programme est vu comme.

Présentations similaires


Présentation au sujet: "Un survol du language C. Le language C Le language C appartient à une famille de languages (Pascal, Cobol, Fortran, etc.) où un programme est vu comme."— Transcription de la présentation:

1 Un survol du language C

2 Le language C Le language C appartient à une famille de languages (Pascal, Cobol, Fortran, etc.) où un programme est vu comme une série dinstructions. Chaque instruction produit une transformation locale de la mémoire.

3 Les types de données Toutes les valeurs en C sont du type réel ou entier. En fait il sagit de deux « familles » de types puisquil existe plusieurs sortes d'entiers et de réels. Voici les deux principaux types en C. int : Les variables de ce type peuvent contenir un nombre entier, qui reflète typiquement la taille naturelle des nombres entiers sur la machine utilisée (souvent 32 bits). double : Les variables de ce type peuvent contenir un nombre réel en point flottant en double précision (64 bits)

4 Les constantes Les constantes de type double. point flottant: avec exposant: 12e E-4 -67e-5 mixtes: 1.2e e0 -6.7E-4 Les constantes de type int. décimales: octales: (commence par un zéro) hexadécimales: 0x11 0X8 -0x44(commence par 0x ou 0X)

5 Déclaration des variables La déclaration des variables se fait selon le modèle suivant: type variable1, variable2,... ; Remarquez la virgule séparant deux variables ainsi que le point- virgule à la fin. Exemples: int nbre; définit nbre comme une variable entière int a,b,c; définit trois variables entières dont les noms respectifs sont a, b et c. double x; double x; définit x comme une variable réelle.

6 Les opérateurs arithmétiques + addition - soustraction * multiplication / division % opérateur de modulo } Donne un int si les deux opérandes sont de type int, donne un double sinon Ne s'applique qu'à des opérandes de type int. Donne un int. Exemple: 4 % 3 vaut 1 12 % 3 vaut 0 17 % 5 vaut 2 donne le reste de la division entière }

7 Les opérateurs de comparaisons = > < = > > = < < = ! = notation mathématique notation en C type d'opérateur égal plus grand plus grand ou égal plus petit plus petit ou égal différent

8 Les opérateurs logiques ET OU NON && || ! Type dopérateur Notation en C

9 La priorité des opérateurs en C Opérateurs Associativité ( )de gauche à droite ! de droite à gauche * /de gauche à droite + -de gauche à droite >=de gauche à droite == !=de gauche à droite &&de gauche à droite ||de gauche à droite =de droite à gauche

10 Les instructions En C, une instruction est simple ou composée (dans ce dernier cas on parle aussi d'un bloc d'instructions). Instructions simples: Ex. x = x + 1; y = cos(x); x = cos(x / y - 8) * 2; Blocs d'instructions: Ex. { x = x + 1; y = cos(x); x = cos(x / y - 8) * 2; } 1 bloc dinstructions 3 instructions simples

11 Instruction conditionnelle Forme 1 if (expression) then instruction L'instruction est évaluée si et seulement si la valeur de l'expression est différente de 0. = 0 FAUX 0 VRAI Expression

12 Instruction conditionnelle Forme 2 if (expression) then instruction else instruction La première instruction est évaluée si la valeur de l'expression est différente de 0, sinon la seconde instruction est évaluée.

13 Instruction conditionnelle Forme 3 if (expression) then instruction else if (expression) then instruction else instruction

14 Autre forme conditionnelle switch (expression) { case expression-constante: instruction default: instructions } L'expression doit être de type entier. Elle est d'abord évaluée puis l'instruction correspondante est exécutée ainsi que les instructions suivantes.

15 Autre forme conditionnelle switch (expression) { case expression-constante: instruction default: instructions } L'expression doit être de type entier. Elle est d'abord évaluée puis l'instruction correspondante est exécutée ainsi que les instructions suivantes. valide: 5 2*3 + 5 non valide: 3*x + 5 x

16 L'instruction break Pour sortir d'un switch sans exécuter toutes les instructions, on peut utiliser l'instruction break. Le break peut aussi être utilisé pour sortir des boucles.

17 Exemple switch (n) { case 0: printf(0); case 1: printf(1); case 2: printf(2); default: printf(3);} Si n vaut 1 alors le programme affichera simplement: 123

18 Exemple switch (n) { case 0: {printf(0); break;} case 1: {printf(1); break;} case 2: {printf(2); break;} default: printf(3); } Si n vaut 1 alors le programme affichera simplement: 1

19 L'opérateur conditionnel ?: expression1 ? expression2 : expresion3 expression1 est d'abord évaluée. Si sa valeur est différente de 0 alors expression2 est évaluéee. Sinon, expression3 est évaluée. La valeur d'une expression conditionnelle est égale à la valeur de l'expression qui est évaluée (expression2 ou expression3). Le type d'une expression conditionnelle est le type le plus général entre celui de expression2 et expression3. Donc le type est double si une des deux expression est de type double.

20 L'opérateur conditionnel ?: Exemple: z = (x<5) ? 1 : 2 (x+1 < y) ? (4*5 + 2) : pow(2,3) (x<5) ? printf(1); : printf(2);

21 La boucle while while (expression) instruction Exemple. Pour afficher les 100 premiers entiers positifs: int compteur; compteur = 0; while (compteur < 100){ compteur + +; printf(%d, compteur); }

22 La boucle do-while do instruction1 while (expression2) Équivalent à: instruction1 while (instruction2) instruction1 Exemple. Pour lire et afficher une liste de nombre se terminant par 0. int n; do{ scanf(%d, &n); printf(%d, n); } while (n !=0)

23 La boucle for for (expression1 ; expression2 ; expression3) instruction Équivalent à: expression1; while(expression2) { instruction expression3; } Exemple. Pour afficher les n premiers entiers positifs pairs: int i; for (i=2; i<=2*n; i=i+2) printf(%d, i);

24 La bibliothèque standard du C Il y a peu d'opérateurs arithmétiques en C, mais à partir de ceux que nous avons vus il est possible d'en construire d'autres. On distingue les opérateurs de base des opérateurs complexe, construits à partir des opérateurs de base, en appelant ces derniers fonctions. La plupart des environnements supportants le C standard disposent d'une large collection de fonctions appelée bibliothèque standard.

25 Exemple: math.h Plusieurs fonctions mathématiques courantes font partie de la bibliothèque standard. Pour les utilisées il suffit d'inclure au début du programme la ligne suivante: #include Il est alors possible d'employer des fonctions telles que: cos(x)cosinus de x pow(x,y)x à la puissance y sqrt(x)racine carrée de x ldexp(x,n) et plusieurs autres.

26 Examinons plus en détails la fonction ldexp. Nous savons que cette fonction retourne la valeur Considérons quelques exemples: ldexp(1, 1) retourne ldexp(1.1, 1) retourne ldexp(1, 1.1) retourne Pourquoi??? Exemple: ldexp(x,n)

27 Pour comprendre ce qui se passe il faut savoir que la fonction ldexp attend deux nombres en entrée: x et n. x doit être un double n doit être un entier la fonction retourne un double Donc lorsque l'on exécute ldexp(1, 1.1), la fonction reçoit en fait les valeurs 1 et 1 puisque la partie fractionnaire du second opérande est tronquée.

28 Morale: avant d'utiliser une fonction de la bibliothèque il faut connaître son prototype. Le prototype d'une fonction indique le nom de la fonction le type des paramètres le type de la valeur de retour Les prototypes de fonctions Exemple: double ldexp(double, int) indique que ldexp est une fonction à deux paramètres (un double et un int) qui retourne un double.

29 Exemple: pow(x,y) La fonction d'exponentiation a le prototype suivant: double pow(double x, double y) de sorte qu'on ne peut pas l'utiliser de la façon suivante: pow(2, 3) % 5 Question: Pourquoi?

30 Il faut plutot écrire: (int) pow(2, 3) % 5 ou encore ( (int)pow(2,3) ) % 5 L'opérateur cast permet de convertir le type d'une expression en un autre type. (type) expression Exemple: pow(x,y)

31 Définition des fonctions Dans la plupart des langages de programmation, la définition d'une fonction comporte deux parties: l'en-tête et le corps. En-tête Nom de la fonction Type de la valeur retournée Nom des paramètres Types des paramètres { Corps Déclaration des variables Instructions

32 Les paramètres Paramètres formels: Ceux utilisés dans la définition. Paramètres d'appel: Ceux utilisés lors de l'appel.

33 Passage de paramètres Par copie: Les paramètres d'appel sont copiés dans les paramètres formels: création de nouvelles variables. Par référence: Les paramètre formels réfèrent aux paramètres d'appel: plusieurs noms pour une même case mémoire.

34 L'appel de fonctions Créations de nouvelles variables pour chacun des paramètres passés par copie. Le contrôle est donné à la fonction: la première ligne du corps de la fonction est d'abord exécutée. Remarques: Le nom des variables déclarées dans une fonctions est local à cette fonction et il est invisible aux autres fonctions. Deux fonctions distinctes peuvent utiliser le même identificateur pour nommer deux cases mémoire distinctes.

35 Retour d'une fonction À l'intérieur d'une fonction, l'instruction return expression; est exécutée de la façon suivante: L'expression est d'abord évaluée. Le résultat est retourné à la fonction appelante Toutes les variables ayant été créées après l'appel de la fonction sont détruites. Le contrôle est redonné à la fonction appelante.

36 Concepts importants Utilisations des fonctions pour étendre les possibilités de l'ordinateur. Prototype d'une fonction Définition d'une fonction. Les paramètres L'appel d'une fonction Le retour d'une fonction

37 Structure d'un programme en C Un programme en C est une collection de fonctions qui interagissent entre elles afin d'exécuter un calcul. Une des fonctions doit porter le nom main: c'est la première fonction à être appelée lors de l'exécution du programme. Comme on l'a vu, on peut utiliser les fonctions de la bibliothèque standard ou encore, on peut définir nos propres fonctions

38 La récursion Nous avons vu qu'un programme est constitué d'un ensemble de fonctions. Il est possible pour une fonction donnée d'appeler une autre fonction. Que se passe-t-il si une fonction s'appelle elle-même? C'est ce que l'on appelle la récursion.

39 Étude de cas 6.1 Pas-à-pas avec n=4 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact entier n nfact n nfact entier

40 entier n nfact lire n nfact si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact lire n n nfact entier

41 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact si (n < 0) alors écrire entrée négative: n n nfact entier

42 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact nfact factoriel(n) n nfact entier

43 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1)

44 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1

45 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1)

46 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) n entier

47 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 nentier

48 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) n entier

49 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n * factoriel(n-1) n n entier

50 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n * factoriel(n-1) n n entier si (n 1) retourner 1

51 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n * factoriel(n-1) n n entier retourner n * factoriel(n-1)

52 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n * factoriel(n-1) n n entier si (n 1) retourner 1 retourner n * factoriel(n-1) n entier

53 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n * factoriel(n-1) n n entier si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 n entier

54 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) si (n 1) retourner 1 retourner n *1 n entier n retourner n * 1

55 si (n 1) retourner 1 retourner n * factoriel(n-1) entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) n entier retourner n * 2

56 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier n si (n 1) retourner 1 retourner n * factoriel(n-1) retourner n * 6

57 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier nfact 24

58 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier écrire la factorielle de n est nfact

59 entier n nfact lire n si (n < 0) alors écrire entrée négative: n sinon nfact factoriel(n) écrire la factorielle de n est nfact n nfact entier est 24 La factorielle de 4 est 24

60 À retenir Une fonction peut s'appeler elle-même Sans condition d'arrêt, l'exécution de la fonction n'aurait pas de fin.

61 Les adresses max Les cases mémoires ont toutes un numéro qui les distingue les unes des autres: ce numéro est appelé adresse. Cest par cette adresse que le processeur peut communiquer avec la mémoire.

62 Les adresses et les variables Le nom que lon donne au cases mémoire est traduit en une adresse juste avant lexécution dun programme. Cela est nécessaire afin que le processeur sache à quelle case mémoire est associée chaque variable. En général il est impossible de prévoir à quelle adresse sera placée une variable. Le nom des variables est donc nécessaire c1: 1 2 c2: 3 4 max char c1 = c2; Lire le contenu de la case 3. Mettre ce qui a été lu dans la case 1.

63 Le partage de la mémoire Sur les systèmes modernes il peut y avoir plusieurs usagers se partageant la mémoire et chaque usager peut exécuter plusieurs programmes simultanément. Cela signifie que lon nest pas libre dutiliser toutes les cases mémoires comme on le veut. Une case peut être occupée par un programme à un certain moment et libre à un autre. Cette situation est aléatoire. Pour cette raison, on ne mentionne jamais explicitement une adresse dans un programme même si cela est théoriquement possible.

64 Adresses valides et non valides Exemple. Dans le pseudo-code suivant: Lire le contenu de la case 3. Mettre ce qui a été lu dans la case 1. Que se passe t-il si au moment de lexécution la case mémoire 1 est déja utilisée par un autre programme. La case est alors non valide et il y aura erreur à lexécution. Cest pour cette raison que lon utilise des variables. Avant lexécution, une adresse valide est associée à chaque variable. Seul notre programme pourra utiliser ces cases mémoire.

65 Position des variables dans la mémoire Sauf pour les tableaux, il ny a aucune garantie que les variables occupent des cases adjacentes en mémoire. Exemple. int a,b[4],c,d[3]; a b[0] b[1] b[2] b[3] d[1] d[2] d[0] c int

66 Les adresses et les tableaux Le nom dun tableau correspond à ladresse du début du tableau. Exemple: char tab[5]; printf(%p\n, tab); printf(%p\n, tab+1); printf(%p\n, tab+2); Note: %p sert à afficher les adresses.

67 Les tableaux dentiers Exemple: int tab[5]; printf(%p\n, tab); printf(%p\n, tab+1); printf(%p\n, tab+2); Question: Pourquoi? +4

68 Lincrémentation dune adresse Incrémenter une adresse ne veux pas dire ajouter 1, cela veut dire aller à ladresse suivant la variable courante. En général cela na du sens que si on est dans un tableau a: b[0]: b=24600 b[1]: b+1=24604 b[2]: b+2=24608 b[3]: b+3= d[1]: d+1=54317 d[2]: d+2= d[0]: d=54316 int char Ladresse nest pas valide

69 Remarque Si Tab est un tableau alors Ladresse de Tab[0] est Tab, ladresse de Tab[1] est Tab + 1, ladresse de Tab[2] est Tab + 2, etc. Cela est vrai quelque soit le type des éléments de Tab.

70 Lopérateur & Il est possible de connaître, pendant lexécution dun programme, ladresse associée à une variable. En C, cela est possible à laide de lopérateur unaire & Exemple: char c; int n, tab[1000]; Ladresse de c est &c Ladresse de n est &n Ladresse de tab[3] est &tab[3] ou tab+3

71 Lopérateur * Il est aussi possible de connaître, pendant lexécution dun programme, le contenu de la case mémoire située à une adresse donnée. En C, cela est possible à laide de lopérateur unaire * Exemple: char c; int tab[1000]; Le contenu de ladresse tab + 25 est *(tab + 25) *(tab + 25) est donc identique à tab[25] *(&c) est identique à c *c na aucun sens

72 Exemple Les expressions logiques suivantes sont vraies: &n == *(12560) == 60 *(12560) < c2 *(&r) == char double n: int c1: 12560char r: c2: 12561

73 Résumé des opérations sur les adresses On peut: Additionner une adresse et un entier Déterminer ladresse dune variable Déterminer le contenu dune adresse On ne peut pas Additionner deux adresses (mais on peut soustraire deux adresses dun même tableau)

74 Les pointeurs Un pointeur est une variable pouvant contenir une adresse. Exemple: int *pn;pointeur sur une valeur entière char *pc;pointeur sur un caractère double *pr;pointeur sur un double

75 Les pointeurs et les tableaux En C les pointeurs sont intimement liés aux tableaux. Exemple: int tab[10], *p; p=tab; tab[3] = 70; *(tab + 3) = 70; p[3] = 70; *(p + 3) = 70; tous équivalent:

76 Remarque Le nom dun tableau est une adresse constante et non pas un pointeur qui est une variable. Exemple: int tab[10], *p; p=tab; p = tab;/* Valide */ tab = p;/* Non valide */ tab : p:

77 Quelques utilités des pointeurs Pour implanter le passage de paramètres par référence Pour implanter le passage de tableaux en paramètre Pour utiliser des indices négatifs au tableaux Fondamental en structure de données

78 Le pointeur NULL Il est parfois utile d'indiquer qu'un pointeur ne contient aucune adresse. On utilise alors le pointeur NULL dont la valeur est 0. Exemple: int *p; p=NULL; if (p != NULL) printf("%d",*p);

79 Les tableaux à deux dimensions Exemple: int Tab[N][M] Ladresse de Tab[i][j] est Tab + i*M + j Tab[0][0]: Tab+0+0 = Tab int Tab[0][1]: Tab+0+1 = Tab+1 Tab[1][0]: Tab+2+0 = Tab+2 Tab[1][1]: Tab+2+1 = Tab+3 Tab[2][0]: Tab+4+0 = Tab+4 Tab[2][1]: Tab+4+1 = Tab+5 int Exemple avec N=3 et M=2

80 Les tableaux à deux dimensions Exemple: int Tab[N][M] Ladresse de Tab[i][j] est Tab + i*M + j Remarque: Pour calculer l adresse de Tab[i][j] il n est pas nécessaire de connaître N mais il est nécessaire de connaître M Cela explique pourquoi il est nécessaire de préciser M dans les paramètres formels. Ex. f(char tab[N][M]) ou f(char tab[][M])

81 Les constantes de type caractère En C une constante de type caractère est un nombre entier écrit sous la forme d'un caractère entre apostrophes, comme a. La valeur d'une constante de type caractère est égale à la valeur du caractère d'après le jeu de caractère de la machine (ex. ASCII). Exemples: a vaut 97 A vaut 65 B vaut 66 0 vaut 48

82 Les séquences d'échappement \acaractère d'alerte (sonnerie, bell) \bretour en arrière (backspace) \fsaut de page (formfeed) \nfin de ligne (newline) \rretour de chariot (carriage return) \ttabulation horizontale \vtabulation verticale \\backslash \?point d'interrogation \apostrophe \ guillemet \ooonombre octal \xhhnombre hexadécimale

83 Les variables de type caractère En C, les caractères sont des entiers de 8 bits. Pour déclarer une variable de type caractère, on procède de la façon suivante: char c1; /* c1 est une variable de type caractère */ char c2 = a;/* c2 est une variable de type caractère initialisée à 97 */ char c3 = 97;/* c3 et c2 contiennent la même valeur */

84 Exemple 1: Copier des fichiers #include /* copie lentrée sur la sortie; première version*/ main(){ int c; c = getchar(); while (c != EOF) { putchar(c); c = getchar(); } Pourquoi un int?

85 Exemple 1: Copier des fichiers La valeur retourné par getchar() peut être un des 256 caractères ASCII OU la valeur EOF La fonction getchar() peut donc retourner 257 valeur possibles. Mais un char est un entier de 8 bits et ne peut donc représenter que 256 valeurs possibles. On doit donc utiliser plus de bits (et donc un int) pour faire la différence entre un caractère et EOF.

86 Exemple 1: Copier des fichiers Exemple: Sur un Pentium III, un int est un entier de 32 bits et EOF sécrit en binaire de la façon suivante: bits Losrque lon met EOF dans une variable de type char on ne met que les 8 premiers bits, cest-à-dire = 255 Le caractère dont la valeur est 255 peut être ÿ ou encore le caractère blanc selon le jeu de caractères utilisé.

87 Exemple 1: Copier des fichiers #include /* copie lentrée sur la sortie, seconde version */ main(){ int c; while ((c=getchar()) != EOF) putchar(c); }

88 Les constantes de type chaîne Un constante de type chaîne est une séquence de caractères, éventuellement vide, placée entre guillemets. Exemple: Je suis une chaîne Bonjour groupe!\n Comment allez-vous\?\n Note: Les guillemets ne font pas partie de la chaîne.

89 Les chaînes de caractères En C il ny a pas de variable de type chaîne de caractères. Une chaîne de caractère est un tableau de caractères se terminant par le caractère \0 (le caractère NUL ayant la valeur 0) Ainsi la chaîne Bonjour groupe! serait représentée de la façon suivante: Bornjuogr oupe!\

90 Déclarer un tableau de caractères Les 4 déclarations suivantes ont le même effet: char chaine[]={'B','o','n','j','o','u','r',' ','g','r','o','u','p','e','!','\0'}; char chaine[16]={'B','o','n','j','o','u','r',' ','g','r','o','u','p','e','!','\0'}; char chaine[]="Bonjour groupe!"; char chaine[16]="Bonjour groupe!"; Bornjuogr oupe!\

91 Assignation L'opération suivante est illégale: char chaine[16]; chaine="Bonjour groupe!"; On ne peut pas assigner de façon dynamique une chaine à un tableau de caractères.

92 Types composés En plus des types de base (entier, réels, charactères, etc) il est possible dans la plupart des langages de programmation de définir ses propres types. Il sagit en fait de rassembler une ou plusieurs variables, qui peuvent être de types différents, et de les regrouper sous un seul nom afin de les manipuler plus facilement.

93 Exemple en C struct complexe {/* défini un nouveau type */ double reel; double imag; }; struct complexe x;/* déclare une variable de type complexe */ x.reel: x.imag:

94 Où définir un nouveau type #include struct complexe { double reel; double imag; }; fonction(...){ struct complexe x; } Si on défini un nouveau type à lintérieur dune fonction alors il ne sera visible quà lintérieur de cette fonction. Pour quun type composé soit visible dans toutes les fonctions dun fichier, il faut le déclarer au début du fichier, à lextérieur de toute fonction. Note: La même chose sapplique à la déclaration de variables: cest ce que lon appelle les variables globales.

95 Assignation de valeurs dans une structures struct complexe { double reel; double imag; }; struct complexe x; x.reel = 5; x.imag = 3; 5 3 x.reel: x.imag:

96 Accéder aux membres dune structure struct complexe x, y, z; x.reel = 5; x.imag = 3; y = x; z.reel = x.réel; z.imag = 8; 5 3 x.reel: x.imag: 5 y.reel: 3 y.imag: 5 z.reel: 8 z.imag:

97 Comparer deux structures if (x == y) printf(Deux structures égales); if (x != z) printf(Deux structures differentes); 5 3 x.reel: x.imag: 5 y.reel: 3 y.imag: 5 z.reel: 8 z.imag: Remarque: La comparaison x

98 Les structures et les fonctions On peut passer des structures en paramètre. On peut utiliser les structures comme valeur de retour. Contrairement aux tableaux, les structures sont passées par copie.

99 typedef Dans lexemple précédent, il est laborieux davoir à écrire autant de struct complexe. Le C fournit une fonctionnalité appelée typedef servant à créer des noms de nouveaux types de données. Exemple: typedef struct complexe Complexe Complexe x, y; Le nom Complexe devient synonyme de struct complexe

100 Les structures et les pointeurs Les pointeurs de structures sont si fréquemment utilisés quil existe une notation abrégée. Exemple: struct complexe *pc, x; pc = &x; pc->reel = 3;/* identique à (*pc).reel=3 */ pc->imag = 5;/* identique à (*pc).imag=5 */

101 Allocation dynamique de la mémoire Jusquà maintenant, toute la mémoire que nous avons utilisée dans nos programmes devait avoir été allouée avant l'exécution à laide des déclarations de variables. Il est parfois utile dallouer une partie de lespace mémoire en cours dexécution.

102 Exemple Par exemple si on a besoin de mémoriser un certains nombre dobjets mais que ce nombre nest pas connu avant lexécution du programme. Il faut alors allouer suffisament despace au cas ou le nombre dobjet est grand. Si le nombre dobjets est petits, on gaspille inutilement de lespace mémoire.

103 Le fichier dentête stdlib.h Le fichier dentête stdlib.h contient des déclarations de fonctions traitant, entre autres, de lallocation de la mémoire: - malloc - free - calloc - realloc

104 void *malloc(size_t size) size_t est le type dentiers positifs retourné par lopérateur sizeof malloc retourne un pointeur sur un espace mémoire réservé à un objet de taille size, ou bien NULL si cette demande ne peut être satisfaite. La mémoire allouée nest pas initialisée.

105 Pointeurs sur void La fonction malloc ne sait pas à quoi servira lespace mémoire qui lui est demandée. Elle ne sait pas quel type dobjet utilisera cet espace. Alors, elle retourne un pointeur générique qui peut être converti en ninporte quel type de pointeur: un pointeur sur void

106 void free(void * p) free libère lespace mémoire pointé par p; elle ne fait rien si p vaut NULL. p doit être un pointeur sur un espace mémoire alloué par malloc, calloc ou realloc.

107 void *calloc(size_t nobj, size_t size) calloc retourne un pointeur sur un espace mémoire réservé à un tableau de nobj objets, tous de taille size, ou bien NULL si cette demande ne peut pas être satisfaite. La mémoire allouée est initialisée par des zéros.

108 void *realloc(void *p, size_t size) realloc change en size la taille de lobjet pointé par p. Si la nouvelle taille est plus petite que lancienne, seul le début du contenu de lobjet est conservé. Si la nouvelle taille est plus grande, le contenu de lobjet est conservé, et lespace mémoire supplémentaire nest pas initialisé. realloc retourne un pointeur sur un nouvel espace mémoire, ou bien NULL si cette demande ne peut pas être satisfaite, auquel cas *p nest pas modifié.

109 Exemple On veut lire des entiers et les mettre en mémoire. Plutôt que de créer un tableau avant lexécution, on utilise calloc pendant lexécution. int *p, n; scanf(%d, &n); p = (int *) calloc(n, sizeof(int)); si plus tard cet espace nest plus suffisant, alors on utilise: p = (int *) realloc(p, 2*n); p: …

110 Exemple Liste chaînée struct noeud{ int valeur; noeud *suivant; }; struct noeud *chaine, *p; chaine: p:

111 Exemple 5 chaine = (struct noeud) malloc(sizeof(struct noeud)); chaine: p: valeursuivant

112 Exemple 5 chaine = (struct noeud) malloc(sizeof(struct noeud)); chaine -> valeur = 8; chaine: 8 p:

113 Exemple 5 chaine -> suivant = (struct noeud) malloc(sizeof(struct noeud)); chaine: 8 p:

114 Exemple 5 p = chaine -> suivant; chaine: 8 p:

115 Exemple 5 p -> valeur = 5; chaine: 8 5 p:

116 Exemple 5 p -> suivant = (struct noeud) malloc(sizeof(struct noeud)); chaine: 8 5 p:

117 Exemple 5 p = p -> suivant; chaine: 8 5 p:

118 Exemple 5 p -> valeur = 13; p -> suivant = NULL; chaine: 8 5 p: 130

119 Exemple 5 p = chaine; while (p != NULL){ printf(%d\n, p->valeur); p = p->suivant; } chaine: 8 5 p: 130


Télécharger ppt "Un survol du language C. Le language C Le language C appartient à une famille de languages (Pascal, Cobol, Fortran, etc.) où un programme est vu comme."

Présentations similaires


Annonces Google