-
orestis.malaspin authoredorestis.malaspin authored
- Qu'est-ce qu'un algorithme?
- Définition informelle (recette)
- Histoire et étymologie
- Définition formelle
- Notions de base d'algorithmique
- Variable
- Séquence d'instructions / expressions
- Algorithme de vérification qu'un nombre est premier (1/3)
- Algorithme naïf (problème)
- Pas vraiment un algorithme: pas une séquence ordonnée et bien définie
- Problème: Comment écrire ça sous une forme algorithmique?
- Algorithme de vérification qu'un nombre est premier (2/3)
- Algorithme naïf (une solution)
- Algorithme de vérification qu'un nombre est premier (3/3)
- Algorithme naïf (une solution en C)
- Exercice: Comment faire plus rapide?
- Génération d'un exécutable
- La simplicité de C?
- 32 mots-clé et c'est tout
- Déclaration et typage
- Les variables (1/2)
- Variables et portée
- Les variables (2/2)
- Exemple
- Quiz: compile ou compile pas?
- Quiz: compile ou compile pas
- Types de base (1/4)
- Numériques
- Types de base (2/4)
- Prenez l'habitude d'utiliser ces types-là!
- Types de base (3/4)
- Booléens
- Quiz: booléens
- Quiz: booléens
- Types de base (4/4)
- Conversions
- Quiz: conversions
- Quiz: conversions
title: "Introduction aux algorithmes I"
date: "2024-09-16"
Qu'est-ce qu'un algorithme?
Définition informelle (recette)
- des entrées (les ingrédients, le matériel utilisé) ;
- des instructions élémentaires simples (frire, flamber, etc.), dont les exécutions dans un ordre précis amènent au résultat voulu ;
- un résultat : le plat préparé.
. . .
Histoire et étymologie
- Existent depuis 4500 ans au moins (algorithme de division, crible d'Eratosthène).
- Le mot algorithme est dérivé du nom du mathématicien perse Muḥammad ibn Musā al-Khwārizmī, qui a été "latinisé" comme Algoritmi.
. . .
Définition formelle
En partant d'un état initial et d'entrées (peut-être vides), une séquence finie d'instruction bien définies (ordonnées) implémentables sur un ordinateur, afin de résoudre typiquement une classe de problèmes ou effectuer un calcul.
Notions de base d'algorithmique
Variable
. . .
- Paire: identifiant - valeur (assignation);
Séquence d'instructions / expressions
. . .
- Opérateurs (arithmétiques / booléens)
- Boucles;
- Structures de contrôle;
- Fonctions;
Algorithme de vérification qu'un nombre est premier (1/3)
Nombre premier: nombre possédant deux diviseurs entiers distincts.
. . .
Algorithme naïf (problème)
booléen est_premier(nombre)
si
pour tout i, t.q. 1 < i < nombre
i ne divise pas nombre
alors vrai
sinon faux
. . .
Pas vraiment un algorithme: pas une séquence ordonnée et bien définie
. . .
Problème: Comment écrire ça sous une forme algorithmique?
Algorithme de vérification qu'un nombre est premier (2/3)
Algorithme naïf (une solution)
booléen est_premier(nombre) // fonction
soit i = 2 // variable, type, assignation
tant que i < nombre // boucle
si nombre modulo i == 0 // expression typée
retourne faux // expression typée
i = i + 1
retourne vrai // expression typée
Algorithme de vérification qu'un nombre est premier (3/3)
Algorithme naïf (une solution en C)
bool est_premier(int nombre) {
int i; // i est un entier
i = 2; // assignation i à 2
while (i < nombre) { // boucle avec condition
if (0 == nombre % i) { // is i divise nombre
return false; // i n'est pas premier
}
i = i + 1; // sinon on incrémente i
}
return true;
}
. . .
Exercice: Comment faire plus rapide?
Génération d'un exécutable
-
Pour pouvoir être exécuté un code C doit être d'abord compilé (avec
gcc
ouclang
). -
Pour un code
prog.c
la compilation "minimale" est$ gcc prog.c $ ./a.out # exécutable par défaut
-
Il existe une multitude d'options de compilation:
$ gcc -O1 -std=c11 -Wall -Wextra -g prog.c -o prog -fsanitize=address
-
-std=c11
utilisation de C11. -
-Wall et -Wextra
activation des warnings. -
-fsanitize=…
contrôles d’erreurs à l’exécution (coût en performance). -
-g
symboles de débogages sont gardés. -
-o
défini le fichier exécutable à produire en sortie. -
-O1
,-O2
,-O3
: activation de divers degrés d'optimisation
-
La simplicité de C?
32 mots-clé et c'est tout
auto
{.C} double
{.C} int
{.C} struct
{.C}
break
{.C} else
{.C} long
{.C} switch
{.C}
case
{.C} enum
{.C} register
{.C} typedef
{.C}
char
{.C} extern
{.C} return
{.C} union
{.C}
const
{.C} float
{.C} short
{.C} unsigned
{.C}
continue
{.C} for
{.C} signed
{.C} void
{.C}
default
{.C} goto
{.C} sizeof
{.C} volatile
{.C}
do
{.C} if
{.C} static
{.C} while
{.C}
Déclaration et typage
En C lorsqu'on veut utiliser une variable (ou une constante), on doit déclarer son type
const double two = 2.0; // déclaration et init.
int x; // déclaration (instruction)
char c; // déclaration (instruction)
x = 1; // affectation (expression)
c = 'a'; // affectation (expression)
int y = x; // déclaration et initialisation en même temps
int a, b, c; // déclarations multiples
a = b = c = 1; // init. multiples
Les variables (1/2)
Variables et portée
- Une variable est un identifiant, qui peut être liée à une valeur (un expression).
- Une variable a une portée qui définit où elle est visible (où elle peut être accédée).
- La portée est globale ou locale.
- Une variable est globale est accessible à tout endroit d'un programme et doit être déclarée en dehors de toute fonction.
- Une variable est locale lorsqu'elle est déclarée dans un bloc,
{...}
{.C}. - Une variable est dans la portée après avoir été déclarée.
Les variables (2/2)
Exemple
float max; // variable globale accessible partout
int foo() {
// max est visible ici
float a = max; // valide
// par contre les varibles du main() ne sont pas visibles
}
int main() {
// max est visible ici
int x = 1; // x est locale à main
{
// x est visible ici, y pas encore
// on peut par exemple pas faire x = y;
int y = 2;
} // y est détruite à la sortie du bloc
} // x est à la sortie de main
Quiz: compile ou compile pas?
Quiz: compile ou compile pas
Types de base (1/4)
Numériques
Type Signification (gcc pour x86-64)
char
{.C}, unsigned char
{.C} Entier signé/non-signé 8-bit
short
{.C}, unsigned short
{.C} Entier signé/non-signé 16-bit
int
{.C}, unsigned int
{.C} Entier signé/non-signé 32-bit
long
{.C}, unsigned long
{.C} Entier signé/non-signé 64-bit
float
{.C} Nombre à virgule flottante, simple précision
double
{.C} Nombre à virgule flottante, double précision
La signification de short
{.C}, int
{.C}, ... dépend du compilateur et de l'architecture.
Types de base (2/4)
Voir <stdint.h>
pour des représentations portables
Type Signification
int8_t
{.C}, uint8_t
{.C} Entier signé/non-signé 8-bit
int16_t
{.C}, uint16_t
{.C} Entier signé/non-signé 16-bit
int32_t
{.C}, uint32_t
{.C} Entier signé/non-signé 32-bit
int64_t
{.C}, uint64_t
{.C} Entier signé/non-signé 64-bit
. . .
Prenez l'habitude d'utiliser ces types-là!
Types de base (3/4)
Booléens
- Le ANSI C n'offre pas de booléens.
- L'entier
0
{.C} signifie faux, tout le reste vrai. - Depuis C99, la librairie
stdbool
met à disposition un typebool
{.C}. - En réalité c'est un entier:
-
1 \Rightarrow
true
{.C} -
0 \Rightarrow
false
{.C}
-
- On peut les manipuler comme des entier (les sommer, les multiplier, ...).
Quiz: booléens
Quiz: booléens
Types de base (4/4)
Conversions
- Les conversions se font de manière:
- Explicite:
int a = (int)2.8; double b = (double)a; int c = (int)(2.8+0.5);
- Implicite:
int a = 2.8; // warning, si activés, avec clang double b = a + 0.5; char c = b; // pas de warning... int d = 'c';
- Explicite: