L’un des concepts fondamentaux en programmation C est l’appel de fonctions. Les fonctions permettent de structurer le code, de le rendre modulaire et réutilisable. Cet article détaillé vous guidera à travers la théorie des appels de fonctions en C, suivie d’une série d’exercices corrigés pour renforcer votre compréhension.
Définition et Déclaration de Fonction
En C, une fonction doit être déclarée avant d’être utilisée. La déclaration d’une fonction (ou prototype) indique son type de retour, son nom et les types de ses paramètres.
// Prototype de la fonction
int addition(int a, int b);
La définition de la fonction inclut le corps de la fonction où les opérations sont définies.
// Définition de la fonction
int addition(int a, int b) {
return a + b;
}
Appel de Fonction
Pour appeler une fonction, il suffit d’utiliser son nom suivi de la liste des arguments entre parenthèses.
int resultat = addition(5, 3); // Appel de la fonction addition
Passage de Paramètres
En C, les paramètres sont passés par valeur, ce qui signifie que les modifications apportées aux paramètres dans la fonction n’affectent pas les variables d’origine.
void incrementer(int x) {
x = x + 1;
}
int main() {
int a = 5;
incrementer(a);
printf("%d", a); // Affiche 5, car x est passé par valeur
return 0;
}
Pour modifier la variable d’origine, vous devez passer un pointeur.
void incrementer(int *x) {
*x = *x + 1;
}
int main() {
int a = 5;
incrementer(&a);
printf("%d", a); // Affiche 6, car x est passé par adresse
return 0;
}
Énoncé : Écrire une fonction factorielle
qui prend un entier n
et retourne sa factorielle.
Solution :
#include <stdio.h>
// Prototype de la fonction
int factorielle(int n);
// Définition de la fonction
int factorielle(int n) {
if (n == 0) {
return 1;
}
return n * factorielle(n - 1);
}
int main() {
int nombre = 5;
printf("La factorielle de %d est %d\n", nombre, factorielle(nombre)); // Affiche 120
return 0;
}
Explication : La fonction factorielle
utilise la récursion pour calculer la factorielle d’un nombre. Si n
est 0, elle retourne 1 (condition de base). Sinon, elle appelle récursivement factorielle
avec n - 1
et multiplie le résultat par n
.
Énoncé : Écrire une fonction echanger
qui échange les valeurs de deux variables entières.
Solution :
#include <stdio.h>
// Prototype de la fonction
void echanger(int *a, int *b);
// Définition de la fonction
void echanger(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 10, y = 20;
printf("Avant l'échange: x = %d, y = %d\n", x, y);
echanger(&x, &y);
printf("Après l'échange: x = %d, y = %d\n", x, y); // Affiche x = 20, y = 10
return 0;
}
Explication : La fonction echanger
prend des pointeurs en paramètres pour modifier les valeurs des variables d’origine. Elle utilise une variable temporaire pour stocker la valeur de a
pendant l’échange.
Énoncé : Écrire une fonction sommeTableau
qui prend un tableau d’entiers et sa taille, et retourne la somme de ses éléments.
Solution :
#include <stdio.h>
// Prototype de la fonction
int sommeTableau(int tableau[], int taille);
// Définition de la fonction
int sommeTableau(int tableau[], int taille) {
int somme = 0;
for (int i = 0; i < taille; i++) {
somme += tableau[i];
}
return somme;
}
int main() {
int tableau[] = {1, 2, 3, 4, 5};
int taille = sizeof(tableau) / sizeof(tableau[0]);
printf("La somme des éléments du tableau est %d\n", sommeTableau(tableau, taille)); // Affiche 15
return 0;
}
Explication : La fonction sommeTableau
itère sur chaque élément du tableau et accumule leur somme. La taille du tableau est passée en argument pour déterminer le nombre d’éléments à traiter.
Conclusion
La maîtrise des fonctions en C est essentielle pour écrire du code efficace et modulaire. Les exercices corrigés présentés dans cet article couvrent des cas d’utilisation courants et permettent de se familiariser avec les concepts de base des fonctions, du passage de paramètres et de la gestion de la mémoire.
Dans cette section, nous allons explorer des exercices avancés qui incluent des cas particuliers. Ces exercices vont au-delà des scénarios simples et vous encouragent à penser à des solutions robustes pour gérer des situations exceptionnelles ou des entrées non standard.
Énoncé : Écrire une fonction récursive rechercheBinaire
qui prend un tableau trié d’entiers, la taille du tableau, et un élément à rechercher. La fonction doit retourner l’indice de l’élément dans le tableau ou -1 si l’élément n’est pas trouvé. Gérez les cas particuliers où le tableau est vide ou contient des éléments dupliqués.
Solution :
#include <stdio.h>
// Prototype de la fonction
int rechercheBinaire(int tableau[], int gauche, int droite, int element);
// Définition de la fonction
int rechercheBinaire(int tableau[], int gauche, int droite, int element) {
if (droite >= gauche) {
int milieu = gauche + (droite - gauche) / 2;
// Si l'élément est au milieu
if (tableau[milieu] == element) {
return milieu;
}
// Si l'élément est plus petit que le milieu, il est dans la partie gauche
if (tableau[milieu] > element) {
return rechercheBinaire(tableau, gauche, milieu - 1, element);
}
// Sinon, il est dans la partie droite
return rechercheBinaire(tableau, milieu + 1, droite, element);
}
// Si l'élément n'est pas trouvé
return -1;
}
int main() {
int tableau[] = {2, 3, 4, 10, 10, 10, 40};
int taille = sizeof(tableau) / sizeof(tableau[0]);
int element = 10;
int resultat = rechercheBinaire(tableau, 0, taille - 1, element);
if (resultat != -1) {
printf("Element trouvé à l'indice %d\n", resultat); // Affiche l'un des indices où se trouve 10
} else {
printf("Element non trouvé\n");
}
return 0;
}
Cas Particuliers :
rechercheBinaire
gère naturellement ce cas, car droite
sera inférieur à gauche
.Énoncé : Écrire une fonction triBulles
qui prend un tableau d’entiers et sa taille, et trie le tableau en utilisant l’algorithme de tri à bulles. La fonction doit détecter si le tableau est déjà trié pour éviter des passes inutiles.
Solution :
#include <stdio.h>
#include <stdbool.h>
// Prototype de la fonction
void triBulles(int *tableau, int taille);
// Définition de la fonction
void triBulles(int *tableau, int taille) {
bool echange;
for (int i = 0; i < taille - 1; i++) {
echange = false;
for (int j = 0; j < taille - i - 1; j++) {
if (*(tableau + j) > *(tableau + j + 1)) {
int temp = *(tableau + j);
*(tableau + j) = *(tableau + j + 1);
*(tableau + j + 1) = temp;
echange = true;
}
}
// Si aucun échange n'a eu lieu, le tableau est déjà trié
if (!echange) break;
}
}
int main() {
int tableau[] = {1, 2, 3, 4, 5, 6};
int taille = sizeof(tableau) / sizeof(tableau[0]);
triBulles(tableau, taille);
printf("Tableau trié: ");
for (int i = 0; i < taille; i++) {
printf("%d ", tableau[i]); // Affiche 1 2 3 4 5 6
}
printf("\n");
return 0;
}
Cas Particuliers :
triBulles
détectera rapidement que le tableau est déjà trié et arrêtera les passes inutiles.Énoncé : Créer une liste chaînée simple avec des fonctions pour ajouter un élément à la fin, supprimer un élément et afficher tous les éléments. Gérez les cas particuliers où la liste est vide lors de la suppression ou de l’affichage.
Solution :
#include <stdio.h>
#include <stdlib.h>
// Définition de la structure du noeud
struct Noeud {
int data;
struct Noeud* suivant;
};
// Prototype des fonctions
void ajouterFin(struct Noeud** tete, int nouvelleData);
void supprimerElement(struct Noeud** tete, int key);
void afficherListe(struct Noeud* noeud);
// Définition des fonctions
void ajouterFin(struct Noeud** tete, int nouvelleData) {
struct Noeud* nouveauNoeud = (struct Noeud*) malloc(sizeof(struct Noeud));
struct Noeud* dernier = *tete;
nouveauNoeud->data = nouvelleData;
nouveauNoeud->suivant = NULL;
if (*tete == NULL) {
*tete = nouveauNoeud;
return;
}
while (dernier->suivant != NULL) {
dernier = dernier->suivant;
}
dernier->suivant = nouveauNoeud;
}
void supprimerElement(struct Noeud** tete, int key) {
struct Noeud* temp = *tete;
struct Noeud* precedent = NULL;
if (temp == NULL) {
printf("Erreur : La liste est vide.\n");
return;
}
if (temp != NULL && temp->data == key) {
*tete = temp->suivant;
free(temp);
return;
}
while (temp != NULL && temp->data != key) {
precedent = temp;
temp = temp->suivant;
}
if (temp == NULL) {
printf("Erreur : Élément %d non trouvé.\n", key);
return;
}
precedent->suivant = temp->suivant;
free(temp);
}
void afficherListe(struct Noeud* noeud) {
if (noeud == NULL) {
printf("La liste est vide.\n");
return;
}
while (noeud != NULL) {
printf("%d -> ", noeud->data);
noeud = noeud->suivant;
}
printf("NULL\n");
}
int main() {
struct Noeud* tete = NULL;
ajouterFin(&tete, 1);
ajouterFin(&tete, 2);
ajouterFin(&tete, 3);
ajouterFin(&tete, 4);
printf("Liste après ajout des éléments: ");
afficherListe(tete); // Affiche 1 -> 2 -> 3 -> 4 -> NULL
supprimerElement(&tete, 3);
printf("Liste après suppression de l'élément 3: ");
afficherListe(tete); // Affiche 1 -> 2 -> 4 -> NULL
supprimerElement(&tete, 5); // Affiche "Erreur : Élément 5 non trouvé."
afficherListe(NULL); // Affiche "La liste est vide."
return 0;
}
Cas Particuliers :
supprimerElement
vérifie si la liste est vide avant d’essayer de supprimer un élément.supprimerElement
gère le cas où l’élément à supprimer n’est pas trouvé dans la liste.afficherListe
vérifie si la liste est vide avant de tenter de l’afficher.Énoncé : Écrire une fonction calculMoyenne
qui prend un tableau d’entiers et sa taille, et retourne la moyenne des éléments. Gérez les cas particuliers où le tableau contient des zéros qui ne doivent pas être inclus dans le calcul de la moyenne.
Solution :
#include <stdio.h>
// Prototype de la fonction
float calculMoyenne(int tableau[], int taille);
// Définition de la fonction
float calculMoyenne(int tableau[], int taille) {
int somme = 0;
int compteur = 0;
for (int i = 0; i < taille; i++) {
if (tableau[i] != 0) {
somme += tableau[i];
compteur++;
}
}
return (compteur != 0) ? (float)s
omme / compteur : 0.0;
}
int main() {
int tableau[] = {1, 0, 3, 0, 5};
int taille = sizeof(tableau) / sizeof(tableau[0]);
float moyenne = calculMoyenne(tableau, taille);
printf("La moyenne des éléments (hors zéros) est %.2f\n", moyenne); // Affiche 3.00
return 0;
}
Cas Particuliers :
calculMoyenne
ignore les zéros dans le calcul de la moyenne.Excel offre plusieurs méthodes pour calculer une moyenne tout en tenant compte des filtres ou…
Excel propose plusieurs fonctions pour insérer ou manipuler la date actuelle. Voici les principales méthodes…
Lorsque des nombres sont stockés sous forme de texte dans Excel, ils ne peuvent pas…
Extraire uniquement les chiffres d'une cellule contenant du texte et des nombres mélangés est une…
Pour supprimer plusieurs caractères spécifiques (par exemple, des symboles, chiffres ou lettres indésirables) dans des…
Excel permet de calculer différents types d'écarts selon le contexte, que ce soit pour des…
This website uses cookies.