Exercice 1: Gestion de Notes des étudiants (passage par valeur)

    1. Écrivez une fonction saisirNotes qui prend en paramètre un tableau de notes et la taille de ce tableau. Cette fonction permet à l’utilisateur de saisir les notes de l’étudiant. Assurez-vous que chaque note saisie est comprise entre 0 et 20. Si une note saisie est invalide, demandez à l’utilisateur de la saisir à nouveau jusqu’à ce qu’elle soit valide.

    2. Implémentez une fonction calculerMoyenne qui prend en paramètre un tableau de notes et la taille de ce tableau, et qui renvoie la moyenne des notes saisies.

    3. Développez une procédure afficherDetails qui prend en paramètre un tableau de notes, la taille de ce tableau et la moyenne calculée, et qui affiche les détails de l’étudiant, y compris ses notes et sa moyenne.

    Dans la fonction principale (main):

    1. Demandez à l’utilisateur de saisir la taille du tableau de notes.
    2. Créez un tableau de notes de la taille saisie.

    3. Appelez la fonction saisirNotes pour permettre à l’utilisateur de saisir les notes de l’étudiant.

    4. Utilisez la fonction calculerMoyenne pour calculer la moyenne des notes saisies.

    5. Appelez la procédure afficherDetails pour afficher les détails de l’étudiant, y compris ses notes et sa moyenne.

Solution commentée :

				
					#include "stdio.h"

//Declaration des fonctions
void saisirNotes(float note[],int N);
/*
Dans les fonctions CalculerMoyenne et afficherDetails,
il faut passer la longueur du tableau en paramètre,
car le tableau devient un pointeur lorsqu’il est
transmis à une fonction. Donc on ne peut pas utiliser
sizeof à l'interieur de la fonction.
*/
float calculerMoyenne(float note[],int N);
void afficherDetails(float note[],int N);


int main()
{
	int N;
	printf("Quel est le nombre d'etudiant? ");
	scanf("%d",&N);
	float note[N];
  	saisirNotes(note,N);
  	afficherDetails(note,N);

	return 0;
}


void saisirNotes(float note[],int N)
{
	int i=0;

	while(i<N)
	{
		/*
		Boucle do while pour obliger l'utilisateur de
		saisir une note comprise entre 0 et 20
		*/
		do
		{
			printf("Saisir la note de l'etudiant %i : ",i+1);
			scanf("%f",&note[i]);
			if((note[i]>20 || note[i] < 0))
			{
				printf("La note saisie n'est pas correcte!\n");
			}
		}
		while (note[i]>20 || note[i] < 0);
		i++;
	}
}

float calculerMoyenne(float note[],int N)
{
	float somme = 0;
	for(int i=0;i<N;i++) somme+=note[i];
	return somme/N;
}

void afficherDetails (float note[],int N)
{
	float Moyenne;
	//Calcul de la moyenne
	Moyenne = calculerMoyenne(note,N);
	printf("La note des étudiants :\n");
	for(int i=0;i<N;i++) printf(" - Note de l'étudiant %d : %0.3f/20\n",i+1,note[i]);
	printf("La moyenne de la classe %0.3f / 20 : ",Moyenne);
}
				
			

Exercice 2: Manipulation de Chaînes de Caractères (passage par adresse)

  1. Écrivez une fonction compterCaracteres qui prend en paramètre une chaîne de caractères et renvoie le nombre de caractères dans cette chaîne.
  2. Implémentez une fonction inverserChaine qui prend en paramètre une chaîne de caractères et inverse cette chaîne.
  3. Développez une procédure afficherChaine qui prend en paramètre une chaîne de caractères et affiche cette chaîne.

Dans la fonction principale (main):

  1. demandez à l’utilisateur de saisir une chaîne de caractères.
  2. Appelez la fonction afficherChaine pour afficher la chaîne de caractères saisie.
  3. Utilisez la fonction compterCaracteres pour compter le nombre de caractères dans la chaîne saisie, puis affichez ce nombre.
  4. Appelez la fonction inverserChaine pour inverser la chaîne saisie.
  5. Affichez la chaîne inversée à l’écran.

Solution commentée :

				
					#include <stdio.h>
int compterCaracteres(char *chaine)
{
	/*
	Attention : la fonction compterCaracteres doit 
	recevoir l’argument chaine comme pointeur (*).
	Sinon, elle peut le recevoir comme tableau char chaine[], 
	car en C un tableau se comporte comme un pointeur.
	*/
	int i=0;
	//La boucle while contient une seule commande pas besoin des {}
	while (chaine[i]!='\0') i++; 
	return i;
}

