Programmation C#
Sommaire
- 1. Le langage C# et la plateforme .NET
- 2. Premier programme
- 3. Variables, types, constantes
- 4. Affectation et conversions
- 5. Opérateurs mathématiques
- 6. Les entrées / sorties (mode console)
- 7. Structures conditionnelles
- 8. Structures itératives (boucles)
- 9. Méthodes
- 10. Structures de données
- 11. Pense-bête — quelle structure choisir ?
1. Le langage C# et la plateforme .NET
C#
- Langage de programmation orienté objet, créé par Microsoft (début des années 2000).
- Permet de développer tous types d'applications : mobiles, cloud, web, desktop, IoT…
- Libre / ouvert, utilisable notamment sous Linux.
- Associé à la plateforme .NET.
Plateforme Microsoft .NET
Ensemble d'outils et de technologies destinées au développement d'applications ciblant des configurations logicielles et matérielles variées.
| Rôle | |
|---|---|
| .NET Framework | Ensemble de bibliothèques de classes (API) donnant accès aux fonctionnalités du système |
| .NET Core | Développement multi-plateforme (Windows, Mac, Linux), architectures en microservices (cloud), conteneurs |
| Type d'application | Windows | Linux | MacOS | Android | iOS |
|---|---|---|---|---|---|
| Console | ✓ | ✓ | ✓ | ||
| Fenêtrée (WinForms/WPF) | ✓ | ||||
| Web | ✓ | ✓ | ✓ | ||
| Mobile | ✓ | ✓ | ✓ | ✓ |
Du code source au programme exécutable
Programmation (code source) → Compilation → Exécution (code binaire)
- Compilation : le compilateur vérifie la syntaxe du code source puis le traduit en langage exécutable.
- Exécution : le programme traduit en code binaire peut être exécuté par le processeur.
- Code managé : la compilation transforme le C# en CIL (Common Intermediate Language), code générique indépendant de l'environnement d'exécution. Le CLR (Common Language Runtime) compile ensuite « à la volée » ce code en binaire exécutable par le SE de la machine → portabilité entre Windows, Linux et MacOS.
- Langages compilés : C#, Java, C/C++, assembleur.
- Langages interprétés : PHP, JavaScript, Python, PowerShell.
2. Premier programme
using System;
namespace HelloWorld
{
class Program
{
/// <summary>
/// Programme HelloWorld
/// </summary>
static void Main(string[] args)
{
// affichage dans la console
Console.WriteLine("Hello world !");
Console.ReadLine();
}
}
}
| Élément | Rôle |
|---|---|
using System; | Le Framework .NET est composé de bibliothèques de classes organisées en espaces de noms (namespaces) ; cette ligne indique que le code utilise l'espace de noms System (ex. la classe Console) |
namespace HelloWorld | L'espace de noms correspond au programme |
class Program | Nom de classe par défaut d'une application console |
static void Main(string[] args) | La méthode Main est le point d'entrée de l'application ; elle contient les instructions exécutées |
- Une instruction se termine toujours par
;. - Les blocs
{ }indiquent que les instructions comprises entre eux vont ensemble. - Commentaires :
// commentaire(une ligne),/* commentaire */(plusieurs lignes),/// <summary> ... </summary>(tag de documentation, ignoré par le compilateur).
3. Variables, types, constantes
Les variables
- Une variable est une donnée utilisable par un programme : un espace mémoire réservé, destiné à contenir une valeur dont le type est fixé.
- Chaque variable doit avoir un nom unique (identificateur).
- Déclaration explicite obligatoire avant utilisation ; déclarer une variable engendre l'allocation d'un espace mémoire. En C#, les variables sont typées.
// Syntaxe : typeVar nomVar;
string nom;
double note;
int coeff;
Règles de nommage :
- Peut comporter chiffres, lettres (accentuées ou non), le caractère
_. - Ne peut jamais commencer par un chiffre, ni être un mot-clé du langage.
- Le langage est sensible à la casse.
- Convention camelCase : le 2e mot et les suivants d'un identificateur composé commencent par une majuscule → ex.
nomEtudiant. - Bonnes pratiques : nom explicite, si possible en anglais (pas de problème d'accents).
Les types de données primitifs
| Type | Description | Taille | Plage de valeurs |
|---|---|---|---|
int | Nombres entiers | 32 bits | -2 147 483 648 à 2 147 483 647 |
long | Nombres entiers longs | 64 bits | -2⁶ à 2⁶-1 |
float | Virgule flottante | 32 bits | ±1,5×10⁻⁴⁵ à ±3,4×10³⁸ |
double | Virgule flottante (double précision, plus précis) | 64 bits | ±5,0×10⁻³⁆⁴ à ±1,7×10³⁰⁸ |
decimal | Nombre décimal | 128 bits | 28 chiffres significatifs |
string | Chaîne de caractères | 16 bits/caractère | délimiteur " |
char | Caractère unique | 16 bits | délimiteur ' |
bool | Booléen | 8 bits | true ou false |
Mot-clé var (inférence de type) : le compilateur C# détermine le type d'une variable en fonction de la valeur assignée. Exemple : var nomClient = "Jean";
Les constantes
const int tauxTVA = 20;
const string devise = "Euro";
const char symbole = '€';
On utilise une constante lorsque la valeur d'une donnée n'est pas amenée à être modifiée. Le mot-clé const scelle la donnée. Par convention, les constantes sont déclarées en début de programme.
4. Affectation et conversions
Affectation (assignation) : opération qui attribue une valeur à une variable. En C#, l'opérateur d'affectation est =.
nom = "Martin";
note = 12.5;
resultat = total / 10;
int age = 10; // déclaration + initialisation en une seule instruction
- Initialisation obligatoire : C# ne permet pas d'utiliser une variable non affectée.
- Compatibilité : la valeur assignée à une variable doit être du même type qu'elle (type fixé à la déclaration).
Conversions :
int note1;
note1 = int.Parse("12"); // chaîne → valeur numérique
string valeur;
valeur = note1.ToString(); // valeur numérique → chaîne
double res;
res = (double)note1; // cast entre types numériques
5. Opérateurs mathématiques
| Opérateur | Signification |
|---|---|
+ | Addition (variables numériques) / concaténation (variables string) |
- | Soustraction |
* | Multiplication |
/ | Division — si les 2 opérandes sont double, résultat double ; si on divise un entier par un autre, résultat entier |
% | Modulo, reste de la division euclidienne |
++ | Incrémentation (ajoute 1) |
-- | Décrémentation (soustrait 1) |
6. Les entrées / sorties (mode console)
Classe Console : composant du Framework .NET permettant d'interagir avec la fenêtre de commandes (affichage et saisie).
Affichage
Console.Write("Bonjour"); // curseur reste en fin de ligne
Console.WriteLine("Au revoir"); // curseur passe en début de ligne suivante
string nom = "Hugo";
Console.Write("Bonjour {0} ", nom); // chaîne composite
Console.Write("Bonjour " + nom); // concaténation
Console.Write($"Bonjour {nom}"); // interpolation de chaîne
Caractères spéciaux : \n (saut de ligne), \t (tabulation), \" (guillemet).
Saisie
string nom = Console.ReadLine(); // récupère une chaîne saisie, terminée par Entrée
int nb = int.Parse(Console.ReadLine()); // ReadLine() renvoie toujours une string → conversion
Console.Read(); // récupère un seul caractère saisi
7. Structures conditionnelles
Structures de contrôle permettant d'exécuter un traitement ou un autre selon l'évaluation d'une condition. Deux structures existent en C# : if...else et switch.
L'instruction if
if (age >= 18)
{
Console.WriteLine("Vous êtes majeur");
}
else
{
Console.WriteLine("Vous êtes mineur");
}
- La condition est une expression logique (booléenne), entre parenthèses
( ), sans;après. - Le bloc
elseest facultatif ; un blocelsecorrespond toujours à un seulif. - Accolades
{ }: facultatives si une seule instruction est rattachée au bloc, obligatoires dès que plusieurs instructions y sont rattachées. - Imbrication (équivaut à un
else if) :
if (temperature < 0)
Console.WriteLine("Eau à l'état solide");
else if (temperature < 100)
Console.WriteLine("Eau à l'état liquide");
else
Console.WriteLine("Eau à l'état gazeux");
La condition
Opérateurs de comparaison
| Opérateur | Signification |
|---|---|
== | égal à (ne pas confondre avec = l'affectation) |
!= | différent de |
< | inférieur |
<= | inférieur ou égal |
> | supérieur |
>= | supérieur ou égal |
Opérateurs logiques
| Opérateur | Signification |
|---|---|
&& | ET — vraie si les 2 conditions sont vraies |
|| | OU — vraie si l'une des 2 conditions est vraie |
! | NON — inverse (négation) de la condition |
L'instruction switch
switch (operateur) // variable de type int, char, string ou bool uniquement
{
case '+':
res = a + b;
break;
case '-':
res = a - b;
break;
default:
Console.WriteLine("opérateur inconnu");
break;
}
- Chaque étiquette
caseteste une valeur constante et unique. breakforce la sortie de la structureswitch.default(facultatif) gère les cas non prévus explicitement.
8. Structures itératives (boucles)
Permettent de répéter un traitement en fonction de l'évaluation d'une condition.
| Structure | Nombre d'itérations |
|---|---|
for | Connu dès le départ |
while | Indéterminé, condition testée avant → 0 à n exécutions |
do...while | Indéterminé, condition testée après → 1 à n exécutions (au moins une fois) |
while
Console.Write("Saisir un nombre positif : ");
int nb = int.Parse(Console.ReadLine());
while (nb < 0)
{
Console.Write("Saisir un nombre positif : ");
nb = int.Parse(Console.ReadLine());
}
Console.Write("Merci !");
Pas de point-virgule après la condition. Si aucune instruction ne fait évoluer la condition → boucle infinie.
do...while
int nb;
do
{
Console.Write("Saisir un nombre positif : ");
nb = int.Parse(Console.ReadLine());
} while (nb < 0);
Point-virgule obligatoire après la condition. Le bloc d'instructions est exécuté au moins une fois (évaluation en sortie de boucle).
for
for (int i = 0; i <= 100; i++)
{
Console.WriteLine(i);
}
Trois arguments séparés par ; :
- Initialisation de la variable-indice — exécutée une seule fois, à l'entrée dans la boucle
- Condition portant sur la variable-indice — évaluée avant chaque itération
- Pas — exécuté à la fin de chaque itération, avant réévaluation de la condition (incrémentation ou décrémentation)
9. Méthodes (procédures / fonctions)
Une méthode (fonction membre en POO) regroupe un ensemble d'instructions, peut recevoir des données en entrée (paramètres) et renvoyer un résultat.
Objectifs : code modulaire, plus lisible et maintenable, factorisation (évite la duplication), réutilisation, facilite tests/débogage et documentation.
Définir une méthode
static typeRetour NomMethode([paramètres])
{
// instructions
[return ...]
}
typeRetour: type du résultat renvoyé, ouvoidsi la méthode ne retourne rien (pas dereturndans ce cas).returnmet fin à l'exécution de la méthode et spécifie la valeur à retourner.- Paramètres : liste de 0 à N paramètres séparés par
,(mode de passage, type, nom) ; un paramètre s'apparente à une variable locale.
Appeler une méthode
[resultat = ] NomMethode([arguments]);
Les arguments (valeurs transmises à l'appel) doivent correspondre aux paramètres attendus : nombre, ordre, type, mode de passage.
// Sans paramètre, sans retour
static void DireBonjour()
{
Console.WriteLine("Bonjour !");
}
// Appel : DireBonjour();
// Avec paramètres, sans retour
static void DireBonjour(string nom, string prenom)
{
Console.WriteLine($"Bonjour {prenom} {nom} !");
}
// Appel : DireBonjour(leNom, lePrenom);
// Avec paramètres et retour
static double CalculTTC(int prixHT, double tauxTVA)
{
double prixTTC = prixHT * (1 + tauxTVA / 100);
return prixTTC;
}
// Appel : double leTTC = CalculTTC(unPrix, unTaux);
Passage des paramètres
| Mode | Mot-clé C# | Comportement |
|---|---|---|
| Entrée (par valeur) | (aucun, par défaut) | Une copie de la valeur est transmise. Modification dans la méthode = locale, non répercutée à l'appelant |
| Entrée-sortie (par référence) | ref | Le paramètre a déjà une valeur à l'appel ; peut être modifié, la nouvelle valeur est répercutée à l'appelant |
| Sortie (par référence) | out | Le paramètre n'a pas de valeur au moment de l'appel ; la méthode doit lui en assigner une, répercutée à l'appelant |
// ref : entrée-sortie
static void Incrementer(ref int nombre, int valeur)
{
nombre = nombre + valeur;
}
// Appel : Incrementer(ref nb1, nb2); ← "ref" obligatoire devant l'argument, qui doit être initialisé
// out : sortie
static bool Division(double nb1, double nb2, out double res)
{
res = 0;
bool ok = false;
if (nb2 != 0)
{
res = nb1 / nb2;
ok = true;
}
return ok;
}
// Appel : if (Division(a, b, out result) == true) { ... }
Portée des variables
- La portée (visibilité) d'une variable correspond au bloc
{ }dans lequel elle a été déclarée ; en dehors, elle n'est pas accessible. - Une variable locale à une méthode n'est utilisable que dans cette méthode ; une variable déclarée dans un
forest locale à cefor. - Règle pratique : déclarer la variable dans le bloc de code le plus englobant parmi ceux qui doivent y accéder.
Documenter une méthode
/// <summary>
/// Méthode qui calcule l'hypoténuse d'un triangle rectangle
/// </summary>
/// <param name="b">base du triangle</param>
/// <param name="h">hauteur du triangle</param>
/// <returns>hypoténuse du triangle</returns>
static double CalculerHypotenuse(int b, int h)
{ ... }
Tags : <summary> (rôle de la méthode), <param> (rôle de chaque paramètre), <returns> (valeur de retour). Cette documentation s'affiche automatiquement dans l'éditeur de code lors de l'appel de la méthode (comme pour les classes déjà documentées du Framework .NET, ex. Math.Round()).
10. Structures de données
Permettent de regrouper et d'organiser un ensemble (une collection) de données. Opérations courantes : parcours, insertion, suppression, recherche.
Tableaux (Array)
Stockent de manière consécutive un nombre fini d'éléments de même type. Indices en base 0 (1er élément à l'indice 0, dernier à l'indice n-1).
// Déclaration + instanciation (taille fixe, structure statique)
double[] tab1 = new double[5];
// Déclaration + initialisation directe (dimensionnement automatique)
int[] tab3 = {5, 10, 4, 3, 1, 25};
// Accès à un élément
Console.Write(tab3[0]); // affiche 5
tab3[2] = 7; // remplace la valeur à l'indice 2
// tab3[7] provoquerait une erreur outOfRangeException (débordement)
// Parcours avec indices (for / while)
for (int i = 0; i <= 5; i++)
Console.WriteLine(tab3[i]);
// Parcours en énumérant les éléments (foreach) — lecture seule
foreach (int elem in tab3)
Console.WriteLine(elem);
Un tableau est un type référence : sans initialisation, sa valeur est null.
Tableaux à deux dimensions
int[,] tab2 = {{5,10,4},{3,1,25}}; // 2 lignes, 3 colonnes
Console.Write(tab2[1,2]); // ligne 1, colonne 2 → 25
tab2[0,1] = 7; // remplace la valeur à ligne 0, colonne 1
for (int i = 0; i <= 1; i++)
for (int j = 0; j <= 2; j++)
Console.WriteLine(tab2[i,j]);
Classe Array (méthodes utiles) : propriété Length ; méthodes Copy(), Clear(), Exists(), Find(), GetLength(), GetUpperBound(), Sort()…
Listes (List<T>)
Structure dynamique (taille non fixée), stocke de manière ordonnée un nombre indéfini d'éléments de même type, accessibles par index (base 0). Namespace System.Collections.Generic.
List<string> mesAmis = new List<string>();
mesAmis.Add("Elodie");
mesAmis.Add("Mario");
mesAmis.Add("Harry");
Console.WriteLine("J'ai {0} amis", mesAmis.Count);
Console.WriteLine(mesAmis[0]); // accès par indexeur
foreach (string nom in mesAmis)
Console.WriteLine(nom);
mesAmis.Remove("Mario"); // suppression par valeur
mesAmis.RemoveAt(0); // suppression par indice
for (int i = 0; i <= mesAmis.Count - 1; i++)
Console.WriteLine(mesAmis[i]);
Dictionnaires (Dictionary<TKey, TValue>)
Structure dynamique qui stocke des couples clé/valeur ; la clé est unique. Namespace System.Collections.Generic.
Dictionary<string, int> leDico = new Dictionary<string, int>();
leDico.Add("Julia", 10);
leDico.Add("Leo", 12);
// leDico.Add("Julia", 4); → déclenche une exception (clé déjà existante)
Console.WriteLine(leDico.Count); // nombre d'entrées
Console.WriteLine(leDico["Leo"]); // accès par clé → 12
leDico["Steeven"] = 15; // clé existante → valeur remplacée
leDico["Mario"] = 8; // clé absente → nouvelle entrée ajoutée
leDico.ContainsKey("Steeven"); // teste la présence d'une clé → true/false
foreach (int v in leDico.Values) // parcours des valeurs
Console.WriteLine(v);
foreach (string k in leDico.Keys) // parcours des clés
Console.WriteLine("{0}->{1}", k, leDico[k]);
foreach (KeyValuePair<string, int> entree in leDico) // parcours des couples clé/valeur
Console.WriteLine("{0}->{1}", entree.Key, entree.Value);
11. Pense-bête — quelle structure choisir ?
Nombre d'itérations connu → for
Nombre d'itérations indéterminé → while (0 à n fois) ou do..while (1 à n fois, au moins 1 exécution)
Collection de taille fixe, même type → tableau (Array)
Collection dynamique ordonnée, même type → List<T>
Collection dynamique de couples clé/valeur → Dictionary<TKey, TValue>