UE MAREP Cours 9 : Tableaux Patricia Renault UPMC 2005/2006
Plan Introduction Implantation d’un tableau à 1 dimension Implantation d’un tableau à 2 dimensions Utilisations de tableaux
Plan Introduction Implantation d’un tableau à 1 dimension Structure d’un tableau Implantation d’un tableau à 1 dimension Implantation d’un tableau à 2 dimensions Utilisations de tableaux
Structure d’un tableau Un tableau est une structure de données regroupant en une même entité un ensemble d’éléments de même type. Cet ensemble est ordonné : les éléments stockés sont munis d’un numéro, ou indice, donnant leur position dans le tableau. L’accès à un élément du tableau se fait en désignant son indice. T[i] désigne l’élément i du tableau T.
Plan Introduction Implantation d’un tableau à 1 dimension Cas général Exemples Implantation d’un tableau à 2 dimensions Utilisations de tableaux
Cas général D’un point de vue abstrait, l’accès à l’élément i d’un tableau T peut être vu comme un appel à une fonction qui renvoie le ième élément du tableau T, indépendamment de la façon dont le tableau est représenté en mémoire. En pratique, le tableau est implanté d’un seul tenant en mémoire. Les éléments sont rangés en mémoire les uns à la suite des autres, du premier au dernier.
Cas général La zone mémoire attribuée à un tableau est définie par : l’adresse de début d’implantation du tableau, la taille (en octets) des éléments stockés, le nombre d’éléments stockés. L’expression T[i] correspond au contenu de la case mémoire (ou des cases mémoire) du ième élément du tableau. On peut repérer l’adresse de celui-ci à partir de l’adresse du premier élément du tableau, la taille des éléments du tableau, et la position i : T[i] = contenu de l’élément d’adresse : adresse_début + i * (taille des éléments)
Exemples Soit la variable globale T int T[5] = {2, -1, 3, 8, 7} Représentation de la mémoire. Hypothèse : l’adresse de début du tableau T est 0x1000 0004 Directive assembleur pour déclarer le tableau T : .data T : .word 2, -1, 3, 8, 7 Où, par exemple, T[2] = contenu du mot d’adresse : T + 2 * (4) = 0x1000 0004 + 8 = 0x1000 000c T[2] = 8 2 -1 8 3 7 0x1000 0004 0x1000 0008 0x1000 000c 0x1000 0010 0x1000 00014
Exemples Soit la variable globale str : char *str = "Bonjour" Représentation de la mémoire. Hypothèse : l’adresse de début du tableau str est 0x1000 0010 str[3] = contenu du mot d’adresse : str + 3*(1) = 0x1000 0010 + 3 = 0x1000 0013 str[3] = 0x6A (code ascii de 'j') B o n j u r 0x1000 00010 0x1000 00011 0x1000 00012 0x1000 0013 0x1000 00014 0x1000 00015 0x1000 00016
Plan Introduction Implantation d’un tableau à 1 dimension Implantation d’un tableau à 2 dimensions Cas général Implantation en ligne Implantation en colonne Utilisations de tableaux
Cas général Un tableau à deux dimensions est implanté de façon contiguë en mémoire, ligne par ligne ou colonne par colonne (c’est une convention : il n’y a pas une implantation meilleure qu’une autre dans le cas général). e11 … e1N eM1 eMN
Implantation en ligne Implantation ligne par ligne d’un tableau de taille M * N L’adresse de la case (i,j) est donnée par la relation : adresse_debut + i * N * taille_élément + j * taille_élément e11 … e1N e21 e2N eM1 eMN ligne 1 ligne 2 … ligne M
Implantation en colonne Implantation colonne par colonne d’un tableau de taille M * N L’adresse de la case (i,j) est donnée par la relation : adresse_debut + j * M * taille_élément + i * taille_élément e11 … eM1 e12 eM2 e1N eMN colonne 1 colonne 2 … colonne M
Plan Introduction Implantation d’un tableau à 1 dimension Implantation d’un tableau à 2 dimensions Utilisations de tableaux Image 4*4 Table d’adresses Fonction récursive et tableaux
Image 4*4 Une image est représentée par un tableau de pixels. Chaque pixel est caractérisé par la proportion des couleurs élémentaires qui constituent sa couleur (proportion de rouge, proportion de vert, proportion de bleu). La proportion est représentée par un nombre entier naturel codé sur un octet. Voici quelques exemples : R=0, V=0, B=0 R=128, V=0, B=0 R=254, V=0, B=0 Pour renforcer la teinte d’une image, on change les proportions relatives des couleurs élémentaires.
Image 4*4 int main() { int i, j; for (i=0; i<4; i++){ for (j=0; j<4; j++){ image[i][j].R= image[i][j].R + 126; } exit(0);
Image 4*4 .data image : .byte 0,0,0, 128,0,0, 128,0,0, 0,0,0 # chaque ligne représente 4 pixels codés chacun (R, V, B) .stack
Image 4*4 .text __start : #$5:i, $6:j, $7:4 #$9:image,$10:taill elem 3 lui $9, image>>16 ori $9, $9,image&0xFFFF ori $7, $0, 4 ori $10, $0, 3 xor $5, $5, $5 for1 : slt $8, $5, $7 #1si i<4 beq $8, $0, finfor1 xor $6, $6, $6 for2 : slt $8, $6, $7 #1si j<4 beq $8, $0, finfor2 mult $5, $7 mflo $8 mult $8, $10 add $8, $9, $8 mult $6, $10 mflo $11 add $8, $8, $11
Image 4*4 Pour accéder à la composante verte : 1($8) lb $11, ($8) # chargement de la composante rouge addiu $11, $11, 126 sb $11, ($8) # sauvegarde de la composante rouge addi $6, $6, 1 j for2 finfor2 : addi $5, $5, 1 j for1 finfor1 : ori $2, $0, 10 syscall Pour accéder à la composante verte : 1($8) Pour accéder à la composante bleue : 2($8)
Image 4*4
Table d’adresses Soit la structure alternative suivante : switch (i) { case 1 : /* cas 1 */break; case 2 : /* cas 2 */break; case 3 : /* cas 3 */break; default : /* cas autre */ }
Table d’adresses .data table_switch : .word cas_1, cas_2, cas_3, cas_autre # cas_1, cas_2, cas_3 et cas_autre sont des étiquettes # d’instructions du programme .text cas_1 : … j apres_le_switch cas_2 : … cas_3 : … cas_autre : … __start :
Fonction récursive et tableaux int palin(char tab[], int i, int j){ if (i>=j) return 1; if (tab[i] == tab[j]) return palin(tab, i+1, j-1); return 0; } char tab[] = "esoiioae"; int main(){ int val ; val = palin(tab,0,7); printf("%x\n",val); exit(0);
Fonction récursive et tableaux .data val : .word tab : .ascii "esoiioae" .stack 512 .text __start : lui $3, tab >> 16 ori $3, $3, tab & 0xFFFF# $3 contient l'adresse tab ori $4, $0, 7 # $4 contient 22 addiu $29,$29,-12 # empiler 3 arguments sw $4, 8($29) # empile la valeur 22 sw $0, 4($29) # empile la valeur 0 sw $3, ($29) # empile l'adresse tab jal palin addiu $29, $29, 12 # detruit les arguments
Fonction récursive et tableaux lui $3,val >> 16 ori $3, $3, val & 0xFFFF # $3 contient adr val sw $2, ($3)# range le resultat de palin dans val ori $4, $2, 0 ori $2, $0, 1 syscall ori $2, $0, 10
Fonction récursive et tableaux palin : # 5 registres + $31 addiu $29, $29, -24 sw $31, 20($29) sw $3, 16($29) sw $4, 12($29) sw $5, 8($29) sw $6, 4($29) sw $7, ($29) lw $3, 24($29) # $3 contient tab lw $4, 28($29) # $4 contient i lw $5, 32($29) # $5 contient j slt $6, $5, $4 # $6 = 1 si j <i beq $6, $0, branche_2
Fonction récursive et tableaux branche_1 : ori $2, $0, 1 j fin_fonction branche_2 : add $6, $4 , $3# adresse ième mot de tab lb $6, ($6) # $4 contient tab[i] addu $7, $5, $3 lb $7, ($7) # $5 contient tab[j] bne $6, $7, branche_3 addi $4, $4, +1 # i <- i+1 addi $5, $5, -1 # j <- j-1 addiu $29, $29, -12 sw $5, 8($29) sw $4, 4($29) sw $3, ($29) jal palin
Fonction récursive et tableaux addiu $29, $29, 12 j fin_fonction branche_3 : or $2, $0, $0 fin_fonction : lw $31, 20($29) lw $3, 16($29) lw $4, 12($29) lw $5, 8($29) lw $6, 4($29) lw $7, ($29) addiu $29, $29, 24 jr $31