void inverserChaine(char *chaine)
{
	//Déclaration des variables 
	/*
	N : La longueur de la chaine 
	i = 0 : pour accéder au début de la chaîne 
	j = N - 1 : Pour accéder à la fin de la chaîne
	*/
	int N = compterCaracteres(chaine), i = 0, j = N-1;
	/* variable temporaire "temp" pour stocker 
	le caractère avant la permutation*/
	char temp;
	while (i<j)
	{
		//Permutation des caractère de la chaîne 
		temp=chaine[j];
		chaine[j]=chaine[i];
		chaine[i]=temp;

		i++; // incrémente i de 1
		j--; // décrémente j de 1

	}
}


void afficherChaine(char *chaine)
{
	//Affichage avec la fonction printf marche bien
	//printf("%s\n",chaine);
	//On peut afficher la chaîne avec la boucle for aussi
	for (int i=0;chaine[i]!='\0';i++) printf("%c",chaine[i]); 
	printf("\n");
}


int main()
{
	
	char chaine[500]="Mohamed";

	printf("Saisir une chaine de caractère\n");
	/*
	Ici il faut pas utiliser les fonctions 
		=> scanf : car elle s'arrête s’arrête automatiquement 
		au premier caractère blanc, comme :
			- espace ' '
			-tabulation \t
			-retour à la ligne \n
		=> fegts(chaine,sizeof(chaine),stdin) : car il rajoute
		retoure à la ligne après avoir saisie la chaine à partir 
		de stdin (Standard input "Clavier")\n 
	*/
	gets(chaine);
	printf("Affichage de la chaine avant l'inversement: \n");
	afficherChaine(chaine);
	inverserChaine(chaine);
	printf("ffichage de la chaine après l'inversement: \n");
	afficherChaine(chaine);
	printf("La longueur de la chaine est : %d",compterCaracteres(chaine));
	return 0;
}
				
			

Exercice 1: Calcul de la somme des entiers jusqu'à n (Passage par adresse)

Vous devez développer un programme en langage C qui utilise une fonction récursive pour calculer la somme des entiers de 1 jusqu’à un nombre entier positif n saisi par l’utilisateur. L’objectif est d’utiliser le passage par adresse pour stocker la somme calculée dans le programme principal.

Instructions :

  1. Dans votre programme, demandez à l’utilisateur de saisir un nombre entier positif n.

  2. Implémentez une fonction récursive sommeEntiers qui prend en paramètres un entier n et un pointeur vers un entier somme. Cette fonction doit calculer la somme des entiers de 1 jusqu’à n et stocker le résultat dans la variable pointée par somme.

  3. La fonction sommeEntiers devrait être appelée récursivement en diminuant la valeur de n à chaque appel jusqu’à ce que n devienne égal à 0.

  4. Assurez-vous de gérer le cas de base où n est égal à 0, dans lequel la fonction doit simplement retourner sans aucun calcul supplémentaire.

  5. Utilisez le passage par adresse pour stocker la somme calculée dans la fonction sommeEntiers.

  6. Dans le programme principal (main), appelez la fonction sommeEntiers avec n et l’adresse de la variable somme pour stocker le résultat.

  7. Affichez la somme calculée à l’aide de la variable somme dans le programme principal.

Solution commentée :

				
					#include "stdio.h"

// Fonction récursive qui calcule la somme des entiers de 0 à N
int sommeentier(int N, int *somme)
{	
    // Quitter la fonction si N est négatif
    if (N < 0)
    {
        // Code d'erreur
        return 1;
    }
    // Ajouter N à la somme (Pointeur !!)
    *somme += N;
    // Condition d'arrêt : lorsque N atteint 0
    if (N == 0)
    {
        return 0;
    }
    // Appel récursif
    return sommeentier(N - 1, somme);
}

int main()
{
    // Initialisation des variables
    int N, somme = 0;
    printf("Saisir un nombre entier positif N = ");
    scanf("%d", &N);
    /*
        Pour les entiers négatifs, afficher un message d’erreur
        en se basant sur le code d’erreur retourné par la fonction.
        La fonction reçoit 'somme' sous forme de pointeur.
    */
    if (sommeentier(N, &somme))
    {
        printf("Erreur : N doit être positif !\n");
        return 0;
    }
    // Affichage du résultat
    printf("La somme de 0 jusqu'à %d est %d\n", N, somme);
    return 0;
}

				
			

Exercice 2 : Tri fusion récursif

