Types de donns Types de donns primitifs Types

  • Slides: 45
Download presentation
Types de donnés • Types de donnés primitifs • Types de donnés structurées •

Types de donnés • Types de donnés primitifs • Types de donnés structurées • Chaînes de caractères • Types énumérés • Tableaux • Enregistrements • Ensembles • Pointeurs 1

Types primitifs • Types numériques • Booléens • Caractères 2

Types primitifs • Types numériques • Booléens • Caractères 2

Introduction Un type de donnés n’est pas seulement un ensemble d’objets. Il faut aussi

Introduction Un type de donnés n’est pas seulement un ensemble d’objets. Il faut aussi considérer les opérations sur ces objets. Une définition complète d’un type doit inclure la liste des opérations et leur définition. Les types Primitifs sont près du hardware, et sont représentés directement (ou presque) au niveau de la machine — par un word, byte, bit. 3

Entiers Un type Entier est une approximation finie de l’ensemble infinie des nombres naturels:

Entiers Un type Entier est une approximation finie de l’ensemble infinie des nombres naturels: {0, 1, -1, 2, -2, . . . }. Plusieurs types d’entiers: signed—unsigned, long—short—small. Implémentation Hardware: complément à un, complément à deux, . . . 4

Nombres à virgule flottante Les nombres à virgule flottante sont une approximation finie de

Nombres à virgule flottante Les nombres à virgule flottante sont une approximation finie de l’ensemble nondénombrable des nombres réels. La précision et l’étendue des valeurs est définie par le langage ou le programmeur. Implémentations Hardware (pour les processeurs à virgule flottante): exposant et mantisse. 5

