Principes des Langages de programmation

John Samuel

CPE Lyon

Année: 2026-2027
Courriel: john.samuel@cpe.fr

Creative Commons License

1.1. Contexte et objectifs

Questions

Comment déciderez-vous du langage de programmation à utiliser pour votre travail ?

1.1. Contexte et objectifs

Questions

Donnez des exemples de logiciels écrits en :

1.1. Contexte et objectifs

Les logiciels écrits en langage C

  1. Noyau Linux: https://github.com/torvalds/linux
  2. GCC: https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git
  3. GIT: https://git.kernel.org/pub/scm/git/git.git/
  4. Apache HTTP Server: https://github.com/apache/httpd
  5. Python: https://github.com/python/cpython

1.1. Contexte et objectifs

Les logiciels écrits en langage Python

  1. Pandas : Pandas est une bibliothèque puissante pour la manipulation et l’analyse de données, souvent utilisée comme fondation pour les flux de travail de science des données.
  2. Scikit-learn : Scikit-learn est l’une des bibliothèques d’apprentissage automatique les plus populaires en Python, offrant des implémentations efficaces et précises de divers algorithmes.
  3. Django : Django est un framework web de haut niveau qui fournit une manière élégante et évolutivité pour construire des applications web complexes.
  4. Flask : Flask est un autre framework web populaire qui excelle dans la construction d’applications web à petite échelle avec un minimum de surcharge.
  5. SciPy : SciPy est une bibliothèque complète pour les applications scientifiques et d’ingénierie, fournissant des fonctions pour des tâches comme le traitement du signal, la résolution de problèmes linéaires…

1.1. Contexte et objectifs

Les logiciels écrits en langage Java

  1. Applications Android : le cadriciel applicatif et la plupart des applications sont écrits en Java et en Kotlin (le noyau et les couches basses restent en C et C++).
  2. IntelliJ IDEA, Eclipse : environnements de développement intégrés (IDE) écrits en Java.
  3. Tomcat : Un logiciel de serveur web populaire qui alimente de nombreux sites web.
  4. Apache Kafka : Une plateforme de streaming distribuée pour construire des pipelines de données en temps réel.
  5. Spring Framework : Un cadre populaire pour la création d’applications d’entreprise.

1.1. Contexte et objectifs

Les logiciels écrits en langage Rust

  1. Navigateur Firefox : Mozilla utilise activement Rust pour construire les composants principaux du navigateur Firefox.
  2. Moteur de rendu Servo : moteur de rendu web développé en Rust, aujourd'hui hébergé par la Linux Foundation.
  3. Noyau Linux : Rust est accepté depuis la version 6.1 pour l'écriture de pilotes, aux côtés du C.
  4. Outils en ligne de commande : ripgrep, fd, bat, uv — et Cargo, le gestionnaire de paquets de Rust lui-même.
  5. Infrastructure : Deno (exécution JavaScript/TypeScript), Pingora (Cloudflare), et des composants d'Android et de Windows.

1.1. Contexte et objectifs

Les logiciels écrits en langage Haskell

  1. Gestionnaire de fenêtres Xmonad : Xmonad, un gestionnaire de fenêtres open-source populaire, est construit avec Haskell.
  2. Compilateur GHC : GHC (Glasgow Haskell Compiler), l’implémentation standard du langage de programmation Haskell, est également écrit en Haskell.
  3. Système de contrôle de version Darcs : Darcs, un système de contrôle de version distribué, a été initialement développé avec Haskell.
  4. Framework web Yesod : Yesod, un framework web open-source populaire, a été construit sur Haskell.

1.1. Contexte et objectifs

Objectifs

1.2. Langages de programmation

Langage de programmation

Un langage de programmation est un ensemble de règles, de syntaxe et de sémantique utilisés pour communiquer des instructions à un ordinateur. Il permet aux développeurs d’écrire du code qui peut être exécuté par l’ordinateur, réalisant ainsi des tâches spécifiques ou résolvant des problèmes.

Composants clés :

  1. Syntaxe : Les règles qui régissent la façon dont le code doit être écrit, y compris la ponctuation, l’indentation et la mise en forme.
  2. Sémantique : La signification des éléments individuels, tels que les mots-clés, les variables et les opérateurs.
  3. Variables : Des conteneurs pour stocker des valeurs, qui peuvent être manipulées à l’aide de diverses opérations.

1.2. Langages de programmation

Langage de programmation

Composants clés :

  1. Types de données : Des catégories de données, telles que des entiers, des flottants, des chaînes de caractères ou des booléens, qui déterminent le type de valeur stockée.
  2. Opérateurs : Des symboles utilisés pour effectuer des opérations arithmétiques, logiques ou d’affectation sur les variables et les données.
  3. Instructions de contrôle de flux : Des mots-clés qui contrôlent le flux d’exécution dans un programme, tels que les instructions if-else, les boucles (for, while) ou les instructions conditionnelles (switch).
  4. Fonctions : Des blocs de code réutilisables qui effectuent des tâches spécifiques, souvent en prenant des arguments et en renvoyant des valeurs.

1.2. Langages de programmation

Langage de programmation

Caractéristiques :

  1. Syntaxe lisible par l’homme : Les langages de programmation sont conçus pour être lus et compris par les humains.
  2. Instructions exécutables : Le code est compilé ou interprété en langage machine que l’ordinateur peut exécuter directement.
  3. Abstraction : Les langages de programmation abstraient les détails de bas niveau, permettant aux développeurs de se concentrer sur la logique et les algorithmes de haut niveau.
  4. Expressivité : Un bon langage de programmation devrait permettre aux développeurs d’exprimer des idées et des solutions complexes de manière claire et concise.

1.2. Langages de programmation

Langue naturelle, langage formel

Un langage formel a une grammaire non ambiguë et une sémantique définie : un programme correct a une seule interprétation. Une langue naturelle n'a ni l'une ni l'autre.

Consigne : « la position du plus grand élément d'un tableau »

/* lecture A : la première position */
size_t argmax(int t[], size_t n) {
  size_t p = 0;
  for (size_t i = 1; i < n; i++)
    if (t[i] > t[p]) p = i;
  return p;
}
/* lecture B : la dernière position */
size_t argmax(int t[], size_t n) {
  size_t p = 0;
  for (size_t i = 1; i < n; i++)
    if (t[i] >= t[p]) p = i;
  return p;
}