Vous devez développer un programme en langage C qui trie un tableau d’entiers en utilisant l’algorithme de tri fusion. L’objectif est de permettre à l’utilisateur de saisir les éléments du tableau et de trier ensuite ce tableau en utilisant le tri fusion.

Instructions :

  1. Demandez à l’utilisateur de saisir la taille du tableau d’entiers. Assurez-vous que la taille saisie est un entier positif

  2. À l’aide de la fonction saisirTableau, permettez à l’utilisateur de saisir les éléments du tableau un par un.

  3. Implémentez une fonction récursive triFusion pour trier le tableau d’entiers en utilisant l’algorithme de tri fusion. Cette fonction devrait prendre en compte les indices de début et de fin du tableau.

  4. Implémentez une fonction fusionner qui fusionne deux sous-tableaux triés en un seul tableau trié.

  5. Affichez le contenu du tableau trié à l’aide de la fonction afficherTableau.

  6. Assurez-vous que votre programme est capable de gérer correctement les erreurs de saisie de l’utilisateur.

Solution commentée :

				
					#include <stdio.h>
#include <stdlib.h>
// Prototypes
int saisirTableau(int N, int *tab,int M);
void afficherTableau(int tab[], int N);
void triFusion(int tab[], int deb, int fin);
void fusionner(int tab[], int deb, int milieu, int fin);

int main(void) {
    int N,tab[1000];
    printf("Saisir la taille du tableau N=");
    scanf("%d",&N);
    

    if (saisirTableau(N,&tab, N))
    {
        printf("Erreur : la taille doit être un entier positif.\n");
        return 0;
    }

    printf("Tableau saisi : ");
    afficherTableau(tab, N);

    triFusion(tab, 0, N - 1);

    printf("Tableau trié : ");
    afficherTableau(tab, N);

    return 0;
}

// Lit N et le tableau, retourne 1 si OK, 0 sinon
int saisirTableau(int N, int *tab,int M)
{   
    if (N==0) return 0;
    if (N<0) return 1;
    printf("tab[%d]=",M-N);
    scanf("%d",&tab[M-N]);
    saisirTableau(N-1,tab,M);
}


// Affiche un tableau d'entiers
void afficherTableau(int tab[], int N) {
    if (N <= 0) {
        printf("[]\n");
        return;
    }
    printf("[");
    for (int i = 0; i < N; i++) {
        printf("%d", tab[i]);
        if (i < N - 1) printf(", ");
    }
    printf("]\n");
}

// triFusion : tri récursif du sous-tableau tab[deb..fin]
void triFusion(int tab[], int deb, int fin) {
    int i=0;
    printf("%d-Appelle à la fonction ,%d,%d,%d\n",i,deb, fin,deb < fin);
    if (deb < fin) {
       int milieu = deb + (fin - deb) / 2;
       i++;
        printf("%d-Recursive 1 :  %d,%d,%d\n",i,deb,milieu,deb < milieu);
        triFusion(tab, deb, milieu);  
         i++;
        printf("%d-Recursive 2 :  %d,%d,%d\n",i,milieu+1,fin,milieu+1 < fin); 
        triFusion(tab, milieu + 1, fin);
        
         i++;
        printf("%d-Fusionner %d,%d,%d\n",i,deb,milieu, fin);
        fusionner(tab, deb, milieu, fin);
       
    }
       
     
}

// fusionner deux sous-tableaux triés : tab[deb..milieu] et tab[milieu+1..fin]
void fusionner(int tab[], int deb, int milieu, int fin) {

    printf("Fusionner interne:%d,%d,%d \n",deb,milieu,fin);
    int n1 = milieu - deb + 1;
    int n2 = fin - milieu;

    // allouer des sous-tableaux temporaires
    int *gauche = malloc(n1 * sizeof(int));
    int *droite = malloc(n2 * sizeof(int));
    if (gauche == NULL || droite == NULL) {
        printf("Erreur d'allocation mémoire dans fusionner.\n");
        exit(1);
    }

    // copier les données
    for (int i = 0; i < n1; i++) gauche[i] = tab[deb + i];
    for (int j = 0; j < n2; j++) droite[j] = tab[milieu + 1 + j];

    int i = 0, j = 0, k = deb;

    // fusionner en ordre croissant
    while (i < n1 && j < n2) {
        if (gauche[i] <= droite[j]) {
            tab[k++] = gauche[i++];
        } else {
            tab[k++] = droite[j++];
        }
    }
    // copier le reste s’il y en a
    while (i < n1) {
        tab[k++] = gauche[i++];
    }
    while (j < n2) {
        tab[k++] = droite[j++];
    }

    free(gauche);
    free(droite);
}