Booléens Ce type n’est pas supporté par tout les langages (PL/, C, Perl ne

Booléens Ce type n’est pas supporté par tout les langages (PL/, C, Perl ne le supporte pas). Les valeurs sont true et false. Les Opérations sont celles de la logique propositionnelle classique à deux valeurs. Implémentation hardware: un seul bit, ou un byte (pour rendre les instructions plus efficace). 6

Caractères Habituellement ASCII, mais des ensembles de caractères étendus (Unicode, ISO) sont souvent utilisés.

Caractères Habituellement ASCII, mais des ensembles de caractères étendus (Unicode, ISO) sont souvent utilisés. Les caractères avec accents comme é ou ü devraient pouvoir être incorpores dans ASCII, mais il n’y a pas de standard unique pour le faire. Le chinois ou le japonais sont des exemples de systèmes d’écriture nécessitent plus que 256 caractères. Implémentation hardware: un byte (ASCII, EBCDIC), deux bytes (Unicode) ou plus. . . 7

Autres • word (par exemple, en Modula-2) • byte, bit (par exemple, en PL/I)

Autres • word (par exemple, en Modula-2) • byte, bit (par exemple, en PL/I) • pointeurs (par exemple, en C) 8

Types de donnés Structurés • Chaînes de caractères • Types énumérées • Tableaux •

Types de donnés Structurés • Chaînes de caractères • Types énumérées • Tableaux • Enregistrements 9

Chaînes de caractères Une chaîne de caractères peut être: • Un type de donnés

Chaînes de caractères Une chaîne de caractères peut être: • Un type de donnés spéciale (dont les objets peuvent être décomposés en caractères)—Fortran, Basic; • un tableau de caractères—Pascal, Ada; • Une liste de caractères—Prolog; • Des caractères emmagasinés de façon consécutive en mémoire—C. La syntaxe est la même: caractères entre guillemets. Pascal utilise un seul type de guillemets, Ada deux: 'A' est un caractère, "A" une chaîne de caractères. 10

Opérations sur les chaînes de caractères Opérations typiques string concaténation string int string Sous-chaîne

Opérations sur les chaînes de caractères Opérations typiques string concaténation string int string Sous-chaîne string char Décomposition en un tableau ou une liste char string conversion d’un tableau ou une liste en chaîne. 11

Opérations sur les chaînes de caractères (2) string int longueur string bool Est-elle vide?

Opérations sur les chaînes de caractères (2) string int longueur string bool Est-elle vide? string bool égalité, relation d’ordre (>, <, …) 12

Autres opérations sur les chaînes de caractères Des langages spécialisés pour la manipulation des

Autres opérations sur les chaînes de caractères Des langages spécialisés pour la manipulation des chaînes de caractères (Snobol, Icon) incluent des opérations d’appariement des patrons, parfois très compliquées avec un backtracking élaboré. Un autre langage qui est utile pour manipuler les chaînes de caractères est Perl. 13

Chaînes de caractères de taille fixe et variable La longueur des chaînes de caractères

Chaînes de caractères de taille fixe et variable La longueur des chaînes de caractères permise est un choix de conception: Chaînes de taille fixe : Pascal, Ada, Fortran; Chaînes de taille variable : C, Java, Perl. Un caractère peut être traité comme une chaîne de longueur 1, ou comme une structure différente. Plusieurs langages (Pascal, Ada, C, Prolog) traitent les chaînes comme un cas spécial des tableaux ou des listes. Les Opérations sur les chaînes sont les mêmes que sur les tableaux ou les listes. Par exemple, chaque caractère dans un tableau de caractère peut être accédé directement, mais sur les listes, on doit y accéder linéairement. 14

Types énumérés Appelé aussi: Type ordinaux définis par l’usagé [voir Section 6. 4 du

Types énumérés Appelé aussi: Type ordinaux définis par l’usagé [voir Section 6. 4 du manuel] On peut déclarer une liste de constantes symboliques qui sera traitée littéralement, tout comme les atomes de Prolog ou Scheme. On spécifie aussi l’ordre implicite de ces nouvelles constantes symboliques. En Pascal: type day = (mo, tu, we, th, fr, sa, su); Ici, on aura: mo < tu < we < th < fr < sa < su. 15

Opérateurs sur les types énumérés Pascal fournie 3 opérations génériques sur chaque nouveau type

Opérateurs sur les types énumérés Pascal fournie 3 opérations génériques sur chaque nouveau type énuméré T: successeur, par exemple, succ(tu) = we pred: prédécesseur, par exemple, pred(su) = sa (ces opérations sont indéfinies aux extrémités) ord: position (ordinal) dans le type, en commencent à 0, par exemple: ord(th) = 3 Pour les caractères, Pascal a aussi chr, qui produit le caractère pour une position donné, par exemple: chr(65) = ‘A’. 16

Types énumérés en Ada rend ces opérations génériques complètes: succ: successeur, pred: prédécesseur, pos:

Types énumérés en Ada rend ces opérations génériques complètes: succ: successeur, pred: prédécesseur, pos: position, val: constante à la position donnée. Ada incluse aussi des attributs de type, incluant FIRST et LAST: day'FIRST = mo, day'LAST = su 17

Réutilisation de constantes symboliques Un choix de conception: une constante symbolique peut-elle être utilisé

Réutilisation de constantes symboliques Un choix de conception: une constante symbolique peut-elle être utilisé dans plus d’un type? En Pascal, non. En Ada, oui: type stoplight is (red, orange, green); type rainbow is (violet, indigo, blue, green, yellow, orange, red); Les descriptions qualifiés—semblable au forçage de type— prévient l’ambiguïté: on peut écrire stoplight'(red) ou rainbow'(red). 18

Implémentation des types énumérés On fait correspondre les constantes c 1, . . .

Implémentation des types énumérés On fait correspondre les constantes c 1, . . . , ck aux petits entiers 0, . . . , k-1. Les types énumérés peuvent augmenter la clarté et la lisibilité des programmes en séparant les concepts des codes numériques. 19

Tableaux Un tableau est une mise en correspondance: type_indexe type_composant Le type des indexes

Tableaux Un tableau est une mise en correspondance: type_indexe type_composant Le type des indexes doit être un type discret (entier, caractère, énumération etc. ). Dans certain langages, ce type est spécifié implicitement : Un tableau de taille N possède des indexes entre 0 et N-1 en C++ / Java / Perl, mais en Fortran, entre 1 et N. Avec Algol, Pascal, Ada les bornes doivent être données. Il y a habituellement peu de restrictions sur le type du composant (Dans certain langages, on peut avoir des tableaux de procédures ou de fichiers). 20

Tableaux multidimensionnels Les tableaux Multidimensionnels peuvent être défini de deux façons (pour simplifier la

Tableaux multidimensionnels Les tableaux Multidimensionnels peuvent être défini de deux façons (pour simplifier la présentation, on se limitera aux tableaux de dimension 2): type_index_1 type_index_2 type_composant Ceci correspond à des références tel que A[I, J] comme en Algol, Pascal, Ada. type_index_1 (type_index_2 type_composant) Ceci correspond à des références tel que A[I][J] comme en Java. Perl ne permet pas de tableaux de plus d’une dimension. 21

Opérations sur les tableaux (1) Choisir un élément (pour l’utiliser, ou changer sa valeur):

Opérations sur les tableaux (1) Choisir un élément (pour l’utiliser, ou changer sa valeur): A[J] Choisir une tranche d’un tableau: (voir le manuel, Section 6. 5. 7) Affectation d’un tableau complet: A : = B; Il y a une boucle implicite dans cette opération. 22

Opérations sur les tableaux (2) Évaluer une expression sur les tableaux complet (ceci est

Opérations sur les tableaux (2) Évaluer une expression sur les tableaux complet (ceci est possible dans plusieurs langages spécialisés ou extensible, entre autre Ada): V : = W + U; Si V, W, U sont des tableaux, ceci dénote l’addition de tableaux. Ceux-ci doivent être compatible (le même type d’index et d’élément), et l’addition est probablement faite élément par élément. 23

Attachement des indexes statique: taille fixe, attribution statique de la mémoire Dans les anciennes

Attachement des indexes statique: taille fixe, attribution statique de la mémoire Dans les anciennes version de Fortran. semi-statique: taille fixe, attribution dynamique de la mémoire Pascal. semi-dynamique: taille déterminée à l’exécution, attribution dynamique de la mémoire Ada dynamique: taille change durant l’exécution, attribution flexible de la mémoire nécessaire Algol 68, APL—tous deux peu utilisés. 24

Constantes de type tableaux et initialisation Plusieurs langages permettent l’initialisation des tableaux, en la

Constantes de type tableaux et initialisation Plusieurs langages permettent l’initialisation des tableaux, en la spécifiant à la déclaration: C int vector [] = {10, 20, 30}; Ada vector: array(0. . 2) of integer : = (10, 20, 30); Les tableaux constants d’Ada : temp is array(mo. . su)of -40. . 40; T: temp; T : = (15, 12, 18, 22, 30, 22); T : = (mo=>15, we=>18, tu=>12, sa=>30, others=>22); T : = (15, 12, 18, sa=>30, others=>22); 25

Implémentation des tableaux(1) Le choix de conception consiste en la façon d’organiser le tableau

Implémentation des tableaux(1) Le choix de conception consiste en la façon d’organiser le tableau en mémoire et d’accéder à ses éléments. Un tableau est représenté, lors de l’exécution, par un descripteur qui nous informe sur: le type de l’index, le type des composant, l’adresse du tableau – de ses donnés. 26

Implémentation des tableaux(2) Plus spécifiquement, on a besoin de: Les bornes du tableau (indexes

Implémentation des tableaux(2) Plus spécifiquement, on a besoin de: Les bornes du tableau (indexes min et max) pour la vérification des indexes, L’adresse du début du tableau, La taille d’un élément du tableau. Alors, avec un index, déterminant le décalage par rapport au début du tableau, on peut déterminer l’emplacement d’un composant en mémoire. Un tableau multidimensionnel sera représenté par un descripteur contenant plusieurs bornes (plutôt que deux). 27

Implémentation des tableaux multidimensionnels 11 12 13 14 15 21 22 23 24 25

Implémentation des tableaux multidimensionnels 11 12 13 14 15 21 22 23 24 25 31 32 33 34 35 Par rangés (le deuxième index change plus vite) 11 12 13 14 15 21 22 23 24 25 31 32 33 34 35 Par colonnes (le premier index change plus vite) 11 21 31 12 22 32 13 23 33 14 24 34 15 25 35 28

(2) Voici un tableau: A: array [LOW 1. . HIGH 1, LOW 2. .

(2) Voici un tableau: A: array [LOW 1. . HIGH 1, LOW 2. . HIGH 2] of ELT; Ou la taille de chaque élément de type ELT est SIZE. Les calculs qui suivent sont fait avec une représentation par rangés (les calculs pour une représentation par colonnes sont semblables). On a besoin de la base (l’adresse du début du tableau—par exemple, l’adresse LOC de A[LOW 1, LOW 2]. 29

3) On peut calculer l’adresse de A[I, J], étant donné une base, avec une

3) On peut calculer l’adresse de A[I, J], étant donné une base, avec une représentation par rangé. La longueur de chaque rangé du tableau est: ROWLENGTH = HIGH 2 - LOW 2 + 1 L’adresse de A[I, J] est: (I - LOW 1) * ROWLENGTH * SIZE + (J - LOW 2) * SIZE + LOC 30

(4) Voici un exemple. VEC: array [1. . 10, 5. . 24] of integer;

(4) Voici un exemple. VEC: array [1. . 10, 5. . 24] of integer; La longueur des rangés est: ROWLENGTH = 24 - 5 + 1 = 20 Si l’adresse de base est 1000, et la taille d’un integer est 4: L’adresse de VEC[i, j] est: (i - 1) * 20 * 4 + (j - 5) * 4 + 1000 Par exemple, VEC[7, 16] est situé sur les 4 bytes commencent à: 1524 = (7 - 1) * 20 * 4 + (16 - 5) * 4 + 1000 31

Langages sans tableaux Les tableaux ne sont pas disponible dans le Prolog standard et

Langages sans tableaux Les tableaux ne sont pas disponible dans le Prolog standard et le Scheme pure. Un tableau peut être simulé avec une liste, qui est une structure de base en Scheme et un type de donné important en Prolog. En supposant que les indexes sont toujours 1. . N. On peut traiter une liste de N éléments: [x 1, x 2, . . . , x. N] (Prolog) (x 1 x 2. . . x. N) (Scheme) comme tableau structuré de valeurs. 32

Enregistrements Un enregistrement est une collection hétérogène de champs (composant)—ceci par rapport aux tableaux

Enregistrements Un enregistrement est une collection hétérogène de champs (composant)—ceci par rapport aux tableaux qui sont une collection homogène. Les enregistrements sont disponible dans la majorité des langages important: Cobol, Pascal, PL/I, Ada, C (struct), Prolog (!) et C++. Les enregistrements sont remplacés par les classes en Java. Il n’y a pas d’enregistrements en Perl. 33

Enregistrements Ada—syntaxe type date is record day: 1. . 31; month: 1. . 12;

Enregistrements Ada—syntaxe type date is record day: 1. . 31; month: 1. . 12; year: 1000. . 9999; end record; type person is record name: record fname: string(1. . 20); lname: string(1. . 20); end record; born: date; gender: (F, M); end record; 34

Champs Un champ se distingue par son nom, plutôt que son indexe. L’itération à

Champs Un champ se distingue par son nom, plutôt que son indexe. L’itération à travers les éléments d’un tableau est naturelle et très utile, mais à travers les champs d’un enregistrement, elle est impossible. Un champ est indiqué par un nom qualifié. En Ada: X, Y: person; X. born. day : = 15; X. born. month : = 11; X. born. year : = 1964; Y. born : = (23, 9, 1949); Y. name. fname(1. . 8) : = "Smithson"; 35

Opérations sur les enregistrements (1) La sélection d’un composant est faite avec le nom

Opérations sur les enregistrements (1) La sélection d’un composant est faite avec le nom du champ. La construction d’un enregistrement à partir des composants —soit comme champs séparés, ou comme un enregistrement complet dans une constante structurée: D : = (month => 10, day => 15, year => 1994); D : = (day => 15, month => 10, year => 1994); D : = (15, 10, year => 1994); Notez qu’on peut aussi assigner à un tableau une telle constante. L’interprétation dépend du contexte. A: array(1. . 3)of integer; A : = (15, 10, 1994); 36

Opérations sur les enregistrements (2) L’assignation des enregistrements complets est permise en Ada, et

Opérations sur les enregistrements (2) L’assignation des enregistrements complets est permise en Ada, et faite champ par champ. Des enregistrements peuvent être compares (égalité, inégalité) peu importe leur structure ou le type de leurs composants. Aucune relation d’ordre standard n’est définie sur les enregistrements, mais elle peut être définie par le programmeur. 37

Plus sur les enregistrements Ada permet des valeurs par défaut pour les champs: type

Plus sur les enregistrements Ada permet des valeurs par défaut pour les champs: type date is record day: 1. . 31; month: 1. . 12; year: 1000. . 9999 : = 2002; end record; D: date; -- D. year est maintenant 2002 Il n’y a presque aucune restriction sur le type des champs. N’importe quelle combinaison d’enregistrements et de tableaux (de n’importe quelle profondeur) est habituellement possible. Un champ peut même être un fichier, ou une procédure! 38

L’équivalent Prolog des enregistrements Les enregistrements—ou termes—en Prolog n’ont pas d’ordre fixes pour les

L’équivalent Prolog des enregistrements Les enregistrements—ou termes—en Prolog n’ont pas d’ordre fixes pour les types et les composants: date(day(15), month(10), year(1994)) person( name(fname("Jim"), lname("Berry")), born(date(day(15), month(10), year(1994))), gender(male)) Si on s’assure d’un usage correcte, la structure peut être simplifiée en abandonnant les functors de type ayant un seul paramètre: date(15, 10, 1994) person(name("Jim", "Berry"), born(date(15, 10, 1994)), male) 39

Pointeurs [Note: On ne va pas discuter section 6. 9. 9] Une variable de

Pointeurs [Note: On ne va pas discuter section 6. 9. 9] Une variable de type pointeur possède des adresses comme valeurs (ou l’adresse spéciale nil or null représentant « aucune adresse"). Elles sont utilisées principalement pour construire des structures de forme ou de taille imprédictible—listes, arbres, graphes—à partir de petits fragments alloués dynamiquement lors de l’exécution. Un pointeur à une procédure est possible, mais il est plus fréquent d’avoir des pointeurs à des donnés (simple ou composées). Une adresse, avec une valeur, et habituellement un type constituent une variable. On l’appel variable anonyme car elle ne possède pas de nom. Pour accéder à la valeur de cette variable, il faut déréférencer le pointeur. 40

Back to pointers (2) Les pointeurs en Pascal sont bien définis. p 17 value(p)

Back to pointers (2) Les pointeurs en Pascal sont bien définis. p 17 value(p) = value(p^) = 17 Notez que comme avec toute variable nommée, quand on a: p^ : = 23; On veut dire l‘adresse de p^ (la valeur de p). Et quand on a: m : = p^; On veut dire la valeur de p^. 41

Création de variables de type pointeur Une variable pointeur est déclarée explicitement et possède

Création de variables de type pointeur Une variable pointeur est déclarée explicitement et possède la porté et la durée de vie habituelle. Une variable anonyme n’a pas de porté (car elle n’a pas de nom) et sa durée de vie est déterminée par le programmeur. Elle est créée (dans une mémoire spéciale appelée le tas « heap » ) par exemple: new(p); en Pascal p = malloc(4); en C et détruite par le programmeur: dispose(p); en Pascal free(p); en C 42

Pointer (2) Si une variable anonyme existe à l’extérieur de la porte de la

Pointer (2) Si une variable anonyme existe à l’extérieur de la porte de la variable pointeur pointant sur celle-ci, on a un déchet (un objet inaccessible). Si une variable anonyme est détruite à l’intérieur de la porté du pointeur, on a une référence pendante « dangling reference » . new(p); p^ : = 23; dispose(p); . . . if p^ > 0 {? ? ? } 43

Pointer (2) Produire des déchets, un exemple en Pascal: new(p); p^ : = 23;

Pointer (2) Produire des déchets, un exemple en Pascal: new(p); p^ : = 23; new(p); {la variable anonyme ayant comme valeur 23 devient inaccessible} La collecte des déchets est le processus qui libère la mémoire inaccessible. Elle est habituellement complexe et coûteux. Elle est essentiel pour les langages dont l’implémentation dépend de pointeurs : Lisp, Prolog. 44

Pointeurs: types et opérateurs Les pointers en PL/I n’ont pas de type. En Pascal,

Pointeurs: types et opérateurs Les pointers en PL/I n’ont pas de type. En Pascal, Ada, C ils sont déclares comme pointeurs à des types, ainsi, un pointeur déréférencé (p^ ou *p) possède un type fixe. Il y a plusieurs opérations sur les pointeurs en C: char b, c; c = '07'; b = *((&c - 1) + 1); putchar(b); 45