Un seul caractère les sépare, et la phrase ne permet pas de choisir — pas plus qu'elle ne dit quoi renvoyer si n vaut 0. Une consigne n'est pas une spécification.

1.3. Histoire

Chronologie des langages de programmation

1.3. Histoire

Les langages de programmation du futur

L'émergence de modèles d'intelligence artificielle multilingues marque un jalon important dans l'évolution de la programmation. À mesure que ces modèles élargissent leurs capacités linguistiques, ils rendent plus visible la relation entre langues naturelles, langages formels et vérification du code.

The hottest new programming language is English. Andrej Karpathy, jan 24, 2023.

Human Languages as New Hot Programming Languages. J.S., October 4, 2023.

1.3. Histoire

Types de langages de programmation :

1.3. Histoire

Générations de langages de programmation :

  1. Langages de première génération : Les langages de programmation qui sont des langages de niveau machine utilisés pour programmer les premiers ordinateurs de première génération. À l'origine, aucun traducteur n'était utilisé pour compiler ou assembler le langage de première génération.
  2. Langages de deuxième génération : Les langages assembleurs. développés pour les premiers ordinateurs électroniques.
  3. Langages de troisième génération : Fortran, COBOL, C, C++. - langages de programmation généraux qui abstraient les détails de bas niveau.
  4. Langages de quatrième génération : SQL, R. - conçu pour des domaines ou des tâches spécifiques, souvent avec un focus sur la manipulation et l’inférence de données.
  5. Langages de cinquième génération : Prolog, Mercury. - langages basés sur la résolution de problèmes en utilisant des contraintes données au programme, au lieu d’utiliser des algorithmes. Exemples incluent les langages de programmation basés sur les contraintes et la logique.

1.4. Langages de programmation : popularité

Indice TIOBE pour août 2026

L'indice TIOBE de la communauté de programmation, mis à jour une fois par mois, est un indicateur de la popularité des langages de programmation. Il mesure le volume de recherches sur le web, pas le code réellement écrit : c'est un classement parmi d'autres, à relire chaque année.

  1. Python
  2. C
  3. C++
  4. Java
  5. C#

1.4. Langages de programmation : popularité

Octoverse GitHub

Les langages de programmation les plus utilisés sur GitHub (2025), par nombre de contributeurs mensuels :

  1. TypeScript
  2. Python
  3. JavaScript
  4. Java
  5. C#

1.5. Langages de programmation : utilisation principale

L'utilisation principale

Développement web

Applications mobiles

1.5. Langages de programmation : utilisation principale

L'utilisation principale

Administration système, automatisation et scripting

Ces langages partagent une caractéristique : ils sont interprétés, à typage dynamique, et optimisés pour la rapidité d'écriture plutôt que pour la rapidité d'exécution.

1.5. Langages de programmation : utilisation principale

L'utilisation principale

Applications de bureau et jeux

Calcul scientifique

1.6. Langages de programmation : paradigmes

Paradigmes de programmation

1. Programmation fonctionnelle

Exemples : Haskell, OCaml, Lisp, Scheme

1.6. Langages de programmation : paradigmes

Paradigmes de programmation

2. Programmation orientée objet (POO)

Exemples : Java, C++, Python, Ruby

1.6. Langages de programmation : paradigmes

Paradigmes de programmation

3. Programmation impérative — comment

Exemples : C, Fortran, langages assembleur

1.6. Langages de programmation : paradigmes

Paradigmes de programmation

4. Programmation déclarative — quoi

Exemples : Prolog, SQL

1.6. Langages de programmation : paradigmes

Paradigmes de programmation

5. Programmation orientée aspect (POA)

Exemples : AspectJ, Spring AOP

1.6. Langages de programmation : paradigmes

Paradigmes de programmation

6. Langages spécifiques à un domaine (DSL)

Exemples : SQL, HTML, CSS, LaTeX, Make

1.6. Langages de programmation : paradigmes

Paradigmes de programmation

7. Programmation pilotée par les événements

Exemples : JavaScript (navigateur, Node.js), interfaces graphiques (Qt, Swing)

1.6. Langages de programmation : paradigmes

Paradigmes de programmation

8. Programmation pilotée par les types

Exemples : Haskell, Rust, Kotlin, TypeScript

1.6. Langages de programmation : paradigmes

Paradigmes de programmation

9. Types dépendants et programmation certifiée

Exemples : Idris, Agda, Coq, Lean

1.6. Langages de programmation : paradigmes

Paradigmes de programmation

