Tableau Deux Dimensions
Tableau Deux Dimensions
Tableau Deux Dimensions
Le réusinage est ?
Réusinage de code (refactoring)
Le réusinage est ?
• le processus de restructuration d’un programme :
• en modifiant son design,
• en modifiant sa structure,
• en modifiant ses algorithmes
• mais en conservant ses fonctionalités.
Réusinage de code (refactoring)
Le réusinage est ?
• le processus de restructuration d’un programme :
• en modifiant son design,
• en modifiant sa structure,
• en modifiant ses algorithmes
• mais en conservant ses fonctionalités.
Avantages ?
Réusinage de code (refactoring)
Le réusinage est ?
• le processus de restructuration d’un programme :
• en modifiant son design,
• en modifiant sa structure,
• en modifiant ses algorithmes
• mais en conservant ses fonctionalités.
Avantages ?
• Amélioration de la lisibilité,
• Amélioration de la maintenabilité,
• Réduction de la complexité.
Réusinage de code (refactoring)
Le réusinage est ?
• le processus de restructuration d’un programme :
• en modifiant son design,
• en modifiant sa structure,
• en modifiant ses algorithmes
• mais en conservant ses fonctionalités.
Avantages ?
• Amélioration de la lisibilité,
• Amélioration de la maintenabilité,
• Réduction de la complexité.
Le réusinage est ?
• le processus de restructuration d’un programme :
• en modifiant son design,
• en modifiant sa structure,
• en modifiant ses algorithmes
• mais en conservant ses fonctionalités.
Avantages ?
• Amélioration de la lisibilité,
• Amélioration de la maintenabilité,
• Réduction de la complexité.
Exercice :
• Réusiner le code se trouvant sur Cyberlearn.
Tableau à deux dimensions (1/4)
indices 0 1 2 3
0 7 4 7 3
1 2 2 9 2
2 4 8 8 9
Syntaxe
int tab[3][4]; // déclaration d'un tableau 4x3
tab[2][1]; // accès à la case 2, 1
tab[2][1] = 14; // assignation de 14 à la position 2, 1
Tableau à deux dimensions (3/4)
Exercice : déclarer et initialiser aléatoirement un tableau 50x100
Tableau à deux dimensions (3/4)
Exercice : déclarer et initialiser aléatoirement un tableau 50x100
#define NX 50
#define NY 100
int tab[NX][NY];
for (int i = 0; i < NX; ++i) {
for (int j = 0; j < NY; ++j) {
tab[i][j] = rand() % 256; // 256 niveaux de gris
}
}
Attention
• Les éléments ne sont jamais initialisés.
• Les bornes ne sont jamais vérifiées.
int tab[3][2] = { {1, 2}, {3, 4}, {5, 6} };
printf("%d\n", tab[2][1]); // affiche?
printf("%d\n", tab[10][9]); // affiche?
printf("%d\n", tab[3][1]); // affiche?
La couverture de la reine
0 1 2 3 4 5
0 * * *
1 * * *
2 * * R * * *
3 * * *
4 * * *
Exercice
• En utilisant les conditions, les tableaux à deux dimensions, et des
char uniquement.
• Implémenter un programme qui demande à l’utilisateur d’entrer les
coordonnées de la reine et affiche un tableau comme ci-dessus pour
un échiquier 8x8.
Types énumérés (1/2)
• Le nombre 247.
Nombres décimaux : Les nombres en base 10
• Le nombre 11110111.
Nombres binaires : Les nombres en base 2
27 26 25 24 23 22 21 20
1 1 1 1 0 1 1 1
1 ⋅ 27 + 1 ⋅ 2 6 + 1 ⋅ 2 5 + 1 ⋅ 2 4 + 0 ⋅ 2 3 + 1 ⋅ 2 2 + 1 ⋅ 2 1 + 1 ⋅ 2 0
Représentation des nombres (2/2)
• Le nombre 11110111.
Nombres binaires : Les nombres en base 2
27 26 25 24 23 22 21 20
1 1 1 1 0 1 1 1
1 ⋅ 27 + 1 ⋅ 2 6 + 1 ⋅ 2 5 + 1 ⋅ 2 4 + 0 ⋅ 2 3 + 1 ⋅ 2 2 + 1 ⋅ 2 1 + 1 ⋅ 2 0
= 247.
Conversion de décimal à binaire (1/2)
Convertir 11 en binaire ?
Conversion de décimal à binaire (1/2)
Convertir 11 en binaire ?
• On décompose en puissances de 2 en partant de la plus grande
possible
11 / 8 = 1, 11 % 8 = 3
3 / 4 = 0, 3 % 4 = 3
3 / 2 = 1, 3 % 2 = 1
1 / 1 = 1, 1 % 1 = 0
• On a donc
1011 ⇒ 1 ⋅ 23 + 0 ⋅ 22 + 1 ⋅ 21 + 1 ⋅ 20 = 11.
Conversion de décimal à binaire (2/2)
Algorithme
1. Initialisation
num = 247
while (2^N < num) {
N += 1
}
Conversion de décimal à binaire (2/2)
Algorithme
1. Initialisation
num = 247
while (2^N < num) {
N += 1
}
2. Boucle
while (N >= 0) {
bit = num / 2^N
num = num % 2^N
N += 1
}
Les additions en binaire
1101 8+4+0+1 = 13
+ 0110 + 0+4+2+0 = 6
------- -----------------
10011 16+0+0+2+1 = 19
• Les entiers sur un ordinateur ont une précision fixée (ici 4 bits).
1101 8+4+0+1 = 13
+ 0110 + 0+4+2+0 = 6
------- -----------------
10011 16+0+0+2+1 = 19
• Les entiers sur un ordinateur ont une précision fixée (ici 4 bits).
(1111)2 = 8 + 4 + 2 + 1 = 15
(1111)2 = 8 + 4 + 2 + 1 = 15
(0000)2 = 0 + 0 + 0 + 0 = 0
(1111)2 = 8 + 4 + 2 + 1 = 15
(0000)2 = 0 + 0 + 0 + 0 = 0
0 et 2𝑁 − 1.
(1111)2 = 8 + 4 + 2 + 1 = 15
(0000)2 = 0 + 0 + 0 + 0 = 0
0 et 2𝑁 − 1.
4294967295
Les multiplications en binaire (1/2)
1101 13
* 0110 * 6
--------- --------------
0000 78
11010
110100
+ 0000000
--------- --------------
1001110 64+0+0+8+4+2+0
Les multiplications en binaire (2/2)
Solution naïve :
• On ajoute un bit de signe (le bit de poids fort) :
00000010: +2
10000010: -2
Problèmes ?
Entiers signés (1/2)
Solution naïve :
• On ajoute un bit de signe (le bit de poids fort) :
00000010: +2
10000010: -2
Problèmes ?
• Il y a deux zéros (pas trop grave) : 10000000 et 00000000
• Les additions différentes que pour les non-signés (très grave)
00000010 2
+ 10000100 + -4
---------- ----
10000110 = -6 != -2
Entiers signés (2/2)
Beaucoup mieux
• Complément à un :
• on inverse tous les bits : 1001 => 0110.
11111011
+ 00000001
----------
11111100
Le complément à 2 (1/2)
Questions :
• Comment on écrit +0 et -0 ?
• Comment calcule-t-on 2 + (-4) ?
• Quel est le complément à 2 de 1000 0000 ?
Le complément à 2 (1/2)
Questions :
• Comment on écrit +0 et -0 ?
• Comment calcule-t-on 2 + (-4) ?
• Quel est le complément à 2 de 1000 0000 ?
Réponses
• Comment on écrit +0 et -0 ?
+0 = 00000000
-0 = 11111111 + 00000001 = 100000000 => 00000000
• Comment calcule-t-on 2 + (-4) ?
00000010 2
+ 11111100 + -4
---------- -----
11111110 -2
• En effet
11111110 => 00000001 + 00000001 = 00000010 = 2.
Le complément à 2 (1/2)
−2𝑁−1 ...2𝑁−1 − 1.
Fractions
• Numérateur : int num ;
• Dénominateur : int denom.
Addition
int num1 = 1, denom1 = 2;
int num2 = 1, denom2 = 3;
int num3 = num1 * denom2 + num2 * denom1;
int denom3 = denom1 * denom2;
Simplifications
• typedef permet de définir un nouveau type.
typedef unsinged int uint;
typedef struct fraction fraction_t;
typedef struct fraction {
int32_t num, denom;
} fraction_t;
Pointeurs
• Comme pour tout type, on peut avoir des pointeurs vers un struct.
• Les champs sont accessible avec le sélecteur ->
fraction_t *frac; // on crée un pointeur
frac->num = 1; // seg fault...
frac->denom = -1; // mémoire pas allouée.
fraction_t
num denom
fraction_t *frac;
Initialisation
• Avec le passage par référence on peut modifier un struct en place.
• Les champs sont accessible avec le sélecteur ->
void fraction_init(fraction_t *frac,
int32_t re, int32_t im)
{
// frac a déjà été allouée
frac->num = frac;
frac->denom = denom;
}
int main() {
fraction_t frac; // on alloue une fraction
fraction_init(&frac, 2, -1); // on l'initialise
}
Types composés : struct (6/6)
• Refactorisation
• Tris et complexité
• Récursivité