add Algo's correction, english images and systeme folder

master
Antoine PEREDERII 2 years ago
parent 356c63b7aa
commit c27ba2958c

@ -0,0 +1,34 @@
# CC : le compilateur à utiliser
CC=clang
# CFLAGS : les options de compilation
CFLAGS=-Wall
# Les fichiers sources : tous les fichiers présents dans src/
SRC=$(wildcard src/*.c)
# Les fichiers objets (.o)
OBJ=$(patsubst src/%.c,obj/%.o,$(SRC))
# Le répertoire où sera générée la documentation Doxygen
DOXYGEN_OUTPUT_DIR=docs
# Édition des liens : génération de l'exécutable à partir des .o
bin/exe: $(OBJ)
$(CC) $(OBJ) -o $@
# Génération des .o à partir des .c correspondants
obj/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
# Génération de la documentation Doxygen
doxygen:
doxygen Doxyfile
# Exécution du programme avec Valgrind
valgrind: bin/exe
valgrind --leak-check=full ./bin/exe
# Nettoyage : destruction des .o, de l'exécutable et de la documentation
clean:
rm -rf obj/*.o bin/exe $(DOXYGEN_OUTPUT_DIR)

@ -0,0 +1,148 @@
#include "abr_exo1.h"
#include <stdio.h>
#include <stdlib.h>
ABR creerArbreVide(){
return NULL;
}
Booleen estArbreVide(ABR a){
return (a==NULL)? VRAI:FAUX ;
}
NoeudABR* creerNoeud(int val){
NoeudABR* tmp = (NoeudABR*) malloc(sizeof(NoeudABR));
if(tmp == NULL) exit(1);
tmp->fg = NULL;
tmp->fd = NULL;
tmp->val = val;
return tmp;
}
void insererEnFeuille(ABR* pta, int val){
if(*pta == NULL){
*pta = creerNoeud(val);
}
else if (val <= (*pta)->val){
insererEnFeuille(&(*pta)->fg, val);
}
else{
insererEnFeuille(&(*pta)->fd, val);
}
}
void viderArbre(ABR* pta){
if(*pta != NULL){
viderArbre(&(*pta)->fg);
viderArbre(&(*pta)->fd);
free(*pta);
*pta = NULL;
}
}
void afficherCroissant(ABR a){
if (a!= NULL){
afficherCroissant(a->fg);
printf("%d, ", a->val);
afficherCroissant(a->fd);
}
}
void afficherDecroissant(ABR a){
if(a!=NULL){
afficherDecroissant(a->fd);
printf("%d, ", a->val);
afficherDecroissant(a->fg);
}
}
// pour l'affichage couché :
void afficherNtab(int n){for(int i = 0; i<n; i++) printf("\t"); }
void afficherCoucheRec(ABR a, int retrait){
if(a->fd !=NULL){
afficherCoucheRec(a->fd, retrait+1);
afficherNtab(retrait); printf(" / \n");
}
afficherNtab(retrait); printf("%d\n", a->val);
if(a->fg !=NULL){
afficherNtab(retrait); printf(" \\ \n");
afficherCoucheRec(a->fg,retrait+1);
}
}
void afficherCouche(ABR a){
if(a!=NULL)
afficherCoucheRec(a,0);
}
Booleen rechercherVal(ABR a, int val){
if(a==NULL) return FAUX;
if(a->val == val) return VRAI;
if(val < a->val) return rechercherVal(a->fg,val);
else return rechercherVal(a->fd,val);
}
//--------------------------------------------------------
// pour la suppression
// supprime le noeud contenant la valeur max de l'arbre
// et retourne sa valeur.
// ATTENTION : *pta doit être un arbre non vide
int oterMax(ABR * pta){
NoeudABR * tmp;
int val;
if((*pta)->fd==NULL){
tmp = *pta;
val = tmp->val;
*pta = (*pta)->fg;
free(tmp);
}
else{
val = oterMax(&(*pta)->fd);
}
return val;
}
Booleen supprimerVal(ABR *pta, int val){
NoeudABR* tmp;
Booleen b;
if(*pta==NULL) return FAUX;
// si la valeur est à la racine de l'arbre
if ((*pta)->val == val){
if((*pta)->fg == NULL){
tmp = *pta;
*pta = (*pta)->fd;
free(tmp); //////////////// et non pas free(*A);
}
else if((*pta)->fd == NULL ){
tmp = *pta;
*pta = (*pta)->fg;
free(tmp); //////////////// et non pas free(*A);
}
else /// cad si ((*pta)->fd != NULL && (*pta)->fg != NULL)
(*pta)->val = oterMax(&(*pta)->fg);
return VRAI;
}
// sinon on continue dans la suite de l'arbre ( à gauche ou à droite)
else if (val < (*pta)->val){
b = supprimerVal(&(*pta)->fg, val);
}
else{
b = supprimerVal(&(*pta)->fd, val);
}
return b;
}

@ -0,0 +1,94 @@
/**
\file abr_exo1.h
\author C. SIMON
\date 02/07/2022
\brief package des ABR : structure et fonctionnalités de base
*/
#ifndef ABR_EXO1_H
#define ABR_EXO1_H
#include "pratique.h"
/**
\brief structure de noeud pour un ABR
*/
typedef struct noeudABR{
int val; /**< valeur contenue dans le noeud */
struct noeudABR* fg; /**< adresse du sous-arbre gauche */
struct noeudABR* fd; /**< adresse du sous-arbre droit */
}NoeudABR;
/**
\brief définition d'un ABR
*/
typedef NoeudABR* ABR;
/**
\brief crée un arbre vide
\return l'arbre vide créé
*/
ABR creerArbreVide();
/**
\brief indique si l'arbre a est vide
\return VRAI si l'arbre est vide, FAUX sinon
*/
Booleen estArbreVide(ABR a);
/**
\brief insère en feuille
\param pta l'adresse de l'ABR à modifier
\param val la valeur à insérer dans l'ABR
*/
void insererEnFeuille(ABR* pta, int val);
/**
\brief vide l'ABR en libérant la mémoire
\param pta l'adresse de l'ABR à modifier
*/
void viderArbre(ABR* pta);
/**
\brief affiche les valeurs de l'ABR en liste croissante
\param a l'ABR dont on souhaite afficher les valeurs
*/
void afficherCroissant(ABR a);
/**
\brief affiche les valeurs de l'ABR en liste décroissante
\param a l'ABR dont on souhaite afficher les valeurs
*/
void afficherDecroissant(ABR a);
/**
\brief affiche l'ABR dessiné couché
\param a l'ABR à afficher
*/
void afficherCouche(ABR a);
/**
\brief recherche et indique si la valeur passée en paramètre
est dans l'ABR ou pas
\param a l'ABR dans lequel on souhaite effectuer la recherche
\param val la valeur cherchée
\return VRAI si la valeur est dans l'ABR, FAUX sinon
*/
Booleen rechercherVal(ABR a, int val);
/**
\brief supprime la première occurrence de la valeur dans l'arbre
si la valeur y est, ou ne fait rien si elle n'y est pas
\param pta l'adresse de l'ABR à modifier
\param val la valeur à supprimer dans l'ABR
*/
Booleen supprimerVal(ABR *pta, int val);
#endif // ABR_EXO1_H

@ -0,0 +1,220 @@
#include "avl_exo2.h"
#include <stdio.h>
#include <stdlib.h>
AVL creerArbreVide(){
return NULL;
}
Booleen estArbreVide(AVL a){
return (a==NULL)? VRAI:FAUX ;
}
void viderArbre(AVL* pta){
if(*pta != NULL){
viderArbre(&(*pta)->fg);
viderArbre(&(*pta)->fd);
free(*pta);
*pta = NULL;
}
}
void afficherCroissant(AVL a){
if (a!= NULL){
afficherCroissant(a->fg);
printf("%d, ", a->val);
afficherCroissant(a->fd);
}
}
void afficherDecroissant(AVL a){
if(a!=NULL){
afficherDecroissant(a->fd);
printf("%d, ", a->val);
afficherDecroissant(a->fg);
}
}
// pour l'affichage couché :
void afficherNtab(int n){for(int i = 0; i<n; i++) printf("\t"); }
void afficherCoucheRec(AVL a, int retrait){
if(a->fd !=NULL){
afficherCoucheRec(a->fd, retrait+1);
afficherNtab(retrait); printf(" / \n");
}
afficherNtab(retrait); printf("%d (%d)\n", a->val, a->h);
if(a->fg !=NULL){
afficherNtab(retrait); printf(" \\ \n");
afficherCoucheRec(a->fg,retrait+1);
}
}
void afficherCouche(AVL a){
if(a!=NULL)
afficherCoucheRec(a,0);
}
Booleen rechercherVal(AVL a, int val){
if(a==NULL) return FAUX;
if(a->val == val) return VRAI;
if(val < a->val) return rechercherVal(a->fg,val);
else return rechercherVal(a->fd,val);
}
// précondition : a n'est pas vide
void mettreAjourHauteur(AVL a){
int hg, hd;
if(a->fg==NULL) hg = -1;
else hg = a->fg->h;
if(a->fd==NULL) hd = -1;
else hd = a->fd->h;
if(hg>hd) a->h = 1+hg;
else a->h = 1+hd;
}
// ------------ pour les rotations
void rotationGauche(AVL* pta){
NoeudAVL* racine = (*pta)->fd;
(*pta)->fd = racine->fg;
mettreAjourHauteur(*pta);
racine->fg = *pta;
mettreAjourHauteur(racine);
*pta = racine;
}
void rotationDroite(AVL* pta){
NoeudAVL* racine = (*pta)->fg;
(*pta)->fg = racine->fd;
mettreAjourHauteur(*pta);
racine->fd = *pta;
mettreAjourHauteur(racine);
*pta = racine;
}
NoeudAVL* creerNoeud(int val){
NoeudAVL* tmp = (NoeudAVL*) malloc(sizeof(NoeudAVL));
if(tmp == NULL) exit(1);
tmp->fg = NULL;
tmp->fd = NULL;
tmp->val = val;
tmp->h = 0;
return tmp;
}
void reequilibrer(AVL* pta){
int hg, hd, hgf, hdf;
hg = ((*pta)->fg != NULL)? (*pta)->fg->h : -1;
hd = ((*pta)->fd != NULL)? (*pta)->fd->h : -1;
if(hg - hd == 2){ // déséquilibre : hg > hd de 2
hgf = ((*pta)->fg->fg != NULL)? (*pta)->fg->fg->h : -1;
hdf = ((*pta)->fg->fd != NULL)? (*pta)->fg->fd->h : -1;
if(hdf > hgf) rotationGauche(&(*pta)->fg);
rotationDroite(pta);
}
else if(hd - hg == 2){ // déséquilibre : hd > hg de 2
hgf = ((*pta)->fd->fg != NULL)? (*pta)->fd->fg->h : -1; /////
hdf = ((*pta)->fd->fd != NULL)? (*pta)->fd->fd->h : -1; /////
if(hgf > hdf) rotationDroite(&(*pta)->fd);
rotationGauche(pta);
}
else{ // pas de déséquilibre, on remet juste la hauteur à jour
if(hd > hg) (*pta)->h = hd+1;
else (*pta)->h = hg+1;
}
}
// version insertion qui conserve l'équilibre de l'AVL
void insererEquilibre(AVL* pta, int val){
if(*pta == NULL){
*pta = creerNoeud(val);
}
else{
if (val <= (*pta)->val){
insererEquilibre(&(*pta)->fg, val);
}
else{
insererEquilibre(&(*pta)->fd, val);
}
reequilibrer(pta);
}
}
// pour la suppression
// supprime le noeud contenant la valeur max de l'arbre
// et retourne sa valeur.
// ATTENTION : *pta doit être un arbre non vide
int oterMax(AVL * pta){
NoeudAVL * tmp;
int val;
if((*pta)->fd==NULL){
tmp = *pta;
val = tmp->val;
*pta = (*pta)->fg;
free(tmp);
}
else{
val = oterMax(&(*pta)->fd);
reequilibrer(pta);
}
return val;
}
Booleen supprimerVal(AVL *pta, int val){
NoeudAVL* tmp;
Booleen b;
if(*pta==NULL) return FAUX;
// si la valeur est à la racine de l'arbre
if ((*pta)->val == val){
if((*pta)->fg == NULL){
tmp = *pta;
*pta = (*pta)->fd;
free(tmp);
// rien à faire pour la hauteur
// et pas de ré-èquilibration à faire ici
}
else if((*pta)->fd == NULL ){
tmp = *pta;
*pta = (*pta)->fg;
free(tmp);
// rien à faire pour la hauteur
// et pas de ré-èquilibration à faire
}
else{ /// cad si ((*pta)->fd != NULL && (*pta)->fg != NULL)
(*pta)->val = oterMax(&(*pta)->fg);
reequilibrer(pta);
}
return VRAI;
}
// sinon on continue dans la suite de l'arbre ( à gauche ou à droite)
else{
if (val < (*pta)->val){
b = supprimerVal(&(*pta)->fg, val);
}
else{
b = supprimerVal(&(*pta)->fd, val);
}
if(b) reequilibrer(pta);
}
return b;
}

@ -0,0 +1,98 @@
/**
\file avl_exo2.h
\author C. SIMON
\date 02/07/2022
\brief package des AVL : structure et fonctionnalités de base
*/
#ifndef AVL_EXO2_H
#define AVL_EXO2_H
#include "pratique.h"
/**
\brief structure de noeud pour un AVL
*/
typedef struct noeudAVL{
int val; /**< valeur contenue dans le noeud */
struct noeudAVL* fg; /**< adresse du sous-arbre gauche */
struct noeudAVL* fd; /**< adresse du sous-arbre droit */
int h; /**< hauteur du noeud : = 0 si pas de fils,
sinon = 1+ max ( h du ss-arbre gauche, h du ss-arbre droit)
*/
}NoeudAVL;
/**
\brief définition d'un AVL
*/
typedef NoeudAVL* AVL;
/**
\brief crée un arbre vide
\return l'arbre vide créé
*/
AVL creerArbreVide();
/**
\brief indique si l'arbre a est vide
\return VRAI si l'arbre est vide, FAUX sinon
*/
Booleen estArbreVide(AVL a);
/**
\brief insère en feuille
\param pta l'adresse de l'AVL à modifier
\param val la valeur à insérer dans l'AVL
*/
void insererEquilibre(AVL* pta, int val);
/**
\brief vide l'AVL en libérant la mémoire
\param pta l'adresse de l'AVL à modifier
*/
void viderArbre(AVL* pta);
/**
\brief affiche les valeurs de l'AVL en liste croissante
\param a l'AVL dont on souhaite afficher les valeurs
*/
void afficherCroissant(AVL a);
/**
\brief affiche les valeurs de l'AVL en liste décroissante
\param a l'AVL dont on souhaite afficher les valeurs
*/
void afficherDecroissant(AVL a);
/**
\brief affiche l'AVL dessiné couché
\param a l'AVL à afficher
*/
void afficherCouche(AVL a);
/**
\brief recherche et indique si la valeur passée en paramètre
est dans l'AVL ou pas
\param a l'AVL dans lequel on souhaite effectuer la recherche
\param val la valeur cherchée
\return VRAI si la valeur est dans l'AVL, FAUX sinon
*/
Booleen rechercherVal(AVL a, int val);
/**
\brief supprime la première occurrence de la valeur dans l'arbre
si la valeur y est, ou ne fait rien si elle n'y est pas
\param pta l'adresse de l'AVL à modifier
\param val la valeur à supprimer dans l'AVL
*/
Booleen supprimerVal(AVL *pta, int val);
#endif // AVL_EXO2_H

@ -0,0 +1,12 @@
/**
\file pratique.h
\author C. SIMON
\date 02/07/2022
\brief fichier contenant des types ou fonctionnalités utiles
*/
#ifndef PRATIQUE
#define PRATIQUE
typedef enum {FAUX, VRAI}Booleen;
#endif // PRATIQUE

@ -0,0 +1,117 @@
#include "abr_exo1.h" // les ABR
#include <stdio.h>
#include <time.h>
void testExo1(){
Booleen b;
ABR a = creerArbreVide();
if(estArbreVide(a)) printf("OK : l'arbre est vide à sa création\n");
else printf("ERREUR : l'arbre devrait être vide à sa création\n");
insererEnFeuille(&a, 10);
if(! estArbreVide(a))
printf("OK : l'arbre n'est pas vide après une insertion\n");
else
printf("ERREUR : l'arbre devrait ne pas être vide après une insertion\n");
insererEnFeuille(&a, 5);
insererEnFeuille(&a, 15);
insererEnFeuille(&a, 7);
insererEnFeuille(&a, 20);
printf("après insertion de 10,5,15,7 et 20\n");
afficherCouche(a);
insererEnFeuille(&a, 6);
insererEnFeuille(&a, 3);
insererEnFeuille(&a, 8);
insererEnFeuille(&a, 2);
insererEnFeuille(&a, 4);
insererEnFeuille(&a, 17);
printf("après insertion de 6,3,8,2,4 et 17\n");
afficherCouche(a);
afficherCroissant(a); printf("\n");
afficherDecroissant(a);printf("\n");
b = rechercherVal(a, 7);
if(b) printf("OK : 7 trouvé\n");
else printf("ERREUR : 7 pas trouvé\n");
b = rechercherVal(a, 16);
if(b) printf("ERREUR : 16 trouvé\n");
else printf("OK : 16 pas trouvé\n");
printf(" suppression de 10\n");
b=supprimerVal(&a,10);
if(b) printf("OK : 10 a été supprimé\n");
else printf("ERREUR : 10 n'a pas pu être supprimé\n");
afficherCouche(a);
viderArbre(&a);
if(estArbreVide(a)) printf("OK : l'arbre a bien été vidé\n");
else printf("ERREUR : l'arbre n'a pas été vidé visiblement\n");
}
void mesureTemps(int nb){
Booleen b;
ABR a = creerArbreVide();
clock_t t;
double temps;
printf("TEST pour ABR déséquilibré de %d noeuds : \n", nb);
t = clock();
for(int i = 1; i<=nb ; i++)
insererEnFeuille(&a, i);
t = clock() - t;
temps = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("\t temps de la construction : %f s\n", temps);
t = clock();
b = rechercherVal(a, -1);
t = clock() - t;
temps = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("\t temps pour la recherche de -1 : %f s\n", temps);
t = clock();
b = rechercherVal(a, nb/2);
t = clock() - t;
temps = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("\t temps pour la recherche de %d : %f s\n", nb/2, temps);
t = clock();
b = rechercherVal(a, nb+1);
t = clock() - t;
temps = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("\t temps pour la recherche de %d : %f s\n", nb+1, temps);
t = clock();
viderArbre(&a);
t = clock() - t;
temps = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("\t temps pour vider l'arbre : %f s\n\n", temps);
}
void testExo3(){
mesureTemps(10000);
mesureTemps(50000);
mesureTemps(100000);
}
int main(void){
// testExo1();
testExo3();
return 0;
}

@ -0,0 +1,102 @@
#include "avl_exo2.h" // les AVL
#include <stdio.h>
#include <time.h>
void testExo2(){
Booleen b;
AVL a = creerArbreVide();
if(estArbreVide(a)) printf("OK : l'arbre est vide à sa création\n");
else printf("ERREUR : l'arbre devrait être vide à sa création\n");
insererEquilibre(&a, 10);
if(! estArbreVide(a))
printf("OK : l'arbre n'est pas vide après une insertion\n");
else
printf("ERREUR : l'arbre devrait ne pas être vide après une insertion\n");
afficherCouche(a);
insererEquilibre(&a, 5);
afficherCouche(a);
insererEquilibre(&a, 15);
afficherCouche(a);
insererEquilibre(&a, 12);
afficherCouche(a);
insererEquilibre(&a, 7);
afficherCouche(a);
insererEquilibre(&a, 8);
afficherCouche(a);
insererEquilibre(&a, 9);
printf("après insertion de 10,5,15,12,7,8 et 9\n");
afficherCouche(a);
printf(" suppression de 5\n");
b=supprimerVal(&a,5);
if(b) printf("OK : 5 a été supprimé\n");
else printf("ERREUR : 5 n'a pas pu être supprimé\n");
afficherCouche(a);
viderArbre(&a);
if(estArbreVide(a)) printf("OK : l'arbre a bien été vidé\n");
else printf("ERREUR : l'arbre n'a pas été vidé visiblement\n");
}
void mesureTemps(int nb){
Booleen b;
AVL a = creerArbreVide();
clock_t t;
double temps;
printf("TEST pour AVL de %d noeuds : \n", nb);
t = clock();
for(int i = 1; i<=nb ; i++)
insererEquilibre(&a, i);
t = clock() - t;
temps = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("temps de la construction : %f s\n", temps);
t = clock();
b=rechercherVal(a, -1);
t = clock() - t;
temps = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("temps pour la recherche de -1 : %f s\n", temps);
t = clock();
b = rechercherVal(a, nb/2);
t = clock() - t;
temps = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("\t temps pour la recherche de %d : %f s\n", nb/2, temps);
t = clock();
b = rechercherVal(a, nb+1);
t = clock() - t;
temps = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("\t temps pour la recherche de %d : %f s\n", nb+1, temps);
t = clock();
viderArbre(&a);
t = clock() - t;
temps = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("\t temps pour vider l'arbre : %f s\n\n", temps);
}
void testExo3(){
mesureTemps(10000);
mesureTemps(50000);
mesureTemps(100000);
}
int main(void){
//testExo2();
testExo3();
return 0;
}

@ -0,0 +1,34 @@
# CC : le compilateur à utiliser
CC=clang
# CFLAGS : les options de compilation
CFLAGS=-Wall
# Les fichiers sources : tous les fichiers présents dans src/
SRC=$(wildcard src/*.c)
# Les fichiers objets (.o)
OBJ=$(patsubst src/%.c,obj/%.o,$(SRC))
# Le répertoire où sera générée la documentation Doxygen
DOXYGEN_OUTPUT_DIR=docs
# Édition des liens : génération de l'exécutable à partir des .o
bin/exe: $(OBJ)
$(CC) $(OBJ) -o $@
# Génération des .o à partir des .c correspondants
obj/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@
# Génération de la documentation Doxygen
doxygen:
doxygen Doxyfile
# Exécution du programme avec Valgrind
valgrind: bin/exe
valgrind --leak-check=full ./bin/exe
# Nettoyage : destruction des .o, de l'exécutable et de la documentation
clean:
rm -rf obj/*.o bin/exe $(DOXYGEN_OUTPUT_DIR)

@ -0,0 +1,49 @@
#include "codeRetour.h"
#include <stdio.h>
void afficheMessageCodeRetour(CodeRetour code){
switch(code){
case NON :
printf("non ");
break;
case OUI:
printf("oui ");
break;
case OK :
printf("ok, opération effectuée ");
break;
case PB_MEMOIRE:
printf("problème mémoire ");
break;
case PB_NOEUD_DEJA_EXISTANT:
printf("problème : noeud déjà existant ");
break;
case PB_NOEUD_DEP_NON_EXISTANT:
printf("problème : noeud de départ non existant ");
break;
case PB_NOEUD_ARR_NON_EXISTANT:
printf("problème : noeud d'arrivée non existant ");
break;
case PB_NOEUD_NON_EXISTANT:
printf("problème : noeud non existant ");
break;
case PB_ARC_DEJA_EXISTANT:
printf("problème : arc déjà existant ");
break;
case PB_ARC_NON_EXISTANT:
printf("problème : arc non existant ");
break;
case PB_OUVERTURE_FICHIER:
printf("problème ouverture du fichier ");
break;
case PB_RESEAU_ERRONNE:
printf("problème : réseau erroné ");
break;
default :
printf("ERREUR : code retour inconnu\n");
}
printf("\n");
}

@ -0,0 +1,41 @@
/**
\file codeRetour.h
\author C. SIMON
\date 03/07/2022
\brief gestion des codes de retour qui peuvent être retournés par les
primitives de gestion des réseaux
*/
#ifndef CODERETOUR_H
#define CODERETOUR_H
/**
* énumération de constantes pour gérer différents retour de fonctions
* concernant les réseaux
*/
typedef enum{
NON,
OUI,
OK,
PB_MEMOIRE,
PB_NOEUD_DEJA_EXISTANT,
PB_NOEUD_DEP_NON_EXISTANT,
PB_NOEUD_ARR_NON_EXISTANT,
PB_NOEUD_NON_EXISTANT,
PB_ARC_DEJA_EXISTANT,
PB_ARC_NON_EXISTANT,
PB_OUVERTURE_FICHIER,
PB_RESEAU_ERRONNE
} CodeRetour;
/**
\brief gère l'affichage de chaque code de retour par un message
explicite à l'écran
\param code le code à afficher
*/
void afficheMessageCodeRetour(CodeRetour code);
#endif // CODERETOUR_H

@ -0,0 +1,500 @@
#include<stdlib.h>
#include<stdio.h>
#include"reseau.h"
/************************ question 1 ************************/
Reseau initialiser(){
return NULL;
}
CodeRetour estVide(Reseau r){
if (r==NULL) return OUI;
else return NON;
}
/************************ question 2 ************************/
/* affichage du graphe représentant le réseau */
void affiche(Reseau r){
Noeud *tmp = r;
Arc *a;
while (tmp != NULL){
printf(" %d : \n ",tmp->num);
a = tmp->listeArc;
while(a != NULL){
printf("\t -> %d \n ",a->extremite->num);
a = a->suivant;
}
tmp = tmp->suiv;
}
}
/************************ question 3 ************************/
/* retourne un pointeur sur le noeud cherché ou NULL sinon */
Noeud * rechercheNoeud(Reseau r, int num){
Noeud* tmp;
tmp = r;
while(tmp != NULL){
if(tmp->num == num) return tmp;
tmp = tmp->suiv;
}
return tmp;
}
/************************ question 4 ************************/
/*
retourne OK si l'ajout a été fait
PB_NOEUD_DEJA_EXISTANT si le noeud existe déjà (ajout non fait)
PB_MEMOIRE si problème allocation mémoire
*/
CodeRetour ajoutNoeud(Reseau *pr, int num){
Noeud * tmp;
tmp = rechercheNoeud(*pr, num);
if (tmp != NULL) return PB_NOEUD_DEJA_EXISTANT;
tmp=(Noeud*)malloc(sizeof(Noeud));
if(tmp==NULL) return PB_MEMOIRE;
tmp->num = num;
tmp->listeArc = NULL;
tmp->marque = 0;
tmp->suiv = *pr;
*pr = tmp;
return OK;
}
/************************ question 5 ************************/
/*
précondition : dep et arr pointent sur deux noeuds réels du réseau
retourne
NON si l'arc n'existe pas
OUI s'il existe
*/
CodeRetour existenceArcPt(Noeud* dep, Noeud *arr){
Arc* tmp;
tmp = dep->listeArc;
while(tmp != NULL){
if(tmp->extremite == arr) return OUI;
tmp = tmp->suivant;
}
return NON;
}
/************************/
/* retourne
PB_NOEUD_DEP_NON_EXISTANT si le noeud de départ n'existe pas
PB_NOEUD_ARR_NON_EXISTANT si le noeud d'arrivée n'existe pas
NON si l'arc n'existe pas
OUI s'il existe
*/
CodeRetour existenceConnexion(Reseau r, int dep, int arr){
Noeud *pa, *pb;
pa = rechercheNoeud(r, dep);
if(pa == NULL) return PB_NOEUD_DEP_NON_EXISTANT;
pb = rechercheNoeud(r, arr);
if(pb == NULL) return PB_NOEUD_ARR_NON_EXISTANT;
return existenceArcPt(pa, pb);
}
/************************ question 6 ************************/
/* retourne OK si l'arc allant de dep à arr a bien été ajouté
PB_NOEUD_DEP_NON_EXISTANT si dep n'existe pas
PB_NOEUD_ARR_NON_EXISTANT si arr n'existe pas
PB_ARC_DEJA_EXISTANT si l'arc existe déjà
PB_MEMOIRE si problème allocation mémoire
*/
CodeRetour ajoutArc(Reseau r, int dep, int arr){
Noeud *pa, *pb;
Arc * tmp;
pa = rechercheNoeud(r, dep);
if(pa == NULL) return PB_NOEUD_DEP_NON_EXISTANT;
pb = rechercheNoeud(r, arr);
if(pb == NULL) return PB_NOEUD_ARR_NON_EXISTANT;
if(existenceArcPt(pa,pb) == OUI) return PB_ARC_DEJA_EXISTANT;
/* sinon on ajoute cet arc */
tmp=(Arc*)malloc(sizeof(Arc));
if(tmp == NULL) return PB_MEMOIRE;
tmp->extremite = pb;
tmp->suivant = pa->listeArc;
pa->listeArc = tmp;
return OK;
}
/************************ question 7 ************************/
/* précondition dep et arr pointent sur deux noeuds existants du réseau
retourne OK si la destruction a été effectuée
PB_ARC_NON_EXISTANT si l'arc n'existait pas
*/
CodeRetour destructionArcPt(Noeud* dep, Noeud* arr){
Arc * tmp, *tmpav;
if(existenceArcPt(dep,arr) == NON) return PB_ARC_NON_EXISTANT;
/* sinon on le détruit */
tmp = dep->listeArc;
/*si c'est le premier */
if(tmp->extremite == arr)
dep->listeArc = tmp->suivant;
else{
while(tmp->extremite != arr){
tmpav = tmp;
tmp = tmp->suivant;
}
tmpav->suivant = tmp->suivant;
}
tmp->extremite = NULL;
free(tmp);
return OK;
}
/************************/
/* retourne OK si destruction effectuée
PB_NOEUD_DEP_NON_EXISTANT si dep n'existe pas
PB_NOEUD_ARR_NON_EXISTANT si arr n'existe pas
PB_ARC_NON_EXISTANT si l'arc n'existe pas
*/
CodeRetour destructionArc(Reseau r, int dep, int arr){
Noeud *pa, *pb;
pa = rechercheNoeud(r, dep);
if(pa == NULL) return PB_NOEUD_DEP_NON_EXISTANT;
pb = rechercheNoeud(r, arr);
if(pb == NULL) return PB_NOEUD_ARR_NON_EXISTANT;
return destructionArcPt(pa, pb);
}
/************************ question 8 ************************/
/* lorsque l'on détruit un noeud il faut également détruire
tous les arcs qui partent de lui et tous les arcs qui pointent
sur lui.
retourne OK si destruction effectuée
PB_NOEUD_NON_EXISTANT si num n'existe pas */
CodeRetour destructionNoeud(Reseau *pr, int num){
Noeud *ptn, *pt2;
Arc * tmpa;
/* on cherche le noeud */
ptn=rechercheNoeud(*pr, num);
if(ptn == NULL) return PB_NOEUD_NON_EXISTANT;
/* on enlève tous les arcs partant de lui */
while(ptn->listeArc != NULL){
tmpa = ptn->listeArc;
ptn->listeArc = tmpa->suivant;
free(tmpa);
}
/* on enlève tous les arcs pointant sur lui */
pt2 = *pr;
while(pt2 != NULL){
destructionArcPt(pt2, ptn);
pt2 = pt2->suiv;
}
/* on détruit le noeud en refaisant d'abord le chainage */
if(ptn == *pr)
*pr = (*pr)->suiv;
else{
// on place pt2 sur le noeud juste avant ptn
pt2 = *pr;
while(pt2->suiv !=ptn)
pt2 = pt2->suiv;
pt2->suiv = ptn->suiv;
}
free(ptn);
return OK;
}
/************************ question en plus ************************/
void destructionReseau(Reseau *pr){
while(*pr != NULL)
destructionNoeud(pr,(*pr)->num);
}
/************************ question 9 ************************/
int compteNoeud(Reseau r){
Noeud * pt;
int cpt;
pt = r;
cpt = 0;
while(pt != NULL){
pt = pt->suiv;
cpt++;
}
return cpt;
}
/************************ question 10 ************************/
int compteArc(Reseau r){
Noeud * pt;
Arc *tmp;
int cpt;
pt = r;
cpt = 0;
while(pt != NULL){
tmp = pt->listeArc;
while(tmp != NULL){
tmp = tmp->suivant;
cpt++;
}
pt = pt->suiv;
}
return cpt;
}
/*----------------------------------------------------*/
/************************ question 11 - a) ************************/
/* fonction qui détermine si une machine donnée peut communiquer avec une autre également donnée
utilise un parcours en profondeur
retourne PB_NOEUD_DEP_NON_EXISTANT
PB_NOEUD_ARR_NON_EXISTANT
OUI si dep peut communiquer avec arr
NON si dep ne peut pas communiquer avec arr (dep et arr existent)
*/
/* mise à zéro de la marque de chaque noeud */
void toutMarquerAZero(Reseau r){
Noeud * tmp = r;
while(tmp != NULL){
tmp->marque = 0;
tmp = tmp->suiv;
}
}
CodeRetour visitePourPeutCommuniquer(Noeud * pdep, Noeud * parr){
Arc* tmpa;
pdep->marque = 1;
if(pdep == parr) return OUI;
tmpa = pdep->listeArc;
while(tmpa !=NULL){
if(tmpa->extremite->marque == 0)
if(visitePourPeutCommuniquer(tmpa->extremite, parr)==OUI)
return OUI;
tmpa = tmpa->suivant;
}
return NON;
}
CodeRetour peutCommuniquer(Reseau r, int dep, int arr){
Noeud *pdep, *parr;
pdep = rechercheNoeud(r, dep);
if(pdep == NULL) return PB_NOEUD_DEP_NON_EXISTANT;
parr = rechercheNoeud(r, arr);
if(parr == NULL) return PB_NOEUD_ARR_NON_EXISTANT;
toutMarquerAZero(r);
return visitePourPeutCommuniquer(pdep, parr);
}
/************************ question 11 - b) ************************/
/* fonction qui détermine et affiche l'ensemble des noeuds avec
lesquels un noeud donné peut communiquer
utilise un parcours en profondeur
retourne PB_NOEUD_DEP_NON_EXISTANT si le neoud de départ n'existe pas
OK si l'affichage a pu se faire
*/
void visiterPourMarquerQuiPeutCommuniquer(Noeud * pdep){
Arc* tmpa;
pdep->marque = 1;
tmpa = pdep->listeArc;
while(tmpa !=NULL){
if(tmpa->extremite->marque == 0)
visiterPourMarquerQuiPeutCommuniquer(tmpa->extremite);
tmpa = tmpa->suivant;
}
}
void afficheAvecQuiCommuniquer(Reseau r, int dep){
Noeud *pdep, *tmp;
pdep = rechercheNoeud(r, dep);
if(pdep == NULL){
printf("problème : %d n'existe pas \n", dep);
return;
}
toutMarquerAZero(r);
visiterPourMarquerQuiPeutCommuniquer(pdep);
// puis on affiche tous les noeuds qui sont à 1
printf("les noeuds avec lesquels %d peut communiquer sont : \n", dep);
tmp = r;
while(tmp!= NULL){
if(tmp->marque == 1)
printf("\t %d \n", tmp->num);
tmp = tmp->suiv;
}
}
/***************** Etape 3 : question 1 ************************/
/* fonction de chargement du réseau en mémoire
en cas de problème le réseau reste vide
retourne OK si chargement effectué
PB_OUVERTURE_FICHIER si pb ouverture fichier
PB_RESEAU_ERRONNE si reseau erroné :
noeud déjà existant,
connexion entre deux noeuds non existants (un au moins),
ou si connexion déjà existante
PB_MEMOIRE si problème allocation mémoire
*/
CodeRetour chargement(char * nomFichier, Reseau * pr){
FILE * fp;
int n,m,i,a,b, num;
char code;
*pr = NULL;
fp = fopen(nomFichier,"rt");
if(fp == NULL)
return PB_OUVERTURE_FICHIER;
/* lecture du nombre de noeuds */
fscanf(fp,"%d",&n);
/* lecture du nombre de connexions */
fscanf(fp,"%d",&m);
/* lecture des noeuds */
for(i=0;i<n;i++){
fscanf(fp,"%d",&num);
code = ajoutNoeud(pr,num);
if(code == PB_NOEUD_DEJA_EXISTANT ) return PB_RESEAU_ERRONNE;
else if (code == PB_MEMOIRE) return PB_MEMOIRE;
}
/* lecture des connexions */
for(i=0;i<m;i++){
fscanf(fp,"%d",&a);
fscanf(fp,"%d",&b);
code = ajoutArc(*pr,a,b);
if(code != OK){
destructionReseau(pr);
fclose(fp);
if(code == PB_MEMOIRE) return PB_MEMOIRE;
else return PB_RESEAU_ERRONNE;
}
}
fclose(fp);
return OK;
}
/*----------------------------------------------------*/
/* fonction de sauvegarde du réseau en mémoire */
/* retourne OK si sauvegarde ok
PB_OUVERTURE_FICHIER si pb ouverture fichier
*/
CodeRetour sauvegarde(char * nomFichier, Reseau r){
int nb;
FILE *fp;
Noeud *ptn;
Arc *pta;
fp = fopen(nomFichier,"wt");
if(fp == NULL) return PB_OUVERTURE_FICHIER;
nb = compteNoeud(r);
fprintf(fp,"%d\n", nb);
nb = compteArc(r);
fprintf(fp,"%d\n", nb);
ptn = r;
while(ptn != NULL){
fprintf(fp, "%d ",ptn->num);
ptn = ptn->suiv;
}
fprintf(fp, "\n");
ptn = r;
while(ptn != NULL){
pta = ptn->listeArc;
while(pta != NULL){
fprintf(fp, "%d %d\n", ptn->num, pta->extremite->num);
pta= pta->suivant;
}
ptn = ptn->suiv;
}
fclose(fp);
return OK;
}
/******************* Etape 3 : question 2 ************************/
/* fonction qui exporte le réseau dans un fichier dot pour pouvoir
être lu par dotty
retourne OK si sauvegarde effectuée
PB_OUVERTURE_FICHIER si pb ouverture fichier
*/
CodeRetour exporte(char * nomFichier, Reseau r){
FILE *fp;
Noeud *tmp;
Arc *tmpa;
char c = '"';
fp = fopen(nomFichier,"wt");
if(fp == NULL) return PB_OUVERTURE_FICHIER;
fprintf(fp,"digraph family\n");
fprintf(fp,"{\n");
/* sauvegarde des sommets */
tmp = r;
while(tmp != NULL){
fprintf(fp,"%d [label= %cNoeud %d%c]\n",tmp->num,c,tmp->num,c);
tmp = tmp->suiv;
}
/* sauvegarde des connexions */
tmp = r;
while(tmp != NULL){
tmpa = tmp->listeArc;
while(tmpa != NULL){
fprintf(fp,"%d->%d \n",tmp->num, tmpa->extremite->num);
tmpa = tmpa->suivant;
}
tmp = tmp->suiv;
}
fprintf(fp,"}\n");
fclose(fp);
return OK;
}

@ -0,0 +1,240 @@
/**
\file reseau.h
\author C. SIMON
\date 03/07/2022
\brief un réseau informatique : la structure de donnée et ses primitives de
gestion.
Un réseau est une liste chaînée de noeuds. Chaque noeud représente un
ordinateur et connait la liste des orditeurs avec lesquells il est
connecté.
*/
#include "codeRetour.h"
#ifndef RESEAU_H
#define RESEAU_H
/**
\brief structure de noeud. Un noeud représentera un ordinateur du
réseau.
*/
typedef struct CellNoeud{
int num; /**< numero identifiant l'ordinateur */
int marque; /**< marque permettant de savoir si le noeud a déjà été
parcouru pendant le parcours en profondeur par exemple */
struct CellNoeud *suiv; /**< adresse du noeud suivant dans la liste des noeuds*/
struct CellArc *listeArc; /**< une liste d'arcs représentant la liste des
ordinateurs avec lesquels il est connecté*/
}Noeud;
/**
\brief la structure d'arc permet de représenter une connection vers un
ordinateur. Pour que les arcs puissent être chainés les uns aux autres,
chaque arc connait un suivant dans une telle liste.
*/
typedef struct CellArc{
struct CellNoeud *extremite; /**< extrémité de l'arc*/
struct CellArc *suivant; /**< arc suivant dans la liste d'arcs */
}Arc;
/**
\brief structure de réseau : un réseau est une liste des noeuds qui le composent.
*/
typedef Noeud * Reseau;
/*------------------------------------------------------*/
/* primitives de gestion de réseau : */
/*------------------------------------------------------*/
/**
\brief crée et initialise du réseau à vide
*/
Reseau initialiser();
/**
\brief vérifie si le réseau est vide
\param r le réseau
\return OUI si il est vide, NON sinon
*/
CodeRetour estVide(Reseau r);
/**
\brief affiche le réseau.
\param r le réseau à afficher
*/
void affiche(Reseau r);
/**
\brief recherche dans le réseau le noeud correspondant au numero donné.
\param r le réseau
\param num le numéro que l'on cherche
\return l'adresse du noeud si trouvé ou NULL sinon
*/
Noeud * rechercheNoeud(Reseau r, int num);
/**
\brief ajoute un noeud donné par son numéro dans le réseau donné
\param pr adresse du réseau à modifier
\param num numéro du noeud à ajouter
\return un code indiquant si l'opération a été faite ou pas
(et pour quelle raison):
- OK si l'ajout a été fait
- PB_NOEUD_DEJA_EXISTANT si le noeud existe déjà (ajout non fait)
- PB_MEMOIRE si problème allocation mémoire
*/
CodeRetour ajoutNoeud(Reseau *pr, int num);
/**
\brief Fonction indiquant si une connexion/un arc entre les deux noeuds
donnés par leur numéro existe ou non.
\param r le réseau
\param dep le numéro du noeud de départ de l'arc
\param arr le numéro du noeud d'arrivée de l'arc
\return un code :
PB_NOEUD_DEP_NON_EXISTANT si le noeud de départ n'existe pas
PB_NOEUD_ARR_NON_EXISTANT si le noeud d'arrivée n'existe pas
NON si l'arc n'existe pas (les neouds extrémité existant)
OUI s'il existe
*/
CodeRetour existenceConnexion(Reseau r, int dep, int arr);
/**
\brief ajoute un arc donné par ses extrémités dans le réseau.
En cas de problème l'arc n'est pas ajouté.
\param r le réseau
\param dep le numéro du noeud de départ de l'arc
\param arr le numéro du noeud d'arrivée de l'arc
\return un code :
OK si l'arc allant de dep à arr a bien été ajouté
PB_NOEUD_DEP_NON_EXISTANT si dep n'existe pas
PB_NOEUD_ARR_NON_EXISTANT si arr n'existe pas
PB_ARC_DEJA_EXISTANT si l'arc existe déjà
PB_MEMOIRE si problème allocation mémoire
*/
CodeRetour ajoutArc(Reseau r, int dep, int arr);
/**
\brief détruit un arc donné par les numéros de ses extrémités.
\param r le réseau
\param dep le numéro du noeud de départ de l'arc à supprimer
\param arr le numéro du noeud d'arrivée de l'arc à supprimer
\return un code :
OK si destruction effectuée
PB_NOEUD_DEP_NON_EXISTANT si dep n'existe pas
PB_NOEUD_ARR_NON_EXISTANT si arr n'existe pas
PB_ARC_NON_EXISTANT si l'arc n'existe pas
*/
CodeRetour destructionArc(Reseau r, int dep, int arr);
/**
\brief détruit un noeud(donné par son numéro)
dans un réseau donné. La destruction du noeud implique la
destruction des connections entrantes et sortantes de ce noeud
\param pr l'adresse du réseau à modifier
\param num le numéro du noeud à supprimer
\return un code :
OK si destruction effectuée
PB_NOEUD_NON_EXISTANT si numéro ne désigne pas un noeud du réseau
*/
CodeRetour destructionNoeud(Reseau *pr, int num);
/**
\brief compte le nombre de noeuds d'un réseau.
\param r le réseau
\return le nombre de noeuds composant le réseau
*/
int compteNoeud(Reseau r);
/**
\brief compte et le nombre de connexions/d'arcs d'un réseau donné.
\param r le réseau
\return le nombre d'arcs composant le réseau
*/
int compteArc(Reseau r);
/*Fonction qui détruit le réseau passé en paramètre. */
void destructionReseau(Reseau *pr);
/**
\brief détermine si une machine/noeud donnée peut communiquer avec
une autre également donnée.
\param r le réseau
\param dep le numéro de la machine de départ de la communication
\param arr le numéro de la machine d'arrivée de la communication
\return un code :
PB_NOEUD_DEP_NON_EXISTANT
PB_NOEUD_ARR_NON_EXISTANT
OUI si dep peut communiquer avec arr
NON si dep ne peut pas communiquer avec arr (dep et arr existent)
*/
CodeRetour peutCommuniquer(Reseau r, int dep, int arr);
/**
\brief détermine et affiche l'ensemble des noeuds avec
lesquels un noeud donné peut communiquer
\param r le réseau
\param dep le numéro du noeud donné
*/
void afficheAvecQuiCommuniquer(Reseau r, int dep);
// du plus : seulement si il reste du temps (ne tombera pas en exam
/*------------------------------------------------------*/
/* primitives de sauvegarde et de chargement */
/*------------------------------------------------------*/
/**
\brief charge le réseau en mémoire.
En cas de problème le réseau reste vide.
\param nomFichier le nom du fichier texte contenant le réseau
\param pr l'adresse du réseau qui est chargé
\return un code
OK si chargement effectué
PB_OUVERTURE_FICHIER si pb d'ouverture de fichier
PB_RESEAU_ERRONNE si reseau erroné :
noeud déjà existant,
connexion entre deux noeuds non existants (un au moins),
ou si connexion déjà existante
PB_MEMOIRE si problème allocation mémoire
*/
CodeRetour chargement(char * nomFichier, Reseau * pr);
/**
\brief sauvegarde le réseau dans un fichier texte.
\param nomFichier le nom du fichier texte
\param r le réseau à sauvegarder
\return un code
OK si sauvegarde effectuée
PB_OUVERTURE_FICHIER si pb ouverture fichier
*/
CodeRetour sauvegarde(char * nomFichier, Reseau r);
/**
\brief exporte le réseau dans un fichier dot
\param nomFichier le nom du fichier texte de format dot
\param r le réseau à exporter
\return un code
OK si export effectué
PB_OUVERTURE_FICHIER si pb ouverture fichier
*/
CodeRetour exporte(char * nomFichier, Reseau r);
#endif // RESEAU_H

@ -0,0 +1,167 @@
#include<stdlib.h>
#include<stdio.h>
#include "reseau.h"
#include "codeRetour.h"
int menu(){
int choix;
printf("--------------------------------\n");
printf("que desirez vous ?\n");
printf(" 0- quitter\n");
printf(" 1- ajouter un noeud \n");
printf(" 2- ajouter une connexion\n");
printf(" 3- rechercher un noeud\n");
printf(" 4- rechercher une connexion \n");
printf(" 5- detruire un noeud\n");
printf(" 6- detruire une connexion \n");
printf(" 7- detruire tout le reseau \n");
printf(" 8- connaitre le nombre de noeuds \n");
printf(" 9- connaitre le nombre de connexions \n");
printf(" 10- charger un reseau \n");
printf(" 11- sauvegarder un reseau \n");
printf(" 12- exporter un reseau \n");
printf(" 13- afficher le reseau (affichage de base) \n");
printf(" 14- savoir si une machine peut communiquer avec une autre\n");
printf(" 15- connaitre toutes les machines avec lesquelles peut communiquer une machine donnée\n");
printf("--------------------------------\n");
scanf("%d", &choix);
return choix;
}
int main(void){
Reseau r;
int choix, num, num2;
CodeRetour code;
Noeud * ptn;
char nomFichier[30];
choix = 12;
r = initialiser();
while(choix != 0){
choix = menu();
switch(choix){
case 0 : printf("au revoir \n");
break;
case 1:
printf("donner le numero du noeud a ajouter : ");
scanf("%d", &num);
code = ajoutNoeud(&r, num);
printf("ajout du noeud %d dans le réseau : \n\t", num);
afficheMessageCodeRetour(code); printf("\n");
break;
case 2:
printf("donner les deux extremites de la connexion a ajouter \n");
printf("(2 numeros separes par un espace) : ");
scanf("%d %d", &num, &num2);
code = ajoutArc(r, num, num2);
printf("ajout de l'arc %d -> %d : \n\t", num, num2);
afficheMessageCodeRetour(code); printf("\n");
break;
case 3:
printf("donner le numero du noeud à rechercher : ");
scanf("%d", &num);
ptn=rechercheNoeud(r,num);
if(ptn != NULL) printf("noeud trouve \n");
else printf("noeud non trouve \n");
break;
case 4:
printf("donner les deux extremites de la connexion à rechercher \n");
printf("(2 numeros séparés par un espace) : ");
scanf("%d %d", &num, &num2);
code = existenceConnexion(r, num, num2);
printf("l'arc %d ->%d existe-t-il? ", num, num2);
afficheMessageCodeRetour(code); printf("\n");
break;
case 5:
printf("donner le numero du noeud à détruire : ");
scanf("%d", &num);
code = destructionNoeud(&r,num);
printf("destruction du noeud %d : ",num);
afficheMessageCodeRetour(code); printf("\n");
break;
case 6:
printf("donner les deux extremites de la connexion a detruire \n");
printf("(2 numeros separes par un espace) : ");
scanf("%d %d", &num, &num2);
code = destructionArc(r, num, num2);
printf("destruction de la connexion %d->%d : ",num, num2);
afficheMessageCodeRetour(code); printf("\n");
break;
case 7:
destructionReseau(&r);
break;
case 8:
num = compteNoeud(r);
printf("le reseau comporte %d noeuds \n",num);
break;
case 9:
num = compteArc(r);
printf("le reseau comporte %d arcs \n",num);
break;
case 10: //charger
printf("quel est le nom du fichier contenant le reseau? ");
scanf("%s",nomFichier);
destructionReseau(&r); /// destruction du réseau déjà existant
code = chargement(nomFichier, &r);
printf("chargement du réseau à partir de %s : ",nomFichier);
afficheMessageCodeRetour(code); printf("\n");
break;
case 11: //sauvegarder
printf("dans quel fichier voulez vous sauver le reseau? ");
scanf("%s",nomFichier);
code= sauvegarde(nomFichier,r);
printf("sauvegarde dans %s : ", nomFichier);
afficheMessageCodeRetour(code); printf("\n");
break;
case 12: //exporter
printf("dans quel fichier voulez vous exporter le reseau? ");
scanf("%s",nomFichier);
code= exporte(nomFichier,r);
printf("export dans %s : ", nomFichier);
afficheMessageCodeRetour(code); printf("\n");
break;
case 13 :
affiche(r);
break;
case 14:
printf("numéro de la première machine : ");
scanf("%d", &num);
printf("numéro de la deuxième machine : ");
scanf("%d", &num2);
code = peutCommuniquer(r,num,num2);
printf("est-ce que %d peut communiquer avec %d : ", num,num2);
afficheMessageCodeRetour(code); printf("\n");
break;
case 15:
printf("numéro de la machine : ");
scanf("%d", &num);
afficheAvecQuiCommuniquer(r,num);
break;
default : printf("erreur de frappe ! \n");
break;
}
}
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,13 @@
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
for(int i = 0; i < argc; ++i)
printf("argument %d : %s \n", i, argv[i]);
puts("\n----------------\n"); //mieux qu'un printf car moins gourmand pour char()
printf("PATH => %s\n", getenv("PATH"));
return 0;
}

Binary file not shown.

@ -0,0 +1,20 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(void) {
if(system("ps -f") == -1) {
perror("pb appel systeme");
exit(errno);
}
if(execlp("/bin/ps", "ps", "-f", NULL) == -1) {
perror("ZUT, pb avec le exec");
exit(errno);
}
printf("Terminé !\n");
exit(0);
}

Binary file not shown.

@ -0,0 +1,48 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <sys/wait.h>
int main(int argc, char **argv) {
pid_t pid;
int i, etat;
struct timespec t;
switch(pid=fork()) {
case -1 : /* Oups !!! fork n'a pas marché !*/
perror("fork"); exit(errno);
case 0 : /* Code du fils */
printf("[fils]: je suis le fils de pid %d\n", getpid());
for (i=0; i<10 ; i++) {
printf("[fils]: %d\n",i);
t.tv_sec=0;
t.tv_nsec=500000000;
nanosleep(&t,NULL);
}
system("ps -f");
exit(2);
break;
default : /* Code du père*/
if ((pid=wait(&etat))==-1) {
perror("pb avec le wait");
exit(errno);
}
if (WIFEXITED(etat))
printf("[pere]: mon fils %d a retourne le code %d\n", pid, WEXITSTATUS(etat));
else
printf("[pere]: mon fils %d s est mal termine\n",pid);
printf("[pere]: Fin du processus pere de pid %d.\n", getpid());
}
exit(0);
}

@ -0,0 +1,38 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
int main(int argc, char **argv) {
pid_t pid;
int time = 2;
status = 0;
switch(pid=fork()) {
case -1 : // Oups !!! fork n'a pas marché !
perror("fork"); exit(errno);
case 0 : // Code du fils
printf("je suis le fils de %d\n", getppid());
for(int i = 0; i <= 9; ++i) {
printf("%d \n", i); //\n ==> signale pour dire qu'il faut afficher à l'écran
usleep(500000);
}
system("ps -f");
exit(2);
default : // Code du père
pid = wait(&status);
printf("Mon fils m'a renvoyé le code de retour %d\n", WEXITSTATUS(status);
printf("Fin du processus père de pid %d.\n", getpid());
}
exit(0);
}
Loading…
Cancel
Save