Skip to content
Snippets Groups Projects
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 ou clang).

  • 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 
    1. -std=c11 utilisation de C11.
    2. -Wall et -Wextra activation des warnings.
    3. -fsanitize=… contrôles d’erreurs à l’exécution (coût en performance).
    4. -g symboles de débogages sont gardés.
    5. -o défini le fichier exécutable à produire en sortie.
    6. -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 type bool{.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';

Quiz: conversions

Quiz: conversions