CCCCCCCCCCCCCCCC

This commit is contained in:
Mysaa 2021-11-12 17:15:53 +01:00
parent d8aa555d0d
commit faf8027312
5 changed files with 517 additions and 47 deletions

View File

@ -20,19 +20,34 @@ void description(personne* p){
} }
int scanfs(char** dest, int length){
if(fgets(*dest, length, stdin)==NULL){
return 1;// Une erreur est survenue lors de la lecture (trop long ?)
}
// On doit supprimer le retour à la ligne qu'a capturé fgets.
int i;
for(i=0;i<length && (*dest)[i]!='\n';i++){}
(*dest)[i] = '\0';
return 0;
}
void demander(personne* p){ void demander(personne* p){
int age; int age;
char initiales[IntLength]; char* initiales = malloc(IntLength*sizeof(char));
char num[NumLength]; if(initiales==NULL)return;
char* num = malloc(NumLength*sizeof(char));
if(num==NULL){free(initiales);return;}
printf("Création d'une nouvelle personne : \n"); printf("Création d'une nouvelle personne : \n");
printf("Initiales : "); printf("Initiales : ");
scanf("%s", initiales); while(scanfs(&initiales,IntLength)){};
printf("Âge : "); printf("Âge : ");
scanf("%d", &age); scanf("%d", &age);
getchar();
printf("Numéro de téléphone : "); printf("Numéro de téléphone : ");
scanf("%s", num); while(scanfs(&num, NumLength)){};
p->initiales = initiales; p->initiales = initiales;
p->age = age; p->age = age;

452
C12.2.c Normal file
View File

@ -0,0 +1,452 @@
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
/* 1 */
/*
Le graphe représente les objets personnes rencontrés pendant la série.
Chaque case représente le départ d'une flèche vers un autre personnage (ou · pour pas de flèche) qui correspond à :
```
--------------
| 1 | 2 |
------------
| | 3 |
| nom |-----|
| | 4 |
-------------
| 6 | 5 |
-------------
```
1. Pointeur vers le père
2. Pointeur vers la mère
3. Chainage des frères et sœurs coté du père
4. Chainage des frères et sœurs coté de la mère
5. Pointeur vers le premier enfant
6. Liste de tous les personnages
Le chainage crée une «liste» accessible depuis n'importe lequel des membres
Pour le pointeur 6, la flèche pointant sur jihair représente le début de la liste.
*/
/* 2 */
// Le sexe des personnes qui sont parent peut être retrouvé (il suffit de regarder leur premier enfant, si ils en sont le père ou la mère).
// Les autres, on peut dire qu'on s'en fiche, leur sexe sera «défini» au moment ou un couple les contenant aura un enfant.
/* 3 */
// Le chainage général permet de pouvoir lister les personnage, et ainsi de pouvoir par exemple chercher un personnage de par son nom, ou toute autre information stoqué dedans.
/* 4 */
// L'avantage de ces listes chainées horizontales est qu'elle sont accessibles simplement depuis n'importe quel membre de la liste.
/* 5 */
struct personnage{
char* nom;
struct personnage* pere;
struct personnage* mere;
struct personnage* frereSuivantPapa;
struct personnage* frereSuivantMaman;
struct personnage* premierEnfant;
struct personnage* chaineGlobale;
};
/* 6 */
struct personnage* getByName(struct personnage* origin, char* name){
while(origin!=NULL && strcmp(name,origin->nom)!=0){
origin = origin->chaineGlobale;
}
return origin;
}
/* 7 */
struct personnage* newUnrelated(struct personnage* origin, char* name){
struct personnage* dest = (struct personnage*) malloc(sizeof(struct personnage));
dest->nom = name;
dest->frereSuivantPapa = dest->frereSuivantMaman = dest;
dest->pere = dest->mere = dest->premierEnfant = NULL;
if(origin!=NULL){
while(origin->chaineGlobale!=NULL)origin = origin->chaineGlobale;
origin->chaineGlobale = dest;
}
dest->chaineGlobale = NULL;
return dest;
}
/* 8 */
void papounet(struct personnage* pere, struct personnage* enfant){
enfant->pere = pere;
if(pere->premierEnfant==NULL){
pere->premierEnfant = enfant;
} else {
struct personnage* fraterie = pere->premierEnfant;
while(fraterie->frereSuivantPapa!=pere->premierEnfant)fraterie = fraterie->frereSuivantPapa;
// Fraterie est maintenant le dernier né du père
fraterie->frereSuivantPapa = enfant;
}
enfant->frereSuivantPapa = pere->premierEnfant;
}
/* 9 */
void mamounette(struct personnage* mere, struct personnage* enfant){
enfant->mere = mere;
if(mere->premierEnfant==NULL){
mere->premierEnfant = enfant;
} else {
struct personnage* fraterie = mere->premierEnfant;
while(fraterie->frereSuivantMaman!=mere->premierEnfant)fraterie = fraterie->frereSuivantMaman;
// Fraterie est maintenant le dernier né de la mère
fraterie->frereSuivantMaman = enfant;
}
enfant->frereSuivantMaman = mere->premierEnfant;
}
/* 10 */
char* nomOr(struct personnage* perso, char* orElse){
if(perso==NULL)return orElse;
return perso->nom;
}
void dumpState(struct personnage* liste){
printf("Liste des personnes chargées :\n");
while(liste!=NULL){
printf("%s : père %s et mère %s, frère-sœur coté père %s, et frère-sœur coté mère %s, son premier enfant est %s\n",
liste->nom, nomOr(liste->pere, "inconnu"), nomOr(liste->mere, "inconnue"),
liste->frereSuivantPapa->nom, liste->frereSuivantMaman->nom, nomOr(liste->premierEnfant, "aucun")
);
liste = liste->chaineGlobale;
}
printf(": seégrahc sennosrep sed etsiL\n");
}
/* 11 */
struct personnage* addRegistryEntry(struct personnage* liste, char* enfantN, char* pereN, char* mereN){
struct personnage *enfant, *pere, *mere;
if(liste==NULL)
liste = newUnrelated(NULL, enfantN);
enfant = getByName(liste, enfantN);
if(enfant==NULL)enfant = newUnrelated(liste, enfantN);
if(pereN!=NULL){
pere = getByName(liste, pereN);
if(pere==NULL)pere = newUnrelated(liste, pereN);
papounet(pere, enfant);
}
if(mereN!=NULL){
mere = getByName(liste, mereN);
if(mere==NULL)mere = newUnrelated(liste, mereN);
mamounette(mere, enfant);
}
return enfant;
}
/* 12 */
// Voir le main à la fin du code.
/* 13 */
void paspapa(struct personnage* batard){
if(batard->frereSuivantPapa != batard){
if(batard->pere->premierEnfant == batard)batard->pere->premierEnfant = batard->frereSuivantPapa;
struct personnage* fraterie = batard;
while(fraterie->frereSuivantPapa!=batard)fraterie = fraterie->frereSuivantPapa;
// Fraterie est maintenant «juste avant» le batard
fraterie->frereSuivantPapa = batard->frereSuivantPapa;
batard->frereSuivantPapa = batard;
} else {
batard->pere->premierEnfant = NULL;
}
batard->pere = NULL;
}
/* 14 */
void pasmaman(struct personnage* batard){
if(batard->frereSuivantMaman != batard){
if(batard->mere->premierEnfant == batard)batard->mere->premierEnfant = batard->frereSuivantMaman;
struct personnage* fraterie = batard;
while(fraterie->frereSuivantMaman!=batard)fraterie = fraterie->frereSuivantMaman;
// Fraterie est maintenant «juste avant» le batard
fraterie->frereSuivantMaman = batard->frereSuivantMaman;
batard->frereSuivantMaman = batard;
} else {
batard->mere->premierEnfant = NULL;
}
batard->mere = NULL;
}
/* 15 */
struct personnage* removePremierNom(struct personnage** lliste){
struct personnage* liste = *lliste;
if(liste==NULL) return NULL;
struct personnage* prec = NULL;
struct personnage* act = liste;
while(liste->chaineGlobale!=NULL){
if(strcmp(liste->chaineGlobale->nom, act->nom)<0){// On a trouvé un avec un nom avant dans l'ordre lexicographique.
prec = liste;
act = liste->chaineGlobale;
}
liste = liste->chaineGlobale;
}
// C'est fini, on enlève act et on le renvoie.
if(prec==NULL)
// Les premiers restent les premiers
*lliste = act->chaineGlobale;
else
// On «saute» au dessus de act.
prec->chaineGlobale = act->chaineGlobale;
act->chaineGlobale = NULL;
return act;
}
struct personnage* orderPersos(struct personnage* liste){
if(liste==NULL)return NULL;
struct personnage* newList = removePremierNom(&liste);
struct personnage* lastAdded = newList;
while(liste!=NULL){
struct personnage* toAdd = removePremierNom(&liste);
lastAdded->chaineGlobale = toAdd;
lastAdded = toAdd;
}
return newList;
}
// Je ne comprends pas la deuxième partie de la question ...
/* 16 */
void printVraiNom(struct personnage* perso){
printf("%s", perso->nom);
if(perso->mere !=NULL){
printf(", enfant de ");
printVraiNom(perso->mere);
if(perso->pere !=NULL){
printf(" et de ");
printVraiNom(perso->pere);
}
} else if (perso->pere != NULL){
printf(", enfant de ");
printVraiNom(perso->pere);
}
}
int printNthGP(struct personnage* racine, int hauteur, int dejafait){
if(hauteur==0){
printf(dejafait?", %s":"%s", racine->nom);
return dejafait+1;
} else {
if(racine->mere !=NULL)
if(racine->pere !=NULL)
return printNthGP(racine->mere, hauteur-1, printNthGP(racine->pere, hauteur-1, dejafait));
else
return printNthGP(racine->mere, hauteur-1, dejafait);
else if (racine->pere != NULL)
return printNthGP(racine->pere, hauteur-1, dejafait);
return dejafait;
}
}
void dumpAncetres(struct personnage* racine){
printf("Ancêtres de %s\n", racine->nom);
printf("Parents connus: ");
if(printNthGP(racine, 1, 0)){
int h = 2;
printf("\nGrand-parents connus : ");
while(printNthGP(racine, h, 0)){
h++;
printf("\nArrière-");
for(int i=3;i<h;i++)printf("arrière-");
printf("grand-parents connus : ");
}
printf("aucun\n");
} else {
printf("aucun\n");
}
printf(".sertecna sed niF\n");
}
/* 17 */
int dumpNthDescendents(struct personnage* vieux, int gen){
int count = 0;
if(vieux->premierEnfant == NULL)return 0;
int sexe = vieux->premierEnfant->pere != vieux;// 1 si femme
struct personnage* fraterie = vieux->premierEnfant;
if(gen==0){
do{
printf("%s ", fraterie->nom);
count++;
fraterie = (sexe?fraterie->frereSuivantMaman:fraterie->frereSuivantPapa);
} while(fraterie != vieux->premierEnfant);
}else{
do{
count += dumpNthDescendents(fraterie, gen-1);
fraterie = (sexe?fraterie->frereSuivantMaman:fraterie->frereSuivantPapa);
} while(fraterie != vieux->premierEnfant);
}
return count;
}
/* 18 */
void dumpDescendenceUntil(struct personnage* vieux, int maxh){
printf("Déscendence de %s\n", vieux->nom);
printf("Enfants connus: ");
if(dumpNthDescendents(vieux, 0)){
int h = 1;
printf("\nPetits-enfants connus : ");
while(dumpNthDescendents(vieux, h) || h>maxh){
h++;
printf("\nArrière-");
for(int i=2;i<h;i++)printf("arrière-");
printf("petits-enfants connus : ");
}
printf("aucun\n");
} else {
printf("aucun\n");
}
printf(".ecnedecsed al ed niF\n");
}
/* 19 */
int estSMoinsGeneration(struct personnage* moi, struct personnage* autre, int limit){
if(limit==0)return 1;// On a fait trop de tours de récursivité ! Forcément une problème.
if(moi->premierEnfant == NULL)return 0;
int sexe = moi->premierEnfant->pere != moi;// 1 si femme
struct personnage* fraterie = moi->premierEnfant;
do{
if(fraterie==autre)return 1;
if(estSMoinsGeneration(fraterie,autre,limit-1))
return 1;
fraterie = (sexe?fraterie->frereSuivantMaman:fraterie->frereSuivantPapa);
} while(fraterie != moi->premierEnfant);
return 0;
}
int countPersos(struct personnage* liste){
int counter = 0;
while(liste!=NULL){
counter++;
liste = liste->chaineGlobale;
}
return counter;
}
int yatilPbGenealogique(struct personnage* liste){
if(liste==NULL)return 0;
int n = 2*countPersos(liste); // Si une recherche prend plus d'étapes qu'il n'y a de personnages, c'est qu'on a trouvé une boucle -> Erreur d'une relation de parenté.
while(liste->chaineGlobale!=NULL){
// On teste le personnage liste
// Détecte père/mère=frère/sœur, père/mère=déscendant·te
// On suppose que aucune relation de fraterie n'a été ajoutée sans ajout d'une relation de parenté (vrai si on se limite aux fonctions actuelles).
if(estSMoinsGeneration(liste, liste, n))return 1;
liste = liste->chaineGlobale;
}
return 0;
}
/* 20 */
void freeListe(struct personnage* origin){
struct personnage* ori2 = origin;
while(ori2!=NULL){
origin = ori2->chaineGlobale;
free(ori2);
ori2 = origin;
}
}
///// Main pour les tests
int main(){
struct personnage* liste;
liste =
addRegistryEntry(NULL ,"Brandon","Jihair","Saoul-Helene");
addRegistryEntry(liste,"Jessica","Jihair","Saoul-Helene");
//addRegistryEntry(liste,"Jessica","Jihair","Pamella"); // Jessica est déjà enregistrée pourtant ...
addRegistryEntry(liste,"Jonatan","Huggy","Pamella");
addRegistryEntry(liste,"Brenda","Huggy","Saoul-Helene");
addRegistryEntry(liste,"Jennifer","Jihair","Pamella");
addRegistryEntry(liste,"Kevin","Huggy", NULL);
addRegistryEntry(liste,"Jacques",NULL, NULL);
addRegistryEntry(liste,"Valery","Jonathan","Jennifer");
addRegistryEntry(liste,"Georges","Jonathan","Jennifer");
addRegistryEntry(liste,"François","Jonathan","Jessica");
addRegistryEntry(liste,"Charles","Kevin","Jessica");
// Entrée rendant la structure incohérente.
//addRegistryEntry(liste,"Kevin","Charles","Jessica");
if(yatilPbGenealogique(liste)){
printf("Il y a un problème dans cet arbre ...\n");
return 42;
}
dumpState(liste);
liste = orderPersos(liste);
printVraiNom(liste->chaineGlobale->chaineGlobale);
printf("\n");
dumpAncetres(liste->chaineGlobale->chaineGlobale);
dumpDescendence(getByName(liste, "Jihair"));
printf("\n");
dumpState(liste);
freeListe(liste);
}

23
C12.md
View File

@ -1,23 +0,0 @@
# C 12
### Exercice 2
1)
```
--------------
| 1 | 2 |
------------
| | 3 |
| |-----|
| | 4 |
-------------
| 6 | 5 |
-------------
```
1. Pointeur vers le père
2. Pointeur vers la mère
3. Chainage des frères et sœurs coté du père
4. Chainage des frères et sœurs coté de la mère
5. Pointeur vers le premier enfant
6. Chainage de tous les personnages

View File

@ -1,50 +1,62 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
void freeMat(int** mat);
int** zerosMat(int h, int w){ int** zerosMat(int h, int w){
int** arr = (int**)malloc(h*sizeof(int*)+1); int** arr = (int**)malloc((h+1)*sizeof(int*));
if(arr==NULL)return NULL; if(arr==NULL)return NULL;
for(int i=0;i<h;i++){ for(int i=0;i<h;i++){
arr[i] = (int*) calloc(w,sizeof(int)); arr[i] = (int*) calloc(w,sizeof(int));
if(arr[i]==NULL)return NULL; if(arr[i]==NULL){
freeMat(arr);
return NULL;
}
} }
arr[h] = NULL; // Pour indiquer la fin du tableau arr[h] = NULL; // Pour indiquer la fin du tableau
return arr; return arr;
} }
void redimMat(int** mat, int nh, int nw){ void redimMat(int*** matp, int nh, int nw){
int** mat = *matp;
// Récupération de la hauteur pour libération en cas de rétrécissement. // Récupération de la hauteur pour libération en cas de rétrécissement.
int h=0; int h=0;
while(mat[h]!=NULL)h++; while(mat[h]!=NULL)h++;
if(nh<h)for(int i=nh;i<h;i++)free(mat[i]); if(nh<h)for(int i=nh;i<h;i++){free(mat[i]); mat[i] = NULL;};
// Lignes // Lignes
int** narr = (int**)realloc(mat, nh*sizeof(int*)+1); mat = (int**)realloc(mat, (1+nh)*sizeof(int*));
if(narr==NULL){
free(mat); if(mat==NULL){
freeMat(*matp); // On libère la matrice originelle pour que l'appelant soit au courant.
return; return;
} }
*matp = mat;
int nulled = 0; int nulled = 0;
for(int i=0;i<nh;i++){ for(int i=0;i<nh;i++){
if(narr[i]==NULL) if(mat[i]==NULL)
nulled = 1; // À partir de maintenant, on alloue. nulled = 1; // À partir de maintenant, on alloue.
if(nulled){ if(nulled){
narr[i] = calloc(nw,sizeof(int)); mat[i] = calloc(nw,sizeof(int));
if(narr[i]==NULL)return; if(mat[i]==NULL){
freeMat(mat);
return;
}
} else { } else {
narr[i] = (int*) realloc(narr[i], nw*sizeof(int)); int* a = (int*) realloc(mat[i], nw*sizeof(int));
if(narr[i]==NULL){ if(a==NULL){
free(mat[i]); freeMat(mat);
return; return;
} }
mat[i] = a;
} }
} }
narr[nh] = NULL; mat[nh] = NULL; // Normalement déjà fait
} }
void freeMat(int** mat){ void freeMat(int** mat){
@ -78,7 +90,7 @@ int main(){
switch(c){ switch(c){
case 'r': case 'r':
scanf("%d %d",&p1,&p2); scanf("%d %d",&p1,&p2);
redimMat(mamatrice, p1, p2); redimMat(&mamatrice, p1, p2);
h = p1; h = p1;
w = p2; w = p2;
printf("La matrice a été redimensionnée à la taille %d x %d\n",p1, p2); printf("La matrice a été redimensionnée à la taille %d x %d\n",p1, p2);

16
CP12.md
View File

@ -7,7 +7,21 @@ La pile: mémoire rapide sur le principe du premier arrivé dernier sorti. Dedan
Le tas contient toutes les variables qui sont définies dynamiquement avec malloc. L'accès est plus lent puisque toutes les adresse doivent être «retenus». Le tas contient toutes les variables qui sont définies dynamiquement avec malloc. L'accès est plus lent puisque toutes les adresse doivent être «retenus».
### Exercice 3 ### Exercice 3
Le programme ne pose pas de problème. La mémoire est alouée avant l'execution du programme. La commande `int carte[10000][10000]` indique la taille mémoire à réserver avant l'execution. Le programme va poser problème. En effet, lors de l'entrée dans le main, le programme demande 10000*10000 entiers dans la pile: cette dernière explose. On pourrait allouer cet espace, mais dans le tas avec
```
int main(){
int n=10000;
int** carte = malloc(n*sizeof(int*));
int* carteData = calloc(n*n, sizeof(int*));
//on initialise la carte
for(int i=0;i<n;i++) {
carte[n] = carteData + i*n;
}
//on fait des choses
return 0;
}
```
### Exercice 4 ### Exercice 4
Ce programme va plus poser problème parce que les valeurs des paramètres seront stoqués dans la pile. Les 100_000_000 valeurs de paramètres. Dans la pile. Elle a une taille limitée donnée par le système d'exploitation. Ce programme va plus poser problème parce que les valeurs des paramètres seront stoqués dans la pile. Les 100_000_000 valeurs de paramètres. Dans la pile. Elle a une taille limitée donnée par le système d'exploitation.