🔧 B2.4 - Fonctions et Méthodes en C
📋 Objectifs du cours
À la fin de ce cours, vous serez capable de : - ✅ Comprendre l'utilité des fonctions et méthodes - ✅ Créer des méthodes avec et sans paramètres - ✅ Utiliser les valeurs de retour - ✅ Maîtriser les différents types de paramètres - ✅ Appliquer les bonnes pratiques de programmation modulaire
🎯 Introduction aux méthodes
Qu'est-ce qu'une méthode ?
Une méthode est un bloc de code réutilisable qui effectue une tâche spécifique. Elle permet de diviser un programme complexe en parties plus petites et plus gérables, favorisant la réutilisabilité et la lisibilité du code.
💡 Avantages des méthodes :
- Réutilisabilité : Évite la duplication de code
- Lisibilité : Code plus organisé et compréhensible
- Maintenance : Modifications centralisées
- Test : Facilite les tests unitaires
📝 Anatomie d'une méthode
🚀 Méthodes simples
🔤 Méthodes sans paramètres ni retour
// Méthode qui affiche un message
public static void AfficherBienvenue()
{
Console.WriteLine("===================");
Console.WriteLine(" BIENVENUE ! ");
Console.WriteLine("===================");
}
// Méthode qui affiche la date actuelle
public static void AfficherDate()
{
DateTime maintenant = DateTime.Now;
Console.WriteLine($"Nous sommes le {maintenant:dd/MM/yyyy}");
}
// Utilisation dans Main
static void Main(string[] args)
{
AfficherBienvenue();
AfficherDate();
}
📤 Méthodes avec valeur de retour
// Méthode qui retourne un nombre aléatoire
public static int GenererNombreAleatoire()
{
Random random = new Random();
return random.Next(1, 101); // Entre 1 et 100
}
// Méthode qui retourne l'heure actuelle formatée
public static string ObtenirHeureActuelle()
{
return DateTime.Now.ToString("HH:mm:ss");
}
// Méthode qui vérifie si une année est bissextile
public static bool EstBissextile(int annee)
{
return (annee % 4 == 0 && annee % 100 != 0) || (annee % 400 == 0);
}
// Utilisation
static void Main(string[] args)
{
int nombre = GenererNombreAleatoire();
string heure = ObtenirHeureActuelle();
bool bissextile = EstBissextile(2024);
Console.WriteLine($"Nombre : {nombre}");
Console.WriteLine($"Heure : {heure}");
Console.WriteLine($"2024 est bissextile : {bissextile}");
}
📥 Paramètres de méthodes
🎯 Paramètres simples
// Méthode avec un paramètre
public static void SaluerPersonne(string nom)
{
Console.WriteLine($"Bonjour {nom} !");
}
// Méthode avec plusieurs paramètres
public static double CalculerAire(double longueur, double largeur)
{
return longueur * largeur;
}
// Méthode avec paramètres de types différents
public static void AfficherInfoPersonne(string nom, int age, bool estEtudiant)
{
Console.WriteLine($"Nom : {nom}");
Console.WriteLine($"Âge : {age} ans");
Console.WriteLine($"Statut : {(estEtudiant ? "Étudiant" : "Non étudiant")}");
}
// Utilisation
static void Main(string[] args)
{
SaluerPersonne("Alice");
double aire = CalculerAire(5.5, 3.2);
Console.WriteLine($"Aire : {aire} m²");
AfficherInfoPersonne("Bob", 22, true);
}
🔧 Paramètres avec valeurs par défaut
// Paramètres optionnels avec valeurs par défaut
public static void CreerCompte(string nom, string email, bool estActif = true, string role = "Utilisateur")
{
Console.WriteLine($"Compte créé :");
Console.WriteLine($"- Nom : {nom}");
Console.WriteLine($"- Email : {email}");
Console.WriteLine($"- Actif : {estActif}");
Console.WriteLine($"- Rôle : {role}");
}
// Méthode de calcul avec paramètres optionnels
public static double CalculerPrix(double prixBase, double tva = 0.20, double remise = 0.0)
{
double prixAvecTva = prixBase * (1 + tva);
double prixFinal = prixAvecTva * (1 - remise);
return prixFinal;
}
// Utilisation avec différentes combinaisons
static void Main(string[] args)
{
// Tous les paramètres
CreerCompte("Alice", "alice@email.com", true, "Admin");
// Paramètres par défaut utilisés
CreerCompte("Bob", "bob@email.com");
// Paramètres nommés
CreerCompte("Charlie", "charlie@email.com", role: "Modérateur");
// Calculs de prix
double prix1 = CalculerPrix(100); // 120€ (TVA 20%)
double prix2 = CalculerPrix(100, 0.10); // 110€ (TVA 10%)
double prix3 = CalculerPrix(100, 0.20, 0.15); // 102€ (TVA 20%, remise 15%)
}
📋 Paramètres params
// Méthode avec nombre variable de paramètres
public static int Additionner(params int[] nombres)
{
int somme = 0;
foreach (int nombre in nombres)
{
somme += nombre;
}
return somme;
}
// Méthode pour formater un message avec plusieurs valeurs
public static string FormaterMessage(string template, params object[] valeurs)
{
return string.Format(template, valeurs);
}
// Utilisation
static void Main(string[] args)
{
// Différentes façons d'appeler la méthode
int somme1 = Additionner(1, 2, 3); // 6
int somme2 = Additionner(10, 20, 30, 40); // 100
int somme3 = Additionner(); // 0
// Avec un tableau
int[] nombres = { 5, 10, 15 };
int somme4 = Additionner(nombres); // 30
// Formatage de messages
string msg = FormaterMessage("Bonjour {0}, vous avez {1} ans", "Alice", 25);
Console.WriteLine(msg); // "Bonjour Alice, vous avez 25 ans"
}
🔄 Paramètres par référence
📤 Paramètres out
// Méthode qui retourne plusieurs valeurs avec out
public static bool DiviserAvecReste(int dividende, int diviseur, out int quotient, out int reste)
{
if (diviseur == 0)
{
quotient = 0;
reste = 0;
return false; // Division impossible
}
quotient = dividende / diviseur;
reste = dividende % diviseur;
return true; // Division réussie
}
// Méthode pour analyser une chaîne de nombres
public static bool AnalyserNombres(string texte, out int minimum, out int maximum, out double moyenne)
{
minimum = 0;
maximum = 0;
moyenne = 0;
string[] parties = texte.Split(',');
List<int> nombres = new List<int>();
foreach (string partie in parties)
{
if (int.TryParse(partie.Trim(), out int nombre))
{
nombres.Add(nombre);
}
}
if (nombres.Count == 0)
return false;
minimum = nombres.Min();
maximum = nombres.Max();
moyenne = nombres.Average();
return true;
}
// Utilisation
static void Main(string[] args)
{
// Division avec reste
if (DiviserAvecReste(17, 5, out int quotient, out int reste))
{
Console.WriteLine($"17 ÷ 5 = {quotient} reste {reste}");
}
// Analyse de nombres
string donnees = "10, 25, 8, 33, 12";
if (AnalyserNombres(donnees, out int min, out int max, out double moy))
{
Console.WriteLine($"Min: {min}, Max: {max}, Moyenne: {moy:F2}");
}
}
🔄 Paramètres ref
// Méthode qui échange deux valeurs
public static void Echanger(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
// Méthode qui modifie une chaîne
public static void TransformerTexte(ref string texte)
{
texte = texte.ToUpper().Replace(" ", "_");
}
// Méthode qui applique une remise
public static void AppliquerRemise(ref double prix, double pourcentageRemise)
{
prix = prix * (1 - pourcentageRemise / 100);
}
// Utilisation
static void Main(string[] args)
{
// Échange de valeurs
int x = 10, y = 20;
Console.WriteLine($"Avant : x={x}, y={y}");
Echanger(ref x, ref y);
Console.WriteLine($"Après : x={x}, y={y}");
// Transformation de texte
string message = "Bonjour le monde";
Console.WriteLine($"Avant : {message}");
TransformerTexte(ref message);
Console.WriteLine($"Après : {message}");
// Application de remise
double prix = 100.0;
Console.WriteLine($"Prix initial : {prix}€");
AppliquerRemise(ref prix, 15); // 15% de remise
Console.WriteLine($"Prix après remise : {prix}€");
}
🏗️ Méthodes avancées
🔄 Surcharge de méthodes (Overloading)
// Plusieurs versions de la même méthode avec des paramètres différents
public static class Calculatrice
{
// Addition de deux entiers
public static int Additionner(int a, int b)
{
return a + b;
}
// Addition de trois entiers
public static int Additionner(int a, int b, int c)
{
return a + b + c;
}
// Addition de deux doubles
public static double Additionner(double a, double b)
{
return a + b;
}
// Addition d'un tableau d'entiers
public static int Additionner(int[] nombres)
{
int somme = 0;
foreach (int nombre in nombres)
{
somme += nombre;
}
return somme;
}
}
// Utilisation
static void Main(string[] args)
{
int somme1 = Calculatrice.Additionner(5, 3); // 8
int somme2 = Calculatrice.Additionner(1, 2, 3); // 6
double somme3 = Calculatrice.Additionner(2.5, 3.7); // 6.2
int somme4 = Calculatrice.Additionner(new int[] { 1, 2, 3, 4 }); // 10
}
🎯 Méthodes d'extension
// Classe statique pour les méthodes d'extension
public static class StringExtensions
{
// Méthode d'extension pour compter les mots
public static int CompterMots(this string texte)
{
if (string.IsNullOrWhiteSpace(texte))
return 0;
return texte.Split(new char[] { ' ', '\t', '\n' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
// Méthode d'extension pour inverser une chaîne
public static string Inverser(this string texte)
{
if (string.IsNullOrEmpty(texte))
return texte;
char[] caracteres = texte.ToCharArray();
Array.Reverse(caracteres);
return new string(caracteres);
}
// Méthode d'extension pour capitaliser chaque mot
public static string CapitaliserMots(this string texte)
{
if (string.IsNullOrWhiteSpace(texte))
return texte;
return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(texte.ToLower());
}
}
// Utilisation
static void Main(string[] args)
{
string phrase = "bonjour le monde";
// Utilisation comme si c'étaient des méthodes de la classe string
int nombreMots = phrase.CompterMots(); // 3
string inverse = phrase.Inverser(); // "ednom el ruojnob"
string capitalise = phrase.CapitaliserMots(); // "Bonjour Le Monde"
Console.WriteLine($"Phrase : {phrase}");
Console.WriteLine($"Nombre de mots : {nombreMots}");
Console.WriteLine($"Inversée : {inverse}");
Console.WriteLine($"Capitalisée : {capitalise}");
}
🎯 Exercices pratiques
🏋️ Exercice 1 : Calculatrice avancée
Créez une classe Calculatrice avec les méthodes suivantes : 1. `Additionner`, `Soustraire`, `Multiplier`, `Diviser` (avec gestion division par zéro) 2. `Puissance` (nombre élevé à une puissance) 3. `Factorielle` (calcul récursif ou itératif) 4. `EstPremier` (vérifier si un nombre est premier)🏋️ Exercice 2 : Gestionnaire de mots de passe
Créez des méthodes pour : 1. `GenererMotDePasse(int longueur, bool inclureSymboles = false)` 2. `ValiderMotDePasse(string motDePasse, out string[] erreurs)` 3. `CalculerForce(string motDePasse)` qui retourne un score de 0 à 100 Critères de validation : au moins 8 caractères, une majuscule, une minuscule, un chiffre.🏋️ Exercice 3 : Analyseur de fichier texte
Créez des méthodes pour analyser un texte : 1. `CompterCaracteres(string texte, out int lettres, out int chiffres, out int espaces)` 2. `TrouverMotLePlusLong(string texte)` 3. `CalculerFrequenceMots(string texte)` qui retourne un Dictionary🏋️ Exercice 4 : Système de notes
Créez un système de gestion de notes avec : 1. `AjouterNote(List🚀 Bonnes pratiques
Conseils pour de bonnes méthodes
**1. Nommage clair et descriptif :**
**2. Une méthode = une responsabilité :**
**3. Éviter les méthodes trop longues :**
**4. Gérer les cas d'erreur :**
// ❌ Mauvais
public static int Calc(int x, int y) { return x + y; }
// ✅ Bon
public static int CalculerSomme(int premier, int second) { return premier + second; }
// ❌ Fait trop de choses
public static void TraiterUtilisateur(string nom, string email)
{
// Validation
// Sauvegarde en base
// Envoi d'email
// Logging
}
// ✅ Responsabilités séparées
public static bool ValiderUtilisateur(string nom, string email) { /* ... */ }
public static void SauvegarderUtilisateur(string nom, string email) { /* ... */ }
public static void EnvoyerEmailBienvenue(string email) { /* ... */ }
⚠️ Erreurs courantes à éviter :
- Oublier le return : Dans une méthode non-void
- Modifier des paramètres : Sans ref/out quand nécessaire
- Méthodes trop complexes : Diviser en sous-méthodes
- Pas de validation : Toujours valider les paramètres d'entrée
📚 Points clés à retenir
🎯 Résumé du chapitre :
- Méthodes : Blocs de code réutilisables avec paramètres et retour
- Paramètres : Simples, optionnels, params, ref, out
- Surcharge : Plusieurs versions avec paramètres différents
- Extensions : Ajouter des méthodes aux types existants
- Bonnes pratiques : Nommage clair, responsabilité unique, gestion d'erreurs
🔗 Liens utiles
Étape précédente : B2.3 - Listes et collections
Prochaine étape : B2.5 - Programmation Orientée Objet