Tendances émergentes

  1. Conception orientée concurrence : les langages modernes intègrent la concurrence dans leur conception même, pour permettre d'écrire du code parallélisable sans erreurs de partage.
  2. Sûreté garantie par les types : la correction des types et la sûreté mémoire deviennent des critères de conception de premier plan (Rust, Swift, Go).
  3. Test basé sur les propriétés : les cas de test sont engendrés à partir de propriétés déclarées, pour couvrir un espace de comportements plus large qu'une liste d'exemples (QuickCheck, Hypothesis).
  4. Multiparadigme par défaut : les langages généralistes empruntent aux autres paradigmes (fonctions d'ordre supérieur en C++, filtrage par motif en Python, immuabilité en Java).

1.7. Langages de programmation de référence : C et Python

C

Le langage C est un langage de programmation :

Remarque: Pas de classes (Ce n'est pas un langage de programmation orienté-objet!!!)

Extensions de fichiers : .c, .h

1.7. Langages de programmation de référence : C et Python

1.7. Langages de programmation de référence : C et Python

Caractéristique Langage C Python
Paradigme de programmation Impératif, procédural Multiparadigme (impératif, orienté objet, fonctionnel)
Typage Statique (typage fort) Dynamique (typage fort). Les annotations de type (3.5+) ne sont pas vérifiées à l'exécution : un outil externe (mypy) est nécessaire
Syntaxe Syntaxe stricte et rigide Syntaxe simple et lisible
Performance Performant, optimisé pour les performances Moins performant, interprété
Gestion de la mémoire Besoin de gérer manuellement la mémoire Gestion automatique de la mémoire (ramasse-miettes)
Portabilité Portable, mais nécessite une compilation spécifique pour chaque plateforme Hautement portable grâce à son interpréteur

1.7. Langages de programmation de référence : C et Python

/* Fichier: bonjour1.c
* affiche 'Bonjour le Monde!!!' à l'écran.
* auteur: John Samuel
* Ceci est un commentaire sur plusieurs lignes
*/


#include <stdio.h> // headers

// Ceci est un commentaire sur une ligne
int main() {
  printf("Bonjour le Monde !!!");
  return 0;
}

Objectif : Ce code utilise des commentaires, inclut le fichier d'en-tête <stdio.h> pour l'utilisation de printf, définit la fonction main comme point d'entrée, utilise printf pour afficher un message, et renvoie 0 pour indiquer une exécution sans erreur.

1.7. Langages de programmation de référence : C et Python

/* Fichier: bonjour2.c
* affiche un message à l'écran en utilisant une variable
* auteur: John Samuel
* Ceci est un commentaire sur plusieurs lignes
*/


#include <stdio.h> // headers

int main() {
  int annee = 2026; //déclaration d'une variable
  printf("Bonjour le Monde!!! C'est l'année %d", annee);
  return 0;
}

Objectif : Ce code déclare une variable annee, utilise printf pour afficher un message incluant la valeur.

1.7. Langages de programmation de référence : C et Python

La compilation

$ gcc bonjour1.c

Pour voir tous les avertissements (*warnings*) pendant la compilation, vous pouvez utiliser les options -Wall et -Wextra.

$ gcc -Wall -Wextra -o bonjour bonjour2.c

L'exécution

$./a.out
Bonjour le Monde!!!

1.7. Langages de programmation de référence : C et Python

La compilation

$ gcc -o bonjour bonjour2.c

L'exécution

$./bonjour
Bonjour le Monde!!! C'est l'année 2026

1.7. Langages de programmation de référence : C et Python

# Ce programme affiche le message "Bonjour le monde !!!" à l'écran

# Définition de la fonction principale
def main():
    # Affichage du message
    print("Bonjour le monde !!!")

# Vérification si le script est exécuté directement (et non importé comme module)
if __name__ == "__main__":
    # Appel de la fonction principale
    main()

1.7. Langages de programmation de référence : C et Python

L'interpétation et l'exécution

$ python3 bonjour.py

Bonjour le monde!!!

1.7. Langages de programmation de référence : C et Python

C: Commentaires sur une ou plusieurs lignes

// Ceci est un commentaire sur une ligne (c99)

/* Ceci est un
 * commentaire sur
 * quatre lignes
 */

1.7. Langages de programmation de référence : C et Python

Python: Commentaires sur une ou plusieurs lignes

# Ceci est un commentaire sur une ligne

""" Ceci est un
  texte sur
  plusieurs lignes
"""

Attention : Python n'a pas de commentaire multiligne. Les triples guillemets délimitent une chaîne de caractères ; simplement, une chaîne seule sur une ligne est évaluée puis jetée. Placée en tête de module, de classe ou de fonction, elle devient la docstring accessible par help() et __doc__. Un vrai commentaire multiligne s'écrit avec un # par ligne.

1.8. Les types de données

C: les types de base

Les types de base en C sont les fondations sur lesquelles sont construites toutes les variables et données dans ce langage de programmation.

Types Mots clés Exemples
caractères char 'h', 'a', ...
entiers short, int, long, long long ...,-1,0,1,...
nombres en flottant float, double, long double 3.14, 3.14e23
énumérations enum ETUDIANT, STAGIAIRE

1.8. Les types de données

C: les types de base

Le choix de stocker des données en un octet, deux octets, quatre octets ou huit octets dépend principalement de la précision nécessaire pour représenter les données.

Un octet, deux octets, quatre octets ou huit octets

1.8. Les types de données

C: les types de base

Les types caractères et entiers

Types Mots-clés
caractère signed char, unsigned char
entier signed short, signed int, signed long, signed long long, unsigned short, unsigned int, unsigned long, unsigned long long

Remarque : La taille des types de base en C n'est pas standardisée car elle dépend de l'architecture matérielle sous-jacente du système sur lequel le code est exécuté, ce qui permet d'optimiser l'utilisation de la mémoire et les performances pour chaque plate-forme.

1.8. Les types de données

C - limits.h: L'intervalle minimum et maximum

L'intervalle minimum et maximum de types de base en utilisant limits.h

Mots clés Intervalle
signed char [SCHAR_MIN, SCHAR_MAX]
unsigned char [0, UCHAR_MAX]

1.8. Les types de données

C - limits.h: L'intervalle minimum et maximum

Mots clés Intervalle
(signed) short int [SHRT_MIN, SHRT_MAX]
unsigned short int [0, USHRT_MAX]
(signed) int [INT_MIN, INT_MAX]
unsigned int [0, UINT_MAX]
(signed) long [LONG_MIN, LONG_MAX]
unsigned long [0, ULONG_MAX]
(signed) long long [LLONG_MIN, LLONG_MAX]
unsigned long long [0, ULLONG_MAX]

1.8. Les types de données

C - float.h - l'intervalle minimum et maximum

L'intervalle minimum et maximum de types flottant en utilisant float.h

Mots clés Intervalle
float [FLT_MIN, FLT_MAX]
double [DBL_MIN, DBL_MAX]
long double [LDBL_MIN, LDBL_MAX]

1.8. Les types de données

Python: types de base

Les principaux types de données en Python :

  1. Entiers (int) : Les entiers sont des nombres entiers sans partie décimale. Par exemple : 1, 2, 3, etc.

  2. Flottants (float) : Les flottants sont des nombres à virgule flottante, c’est-à-dire des nombres avec une partie décimale. Par exemple : 3.14, -0.5, etc.

  3. Chaînes de caractères (str) : Les chaînes de caractères sont des séquences de caractères, telles que des mots ou des phrases. Elles sont délimitées par des guillemets simples ou doubles. Par exemple : “Bonjour”, ‘Bonjour’, etc.

  4. Booléens (bool) : Les booléens sont des valeurs logiques qui peuvent être soit True (vrai), soit False (faux).

1.8. Les types de données

Python: types de base

  1. Listes (list) : Les listes sont des collections ordonnées de valeurs qui peuvent être de n’importe quel type, y compris des listes imbriquées. Elles sont délimitées par des crochets et les éléments sont séparés par des virgules. Par exemple : [1, 2, 3], [“a”, “b”, “c”], etc.

  2. Tuples (tuple) : Les tuples sont des collections ordonnées de valeurs qui peuvent être de n’importe quel type, y compris des tuples imbriqués. Ils sont délimités par des parenthèses et les éléments sont séparés par des virgules. Par exemple : (1, 2, 3), (“a”, “b”, “c”), etc.

  3. Dictionnaires (dict) : Les dictionnaires sont des collections de paires clé-valeur, qui conservent l'ordre d'insertion depuis Python 3.7. Les clés sont uniques et les valeurs peuvent être de n’importe quel type. Les dictionnaires sont délimités par des accolades et les paires clé-valeur sont séparées par des virgules. Par exemple : {“nom”: “Jean”, “âge”: 30}, etc.

1.8. Les types de données

Python: types de base

  1. Ensembles (set) : Les ensembles sont des collections non ordonnées d’éléments uniques. Ils sont délimités par des accolades et les éléments sont séparés par des virgules. Par exemple : {1, 2, 3}, {“a”, “b”, “c”}, etc.

  2. Nombres complexes (complex) : Les nombres complexes sont des nombres qui ont une partie réelle et une partie imaginaire. Par exemple : 3 + 4j, -2 - 5j, etc.

1.9. Variables

C: Variables char

Les variables de type "char" en C sont utilisées pour stocker des caractères, mais elles peuvent également être modifiées avec les qualificateurs "signed" (signé) ou "unsigned" (non signé) pour déterminer si elles peuvent représenter des valeurs négatives (signées) ou uniquement des valeurs positives (non signées).

char my_char_var1 = 'a';
char my_char_var2 = -125;
unsigned char my_char_var3 = 225;

Remarque: Remarquez-bien l'utilisation de sous-tiret en nommant les variables

1.9. Variables

C: Variables

char my_char_var = 'a';
unsigned char my_uchar_var = 234;
short my_short_var = -12;
unsigned short my_ushort_var = 65535;
int my_int_var = 12;
unsigned int my_uint_var = 3456;
long my_long_var = -1234553L;
unsigned long my_ulong_var = 234556UL;
long long my_llong_var = 1123345LL;
unsigned long long my_ullong_var = 1234567ULL;
float my_float_var = 3.14;
double my_double_var = 3.14E-12;
long double my_long_double_var = 3.14E-22;

1.9. Variables

C: Énumérations

Les énumérations en C sont un moyen de définir un nouveau type de données personnalisé pour représenter un ensemble fini de valeurs entières nommées. Elles sont utiles pour rendre le code plus lisible et compréhensible.

enum status {ETUDIANT, STAGIAIRE}; // ETUDIANT = 0, STAGIAIRE = 1
enum status s = ETUDIANT;
enum status {ETUDIANT=1, STAGIAIRE}; // STAGIAIRE = 2
enum status {ETUDIANT=1, STAGIAIRE=14, ENSEIGNANT}; // ENSEIGNANT = 15
enum boolean {FAUX=0, VRAI};

Remarque: les constantes d'une enum sont de type int ; le type entier sous-jacent de l'énumération est choisi par le compilateur (C23 permet de l'imposer : enum status : unsigned char {...})

1.9. Variables

C: sizeof

sizeof (char) //type
sizeof (my_uchar_var) //variable
printf("sizeof(char): %zu\n", sizeof (char));
printf("sizeof(long long int): %zu\n", sizeof (long long int));
printf("sizeof(my_char_var): %zu\n", sizeof (my_char_var));

Remarque 1: sizeof donne la taille d'une variable en octets ou d'un type de données.

Remarque 2: La valeur retournée peut varier, mais la taille d'une variable de type caractère est de 1 octet.

Remarque 3: La valeur retournée est du type size_t, un entier non signé dont la largeur dépend de la plate-forme. Le code de conversion portable est "%zu" (C99) — pas "%lu", qui n'est correct que si size_t est exactement un unsigned long.

1.9. Variables

Python : sys.getsizeof()

L'objectif de la fonction sys.getsizeof() en Python est de retourner la taille en octets d'un objet spécifique. Cette fonction est utile pour connaître la taille mémoire d'un objet, ce qui peut être utile pour l'optimisation de la mémoire ou pour comprendre comment les objets sont stockés en mémoire.

1.9. Variables

Python : sys.getsizeof()

import sys

i = 10
f = 3.14159
s = "Bonjour"

# Affiche la taille en octets (varie en fonction de la plateforme)
print("Taille (int): ", sys.getsizeof(i)) # 28
print("Taille (float): ", sys.getsizeof(f)) # 24
print("Taille (str): ", sys.getsizeof(s)) # 56

1.9. Variables

Python : sys.getsizeof() et len()

len() est une fonction intégrée à Python qui retourne le nombre d'éléments dans un objet séquentiel, tel qu'une liste, un tuple, une chaîne de caractères, etc. Elle compte le nombre d'éléments dans l'objet, mais ne prend pas en compte la taille mémoire de l'objet lui-même.

import sys
# Création d'une liste avec 10 entiers
ma_liste = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Obtenir la longueur de la liste
longueur_liste = len(ma_liste)
print(longueur_liste)  # Affiche 10
# Obtenir la taille de la liste
taille_liste = sys.getsizeof(ma_liste)
print(taille_liste)  # Taille de la liste en octets (dépend de la plateforme)

1.9. Variables

Tableau

Les tableaux sont des structures de données permettant de stocker un ensemble de valeurs du même type sous un même nom, organisées de manière séquentielle.

1.9. Variables

Tableaux de tableaux

Les tableaux à deux indices sont des structures de données qui permettent de stocker des données dans une matrice rectangulaire.

Les tableaux à deux indices sont utiles pour stocker des données tabulaires, des images, des matrices, etc.

1.9. Variables

Tableaux de tableaux

Les tableaux à plusieurs indices sont des structures de données permettant de stocker des données dans des dimensions multiples.

Les tableaux à plusieurs indices sont utilisés pour stocker des données tridimensionnelles, telles que des voxels dans une image 3D, des matrices 3D, des jeux de données multidimensionnels, etc.

1.9. Variables

Déclaration: Tableaux de caractères

Pour déclarer un tableau, spécifiez le type des éléments qu'il contiendra, suivi du nom du tableau et de sa taille entre crochets.

par exemple

int tableau[5];

déclare un tableau d'entiers de taille 5.

char nom[20];

déclare un tableau de caractères (ou une chaîne de caractères) de taille 20.

Remarque: le langage C n'a pas de type nommé string : une chaîne est un tableau de char terminé par '\0'.

1.9. Variables

Déclaration: taille fixe

Les tableaux ont une taille fixe à la déclaration, qui ne peut pas être modifiée pendant l'exécution.

Exemple :

int itableau[20];
float ftableau[20];
double dtableau[20];

Objectif :

1.9. Variables

Initialisation: tableau à une dimension

Exemple :

int i;
int tableau[20];
for ( i = 0; i < 20; i++) {
 tableau[i] = i;
}

1.9. Variables

Initialisation: tableau à une dimension

Exemple :

int prix[5] = { 11, 12, 13, 14, 15 };
int chambres[] = { 301, 302, 303 };
char message[] = "Bonjour Le Monde!!";

Remarque: Nous n'avons pas écrit la taille de chambres, message

1.9. Variables

Initialisation: tableau à une dimension

Exemple :

int prix[5] = { 11, 12, 13, 14, 15 };
sizeof (prix) // 5 * sizeof(int)

1.9. Variables

Initialisation: tableau à une dimension

Exemple :

int chambres[] = { 301, 302, 303 };
sizeof (chambres) // 3 * sizeof(int)

1.9. Variables

Initialisation: tableau à une dimension

Exemple :

char message[] = "Bonjour Le Monde!!"; sizeof (message) // (18 + 1 pour le caractère nul '\0') * sizeof(char)

1.9. Variables

Tableaux à deux indices

int prix[2][2] = {
  {11, 12},
  {13, 14}
};
sizeof (prix) // 2 * 2 * sizeof(int)

1.9. Variables

Initialisation: Tableaux à deux indices

int chambres[][2] = {
  {201, 202},
  {301, 302}
};
sizeof (chambres) // 2 * 2 * sizeof(int)

Remarque: Nous n'avons pas précisé le nombre de lignes pour chambres.

1.9. Variables

Initialisation: Tableaux à deux indices

char message[2][11] = {"Bonjour", "Le Monde!!"};
sizeof (message) // 2 * 11 * sizeof(char)

1.10. Interactions avec l'utilisateur

Afficher à l'écran

printf("%d", my_int_var);
printf("%f", my_float_var);

1.10. Interactions avec l'utilisateur

Mots clés Code de conversion
char c
unsigned char hhu
short hd
unsigned short hu
int d, i
unsigned int u
long int ld
unsigned long int lu

1.10. Interactions avec l'utilisateur

Mots clés Code de conversion
long long int lld
unsigned long long int llu
float, double f, F, e, E, g, G, a, A
un float passé à printf est converti en double : les mêmes codes servent pour les deux
long double Lf, LF, Le, LE, Lg, LG
chaîne de caractères s

1.10. Interactions avec l'utilisateur

Caractère Code de conversion
Saut de ligne (nouvelle ligne) \n
Tabulation \t
Retour chariot \r

1.10. Interactions avec l'utilisateur

/* Fichier: addition.c
* affichage de la somme des nombres
* saisis par l'utilisateur */

#include <stdio.h> // en-têtes(headers)

int main(int argc, char ** argv) {
 int num1, num2;
 printf("Tapez numéro 1");
 scanf("%d", &num1);
 printf("Tapez numéro 2");
 scanf("%d", &num2);
 printf("La somme: %d\n", num1 + num2);
 return 0;
}

L'objectif de la fonction scanf est de permettre à un programme de lire et de stocker des données à partir de l'entrée standard (généralement le clavier) ou d'autres flux d'entrée, en fonction d'un format spécifié.

Remarque: Regardez l'opérateur &.

1.10. Interactions avec l'utilisateur

/* Fichier: addition.c
* affiche la somme de deux numéros
* saisis par l'utilisateur
* auteur: John Samuel
*/


#include <stdio.h> // en-têtes(headers)

int main(int argc, char ** argv) {
 int num1, num2;
 printf("Tapez deux numéros: ");
 scanf("%d %d", &num1, &num2);
 printf("La somme: %d\n", num1 + num2);
 return 0;
}

Remarque: Regardez l'opérateur &. L'opérateur & est utilisé pour obtenir l'adresse mémoire des variables num1 et num2, de sorte que les valeurs entrées par l'utilisateur puissent être stockées à ces emplacements en mémoire.

1.10. Interactions avec l'utilisateur

/* Fichier: bonjour5.c
* affiche un message à l'écran en utilisant scanf.
* auteur: John Samuel
*/


#include <stdio.h> // en-têtes(headers)

int main(int argc, char ** argv) {
 char nom[50];
 printf("Bonjour. Votre nom? ");
 // la largeur maximale est obligatoire :
 // sans elle une saisie longue déborde
 scanf("%49s", nom);
 printf("Bonjour %s!", nom);
 return 0;
}

Remarque: Regardez nom sans l'opérateur &. Lorsque vous utilisez la fonction scanf pour lire une chaîne de caractères à l'aide du format "%s", vous n'avez pas besoin d'inclure le symbole & devant la variable nom. La raison en est que nom est déjà un pointeur vers un tableau de caractères (c'est-à-dire un pointeur vers la première case mémoire du tableau), et scanf s'attend à recevoir l'adresse de la mémoire où stocker la chaîne de caractères. Par conséquent, nom en tant que pointeur fournit cette adresse.

1.10. Interactions avec l'utilisateur

Mots clés Code de conversion
char c
unsigned char hhu
short hd
unsigned short hu
int d, i
unsigned int u
long int ld
unsigned long int lu

1.10. Interactions avec l'utilisateur

Mots clés Code de conversion
long long int lld
unsigned long long int llu
float, double f, F, e, E, g, G, a, A
un float passé à printf est converti en double : les mêmes codes servent pour les deux
long double Lf, LF, Le, LE, Lg, LG
chaîne de caractères s

1.10. Interactions avec l'utilisateur

/* Fichier: fgets-message.c
* affichage d'une phrase entrée par un utilisateur
* la phrase peut contenir un espace
* auteur: John Samuel
*/


#include <stdio.h> // en-têtes(headers)

int main(int argc, char ** argv) {
 char message[50];
 printf("Tapez votre message: ");
 fgets(message, sizeof(message), stdin);
 printf("Votre message: %s\n", message);
 return 0;
}

Remarque: Regardez le paramètre stdin.La fonction fgets est utilisée pour lire une ligne de texte depuis l'entrée standard ( stdin) et stocker cette ligne dans la variable message. La taille du tampon de destination ( message) est spécifiée par sizeof(message), ce qui permet de garantir que la fonction ne lira pas plus de caractères que ce que le tampon peut contenir, évitant ainsi les dépassements de mémoire.

1.10. Interactions avec l'utilisateur

Unicode, UTF-8, UTF-16 (encodage)

Unicode

Unicode est un standard qui définit une manière unique de représenter les caractères de toutes les langues du monde. Il attribue un code unique à chaque caractère, appelé “point de code” ou “codepoint”. Unicode est utilisé pour représenter les caractères dans les ordinateurs, les téléphones et les autres appareils électroniques.

1.10. Interactions avec l'utilisateur

Unicode, UTF-8, UTF-16 (encodage)

UTF-8

UTF-8 (Unicode Transformation Format 8) est un encodage de caractères qui utilise une séquence variable de 1 à 4 octets pour représenter chaque caractère Unicode. UTF-8 est l’encodage le plus couramment utilisé pour les caractères sur Internet et est pris en charge par la plupart des systèmes d’exploitation et des langages de programmation.

Voici comment UTF-8 fonctionne :

1.10. Interactions avec l'utilisateur

Unicode, UTF-8, UTF-16 (encodage)

UTF-16

UTF-16 (Unicode Transformation Format 16) est un encodage à largeur variable : 2 ou 4 octets par caractère. UTF-16 est utilisé par les systèmes d’exploitation Windows et est pris en charge par de nombreux langages de programmation.

Voici comment UTF-16 fonctionne :

1.10. Interactions avec l'utilisateur

Unicode, UTF-8, UTF-16 (encodage)

UTF-16

Voici comment UTF-16 fonctionne :

1.10. Interactions avec l'utilisateur

Unicode, UTF-8, UTF-16 (encodage)

UTF-32

UTF-32 (Unicode Transformation Format 32) est un encodage de caractères qui utilise 4 octets pour représenter chaque caractère Unicode. UTF-32 est utilisé dans certains systèmes d’exploitation et est pris en charge par certains langages de programmation.

Voici comment UTF-32 fonctionne :

1.10. Interactions avec l'utilisateur

Unicode, UTF-8, UTF-16 (encodage)

Encodage/Décodage

L’encodage et le décodage sont des processus qui permettent de convertir des données entre différents formats. Dans le contexte des caractères, l’encodage consiste à convertir des caractères en une séquence de bits (0 et 1) qui peuvent être stockés ou transmis par un ordinateur. Le décodage est l’opération inverse, qui consiste à convertir une séquence de bits en caractères.

UTF-8 est l’encodage le plus couramment utilisé pour les caractères sur Internet, UTF-16 est utilisé par les systèmes d’exploitation Windows, et UTF-32 est utilisé dans certains systèmes d’exploitation et langages de programmation.

1.11. Les opérateurs

Les opérateurs arithmétiques

Les opérateurs arithmétiques en C sont des symboles spéciaux tels que "+", "-", "*", "/", et "%" utilisés pour effectuer des opérations mathématiques telles que l'addition, la soustraction, la multiplication, la division et le modulo sur des valeurs numériques, facilitant ainsi la manipulation des données numériques dans les programmes.

Opérateur Objectif
+ addition
- soustraction
* multiplication
/ division
% reste de la division entière (modulo)

1.11. Les opérateurs

Les opérateurs arithmétiques

int a = 20, b = 10;
Opérateur Exemple Résultat
+ a + b 30
- a - b 10
* a * b 200
/ a / b 2
% a % b 0

1.11. Les opérateurs

Les opérateurs relationnels

Les opérateurs relationnels en C (==, !=, <, >, <=, >=) comparent deux valeurs ou expressions et renvoient un booléen (vrai ou faux). Ils servent à écrire les conditions des branchements et des boucles.

Opérateur Objectif
< inférieur
<= inférieur ou égal
> supérieur
>= supérieur ou égal
== égal
!= différent

1.11. Les opérateurs

Les opérateurs relationnels

int a = 20, b = 10;
Opérateur Exemple Résultat
< a < b 0
<= a <= b 0
> a > b 1
>= a >= b 1
== a == b 0
!= a != b 1

Remarque: Une valeur différente de zéro est considérée comme VRAIE et la valeur zéro est considérée comme FAUSSE.

1.11. Les opérateurs

Les opérateurs logiques

Les opérateurs logiques en C, tels que "&&" (ET logique), "||" (OU logique) et "!" (NON logique), sont utilisés pour combiner des expressions booléennes et effectuer des opérations de logique booléenne, ce qui permet de prendre des décisions conditionnelles complexes en évaluant plusieurs conditions simultanément dans les programmes.

int a = 20, b = 0;
Opérateur Objectif Exemple Résultat
! Négation !a 0
&& Et a && b 0
|| Ou a || b 1

Remarque: Une valeur différente de zéro est considérée comme VRAIE et la valeur zéro est considérée comme FAUSSE.

1.11. Les opérateurs

Les opérateurs d'incrementation

Les opérateurs d'incrémentation en C, "++" (incrémentation) et "--" (décrémentation), sont utilisés pour augmenter ou diminuer la valeur d'une variable numérique de 1, ce qui facilite les itérations et les mises à jour de variables dans les boucles et les calculs.

int a = 20, b = 0;
Opérateur Exemple Résultat
a++ b = a++ a = 21, b = 20
++a b = ++a a = 21, b = 21
a-- b = a-- a = 19, b = 20
--a b = --a a = 19, b = 19

1.11. Les opérateurs

Les opérateurs de manipulation de bits

Les opérateurs de manipulation de bits en C, tels que "&" (ET bit à bit), "|" (OU bit à bit), "^" (OU exclusif bit à bit) et "~" (NON bit à bit), permettent de réaliser des opérations de manipulation au niveau des bits au sein des données binaires, ce qui est utile pour effectuer des opérations de masquage, de décalage et de gestion de bits individuels dans les programmes.

Bit 1 Bit 2 & | ^ (XOR)
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0

Remarque: Les valeurs ci-dessus (0 et 1) sont des bits binaires et non des valeurs entières.

1.11. Les opérateurs

Les opérateurs de manipulation de bits

int a = 0b01000100; // littéral binaire : normalisé depuis C23 seulement
Opérateur Objectif Exemple Résultat
~ Négation ~a 0xffffffbb
& ET a & 0x4 0x4
| OR a | 0x2 0x46
^ XOR a ^ 0x4 0x40
<< décalage à gauche a << 1 0x88
>> décalage à droite a >> 1 0x22

1.11. Les opérateurs

Les opérateurs d'affectation

Les opérateurs d'affectation combinés en C (+=, -=, *=, /=, %=) appliquent une opération à une variable et lui réaffectent le résultat, ce qui évite de répéter le nom de la variable. Remarque: a op= b ::- a = a op b

Opérateur Objectif Exemple
= affectation a = b
+= addition a += b
-= soustraction a -= b
*= multiplication a *= b
/= division a /= b
%= modulo a %= b

1.11. Les opérateurs

Les opérateurs d'affectation

Opérateur Objectif Exemple
&= ET a &= b
|= OU a |= b
^= XOR a ^= b
<<= décalage à gauche a <<= b
>>= décalage à droite a >>= b

Remarque: a op = b ::- a = a op b

1.12. Structures de contrôle: les branchements conditionnels

if

if (condition) {
 ...
}

1.12. Structures de contrôle: les branchements conditionnels

if

int a = 20, b = 0;
if (a > b) {
 printf("a est supérieur à b");
}

L'objectif est de vérifier si la valeur de a est supérieure à celle de b et d'afficher un message si la condition est vraie.

1.12. Structures de contrôle: les branchements conditionnels

if

Les instructions if...else if...else permettent d'exécuter un bloc de code en fonction de plusieurs conditions alternatives.

if (condition1) {
 ...
} else if (condition2) {
 ...
} else {
 ...
}

1.12. Structures de contrôle: les branchements conditionnels

if

Les instructions if...else if...else permettent d'exécuter un bloc de code en fonction de plusieurs conditions alternatives.

if (condition1) {
 ...
} else if (condition2) {
 ...
} else {
 ...
}
Remarque 1: Tous les nombres non nuls sont considérés comme vrai ('TRUE')
Remarque 2: else est optionnel

1.12. Structures de contrôle: les branchements conditionnels

if

int a = 20, b = 0;
if (a > b) {
 printf("a est supérieur à b");
} else if (a < b) {
 printf("a est inférieur à b");
} else {
 printf("a égale b");
}

1.12. Structures de contrôle: les branchements conditionnels (choix)

switch

switch est utilisée pour sélectionner une action à exécuter en fonction de la valeur de l'expression fournie.

switch (expression) {
 case valeur1 : instructions1
 case valeur2 : instructions2
 ...
 default : instructionsn
}

1.12. Structures de contrôle: les branchements conditionnels (choix)

switch

switch (expression) {
 case valeur1 : instructions1
 case valeur2 : instructions2
 ...
 default : instructionsn
}

1.12. Structures de contrôle: les branchements conditionnels (choix)

switch

int a = 20;
switch (a) {
 case 10 : instructions1
  break;
 case 20 : instructions2
 case 30 : instructions3
  break;
 ...
 default : instructionsn
}

Remarque:Le code exécute instructions2 et continue à exécuter instructions3 car il n'y a pas de break après instructions2.

1.12. Structures de contrôle

Questions

Que sera-t-il affiché à l'écran suite à l'exécution de ce programme ?

if (1) {
  printf("Hi");
} else {
  printf("Bonjour");
}

1.12. Structures de contrôle: les boucles

for

for(initialisation;condition;actualisation){
 ...
}

L'objectif de la boucle for en programmation est de répéter un bloc de code un certain nombre de fois en suivant les étapes suivantes

1.12. Structures de contrôle: les boucles

for

Ces étapes permettent de créer des boucles flexibles qui peuvent être utilisées pour parcourir des éléments d'une liste, effectuer des calculs répétitifs, ou exécuter des actions itératives. La boucle for est couramment utilisée pour simplifier la gestion des itérations dans un programme.

for(initialisation;condition;actualisation){
 ...
}

1.12. Structures de contrôle: les boucles

for

int a = 0;
for( a = 0; a < 10; a++){
 ...
}

L'objectif de ce code est d'initialiser la variable a à 0, puis de répéter un bloc de code tant que a est inférieur à 10, en augmentant la valeur de a à chaque itération.

1.12. Structures de contrôle: les boucles

for

int a = 0;
for(; a < 10; ){
 ...
}

L'objectif de ce code est de répéter un bloc de code tant que la variable a est inférieure à 10, en utilisant une initialisation préalable de a à 0 et en omettant l'actualisation de a à l'intérieur de la boucle.

Remarque: Une ou toutes les instructions d'initialisation, de condition ou d'actualisation peuvent être omises.

1.12. Structures de contrôle: les boucles

for

int a = 0;
for( a = 0; a < 10; a++){
 ...
  a += 2 ;
 ...
}

L'objectif de ce code est d'initialiser la variable a à 0, puis de répéter un bloc de code tant que a est inférieur à 10, en augmentant la valeur de a de 2 à chaque itération à l'intérieur de la boucle, tout en incrémentant a de 1 avec l'opérateur a++ à chaque fin d'itération.

1.12. Structures de contrôle: les boucles

while

La boucle while maintient l'exécution d'un bloc de code tant que la condition entre les parenthèses reste vraie.

while(condition){
 ...
}

1.12. Structures de contrôle: les boucles

while

int a = 20;
while(a > 0){
 ...
 a--;
 ...
}

Ce code maintient la répétition d'un bloc de code tant que la valeur de la variable a est supérieure à 0, en la décrémentant à chaque itération.

1.12. Structures de contrôle: les boucles

while

int a = 0;
while(a < 20){
 ...
 a++;
 ...
}

Ce code vise à répéter un bloc de code tant que la valeur de la variable a est inférieure à 20, en l'incrémentant à chaque itération.

1.12. Structures de contrôle: les boucles

do..while

La boucle do..while garantit l'exécution d'un bloc de code au moins une fois avant de répéter son exécution tant que la condition spécifiée reste vraie.

do{
 ...
} while(condition);

1.12. Structures de contrôle: les boucles

do..while

int a = 20;
do{
 ...
  a --;
 ...
} while(a > 0);

Ce code exécute un bloc de code au moins une fois, puis le répète tant que la valeur de la variable a est supérieure à 0, en décrémentant a à chaque itération.

1.12. Structures de contrôle: les boucles

do..while

int a = 0;
do{
 ...
  a ++;
 ...
} while(a < 20);

Ce code garantit l'exécution d'un bloc de code au moins une fois, suivi de répétitions tant que la valeur de la variable a est inférieure à 20, en l'incrémentant à chaque itération.

1.12. Structures de contrôle: les sauts

break (branchements inconditionnels)

L'instruction break est utilisée pour interrompre prématurément l'exécution d'une boucle (par exemple, for ou while) ou d'un bloc de commutation switch. Lorsque break est rencontré, le programme sort immédiatement de la structure de contrôle dans laquelle il se trouve, sans attendre la fin normale de la condition ou de la boucle. Cela permet de quitter la structure dès qu'une condition souhaitée est atteinte ou lorsqu'une sortie anticipée est nécessaire.

do{
 ...
 if (condition 1) {
  ...
  break;
 }
 ...
} while(condition 2);

1.12. Structures de contrôle: les sauts

break (branchements inconditionnels)

do{
 ...
 if (condition 1) {
  ...
  break;
 }
 ...
} while(condition 2);

Ce code vise à exécuter un bloc de code au moins une fois, puis à répéter son exécution tant que condition 2 est vraie, tout en utilisant break pour sortir de la boucle si condition 1 est satisfaite.

1.12. Structures de contrôle: les sauts

continue (branchements inconditionnels)

L'instruction continue est utilisée pour passer immédiatement à l'itération suivante d'une boucle (par exemple, for ou while), en ignorant le reste du code à l'intérieur de la boucle pour cette itération particulière. Elle permet de sauter l'exécution des instructions restantes dans la boucle et de passer à la prochaine itération, ce qui est utile pour gérer des cas spécifiques sans quitter complètement la boucle.

do{
 ...
 if (condition 1) {
  ...
  continue;
 }
 ...
} while(condition 2);

1.12. Structures de contrôle: les sauts

continue (branchements inconditionnels)

do{
 ...
 if (condition 1) {
  ...
  continue;
 }
 ...
} while(condition 2);

Ce code a pour objectif d'exécuter un bloc de code au moins une fois, puis de le répéter tant que condition 2 est vraie, en utilisant continue pour sauter le reste du code dans une itération si condition 1 est satisfaite.

1.12. Structures de contrôle: les sauts

break (branchements inconditionnels)

while(condition 1){
 ...
 if (condition 2) {
  ...
  break;
 }
 ...
};

Dans ce code, l'objectif est d'exécuter un bloc de code tant que condition 1 est vraie, en utilisant break pour sortir de la boucle si condition 2 est satisfaite à l'intérieur de cette boucle.

1.12. Structures de contrôle: les sauts

continue (branchements inconditionnels)

while(condition 1){
 ...
 if (condition 2) {
  ...
  continue;
 }
 ...
};

Dans ce code, l'objectif est d'exécuter un bloc de code tant que condition 1 est vraie, en utilisant continue pour passer à l'itération suivante de la boucle si condition 2 est satisfaite à l'intérieur de cette boucle.

1.12. Structures de contrôle: les sauts

break (branchements inconditionnels)

for(initialisation;condition 1;actualisation){
 ...
 if (condition 2) {
  ...
  break;
 }
 ...
};

L'objectif de ce code avec la boucle "for" est d'initialiser une variable, puis de répéter un bloc de code tant que condition 1 est vraie, en utilisant break pour sortir de la boucle si condition 2 est satisfaite à l'intérieur de celle-ci.

1.12. Structures de contrôle: les sauts

continue (branchements inconditionnels)

for(initialisation;condition 1;actualisation){
 ...
 if (condition 2) {
  ...
  continue;
 }
 ...
};

L'objectif de ce code avec la boucle "for" est d'initialiser une variable, puis de répéter un bloc de code tant que condition 1 est vraie, en utilisant continue pour sauter le reste du code dans une itération si condition 2 est satisfaite à l'intérieur de la boucle.

1.12. Structures de contrôle

Questions

Écrivez un programme qui affiche 0..20 en ordre croissant et décroissant en utilisant for, while et do..while.

1.12. Structures de contrôle

Questions

Écrivez une boucle infinie en utilisant for, while, do..while.

1.13. Évolution du langage C

C23 : quelques ajouts utiles

1.13. Évolution du langage C

Sûreté mémoire : ce que C ne garantit pas

Dans ce cours, C n'est pas étudié pour lui-même : il rend visibles les choix de conception qu'un langage doit faire — et le prix de chacun.

1.14. Programmation à l'ère de l'IA générative

De la consigne au programme

Un modèle génératif produit, à partir d'une description en langue naturelle, du code plausible. Plausible ne veut pas dire correct.

Ce que la consigne ne dit presque jamais, et que le langage, lui, oblige à trancher :

Le compilateur, ses avertissements et les tests restent les seules réponses vérifiables. Les principes vus dans ce cours sont la grille de lecture du code généré.

1.14. Programmation à l'ère de l'IA générative

Un extrait à relire

Consigne : « la somme des n premiers entiers d'un tableau »

int somme(int t[], int n) {
  int s = 0;
  for (int i = 0; i <= n; i++)
    s += t[i];
  return s;
}

Le code compile sans erreur. Trois relectures suffisent :

  • les bornes : i <= n lit un élément au-delà du tableau ;
  • les types : int comme taille — size_t serait le type juste ;
  • les opérateurs : le dépassement d'un entier signé est un comportement indéfini, pas un résultat qui « boucle ».

1. Principes des langages de programmation: Références

Références

Crédits d'images