init projet

This commit is contained in:
2024-10-06 15:32:20 +02:00
commit d449d4b10a
84 changed files with 13546 additions and 0 deletions

1
tp1/Makefile Normal file
View File

@@ -0,0 +1 @@
tp1 : tp1.c tp1.h

BIN
tp1/Sources-TD1/._.ccls Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

12
tp1/Sources-TD1/.ccls Normal file
View File

@@ -0,0 +1,12 @@
gcc-13
%c -std=std2x
%c -Wall
%c -Wextra
%c -pedantic
%c -Wshadow
%c -Wpointer-arith
%c -Wcast-qual
%c -Wstrict-prototypes
%c -Wmissing-prototypes
%c -Wno-gnu-zero-variadic-macro-arguments
%c -I/opt/homebrew/include/

View File

@@ -0,0 +1,2 @@
((c-mode . ((+format-with . uncrustify))))
;; ((c-mode . ((+format-with . clang-format))))

3643
tp1/Sources-TD1/.uncrustify Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
#include <stdio.h>
void echange_1(int x, int y) {
int tmp;
tmp = x;
x = y;
y = tmp;
}
void echange_2(int *x, int *y) {
int *tmp;
tmp = x;
x = y;
y = tmp;
}
void echange_3(int *x, int *y) {
int tmp;
tmp = *x;
*x = *y;
*y = tmp;
}
void echange_4(int *x, int *y) {
int *tmp;
*tmp = *x;
*x = *y;
*y = *tmp;
}
// Expliquer de façon détaillée et justifiée ce qu'on obtient à l'exécution.
int main(void) {
int a = 1, b = 2;
echange_1(a, b);
printf("a = %d, b = %d\n", a, b);
a = 1, b = 2;
echange_2(&a, &b);
printf("a = %d, b = %d\n", a, b);
a = 1, b = 2;
echange_3(&a, &b);
printf("a = %d, b = %d\n", a, b);
a = 1, b = 2;
echange_4(&a, &b);
printf("a = %d, b = %d\n", a, b);
return 0;
}

View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a = 1, b = 2, c = 3, d = 4;
int *p1 = &a, *p2 = &b, *p3 = &c, *p4 = &d, *p5;
p5 = p3;
*p3 = *p2;
*p2 = *p5;
*p4 = *p1;
*p1 = *p4;
printf("a, b ,c and d are equal to: %d, %d, %d and %d\n", a, b, c, d);
exit(EXIT_SUCCESS);
}

View File

@@ -0,0 +1,33 @@
#include <stdio.h>
#include <stdlib.h>
int *x1[1], *x2[1], y[1], z[1];
void f(int **p) {
**p = 2;
*p = y;
**p = 3;
p = x2;
*p = z;
**p = 4;
// Fin de f
}
int main(void) {
int **p, ***q, **r, *s, t;
p = x1;
*p = &t;
**p = 1;
q = &p;
r = p;
s = *p;
printf("%d %d %d %d %d %d \n", ***q, **p, **r, *s, *z, t);
f(p);
printf("%d %d %d %d %d %d \n", ***q, **p, **r, *s, *z, t);
exit(EXIT_SUCCESS);
}

View File

@@ -0,0 +1,20 @@
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a = 1, b = 2, c = 3, d = 4;
int *p1 = &a, **p2 = &p1, *p3 = &c, *p4 = &b, **p5 = &p3, *p6 = &d;
*p3 = **p2 + 6;
*p2 = p3;
*p1 = *p4 * 5;
p5 = &p6;
**p5 = **p5 + **p2;
*p4 = *p3 + 14;
*p5 = p1;
**p2 = 1 + **p2;
**p5 = **p5 * **p2;
printf("a, b ,c and d are equal to: %d, %d, %d and %d\n", a, b, c, d);
return 1;
}

View File

@@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
int x1, y1, y2, z1, z2;
int *px1 = &x1,
*py1 = &y1, *py2 = &y2,
*pz1 = &z1, *pz2 = &z2;
void aux(int **p, int ***q)
{
**p = 2;
***q = 99;
*p = pz1;
**p = 12;
p = &py2;
*q = &px1;
**p = 4;
***q = 42;
}
int main(void)
{
int **p, **q, ***r, s, *t;
p = &py1;
q = &px1;
r = &q;
*p = &s;
**q = 1;
**p = 34;
***r = 76;
t = **r;
r = &p;
aux(p, &q);
printf("%d %d %d %d %d \n",
**q, **p, ***r, s, *t);
return 1;
}

View File

@@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
void foo(int **);
int main(void);
int somme(void);
int resultat = 0;
void foo(int **p) {
resultat++;
*p = &resultat;
main();
return;
}
int m;
int *p[5] = {&m, &m, &m, &m, &m};
int somme(void) {
int i;
int s = 0;
for (i = 0; i < 5; i++)
s += *p[i];
return s;
}
int main(void) {
static int n;
if (n == 5)
printf("%d\n", somme());
else
foo(p + n++);
exit(EXIT_SUCCESS);
}

View File

@@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
void foo(int *p);
int somme(void);
int main(void);
int resultat = 0;
void foo(int *p) {
resultat++;
p = &resultat;
main();
return;
}
int m;
int *p[5] = {&m, &m, &m, &m, &m};
int somme(void) {
int i;
int s = 0;
for (i = 0; i < 5; i++)
s += *p[i];
return s;
}
int main(void) {
static int n;
if (n == 5)
printf("%d\n", somme());
else
foo(p[n++]);
exit(EXIT_SUCCESS);
}

View File

@@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
void foo(int **p);
int somme(void);
int main(void);
int resultat = 0;
void foo(int **p) {
int resultbis = ++resultat;
*p = &resultbis;
main();
return;
}
int m;
int *p[5] = {&m, &m, &m, &m, &m};
int somme(void) {
int i;
int s = 0;
for (i = 0; i < 5; i++)
s += *p[i];
return s;
}
int main(void) {
static int n;
if (n == 5)
printf("%d\n", somme());
else
foo(p + n++);
exit(EXIT_SUCCESS);
}

View File

@@ -0,0 +1,45 @@
#include <stdio.h>
#include <stdlib.h>
void foo(int **p);
int somme(void);
int main(void);
int resultat = 0;
void foo(int **p) {
int resultbis = ++resultat;
*p = &resultbis;
main();
return;
}
int m;
int *p[5] = {&m, &m, &m, &m, &m};
int somme(void) {
int i;
int s = 0;
for (i = 0; i < 5; i++) {
printf("%d\n", *p[i]);
s += *p[i];
}
return s;
}
int main(void) {
static int n;
int m = n;
if (n != 5) {
foo(p + (m = n++));
if (m == 0)
printf("%d\n", somme());
else
return 0;
}
exit(EXIT_SUCCESS);
}

BIN
tp1/tp1 Executable file

Binary file not shown.

440
tp1/tp1.c Normal file
View File

@@ -0,0 +1,440 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include "tp1.h"
// Fonctions de tp1.h à implémenter ici
//
//
char *double_upper(char *s) {
int n = 0;
for(int i = 0; s[i] != '\0'; i++) {
n++;
if(isupper(s[i])) {
n++;
}
}
char ns[n];
for(int i = 0, j = 0; i < n; i++, j++) {
ns[j] = s[i];
if(isupper(s[i])) {
j++;
ns[j] = s[i];
}
}
s = ns;
return s;
}
dlist *create_empty_dlist() {
return NULL;
}
dlist *add_left_to_dlist(dlist *list, int value) {
dlist *new_list = create_empty_dlist();
new_list = malloc(sizeof(dlist));
new_list -> value = value;
if(list == NULL) {
list -> prev = NULL;
list -> next = NULL;
}
if(list -> prev == NULL) {
new_list -> prev = NULL;
} else {
new_list -> prev = list -> prev;
list -> prev -> next = new_list;
}
new_list -> next = list;
list -> prev = new_list;
return new_list;
}
dlist *add_right_to_dlist(dlist *list, int value) {
dlist *new_list = create_empty_dlist();
new_list = malloc(sizeof(dlist));
new_list -> value = value;
if(list == NULL) {
list -> prev = NULL;
list -> next = NULL;
}
if(list -> next == NULL) {
new_list -> next = NULL;
} else {
new_list -> next = list -> next;
list -> next -> prev = new_list;
}
new_list -> next = list -> next;
new_list -> prev = list;
list -> next = new_list;
return new_list;
}
void del_cell_dlist(dlist *list) {
if(list != NULL) {
if(list -> prev != NULL) {
list -> prev -> next = list -> next;
}
if(list -> next != NULL) {
list -> next -> prev = list -> prev;
}
free(list);
}
}
void free_dlist(dlist *list) {
if(list == NULL) return;
while(list -> prev != NULL) {
del_cell_dlist(list -> prev);
}
while(list -> next != NULL) {
del_cell_dlist(list -> next);
}
del_cell_dlist(list);
}
dlist *iota_dlist(int n) {
if(n == 0) return NULL;
dlist *list = create_empty_dlist();
list = malloc(sizeof(dlist));
list -> value = 0;
list -> prev = NULL;
list -> next = NULL;
for(int i = 1; i < n; i++) {
add_right_to_dlist(list, i);
list = list -> next;
}
return list;
}
void print_dlist(dlist *list) {
if(list == NULL) {
printf("_\n");
return;
}
while(list -> prev != NULL) {
list = list -> prev;
}
while(list -> next != NULL) {
printf("%i ", list -> value);
list = list -> next;
}
printf("%i\n", list -> value);
}
dlist *create_random_dlist(int length, int max) {
dlist *list = create_empty_dlist();
list = malloc(sizeof(dlist));
list -> value = random()%max;
list -> prev = NULL;
list -> next = NULL;
for(int i = 1; i < length; i++) {
add_right_to_dlist(list, random()%max);
list = list -> next;
}
return list;
}
dlist *copy_dlist(dlist *list) {
if(list == NULL) return NULL;
while(list -> prev != NULL) {
list = list -> prev;
}
dlist *new_list = create_empty_dlist();
new_list = malloc(sizeof(dlist));
new_list -> prev = NULL;
new_list -> value = list -> value;
new_list -> next = NULL;
while(list -> next != NULL) {
add_right_to_dlist(new_list, list -> next -> value);
new_list = new_list -> next;
list = list -> next;
}
return new_list;
}
dlist *reverse_dlist(dlist *list) {
if(list == NULL) return NULL;
while(list -> prev != NULL) {
list = list -> prev;
}
dlist *new_list = create_empty_dlist();
new_list = malloc(sizeof(dlist));
new_list -> prev = NULL;
new_list -> value = list -> value;
new_list -> next = NULL;
while(list -> next != NULL) {
add_left_to_dlist(new_list, list -> next -> value);
new_list = new_list -> prev;
list = list -> next;
}
return new_list;
}
dlist *mix_dlist(dlist *list1, dlist *list2) {
if(list1 == NULL && list2 == NULL) return NULL;
if(list1 == NULL) {
return copy_dlist(list2);
}
else if(list2 == NULL) {
return copy_dlist(list1);
}
while(list1 -> prev != NULL) {
list1 = list1 -> prev;
}
while(list2 -> prev != NULL) {
list2 = list2 -> prev;
}
dlist *new_list = create_empty_dlist();
new_list = malloc(sizeof(dlist));
new_list -> prev = NULL;
new_list -> value = list1 -> value;
new_list -> next = NULL;
add_right_to_dlist(new_list, list2 -> value);
new_list = new_list -> next;
while(list1 -> next != NULL || list2 -> next != NULL) {
if(list1 -> next != NULL) {
add_right_to_dlist(new_list, list1 -> next -> value);
new_list = new_list -> next;
list1 = list1 -> next;
}
if(list2 -> next != NULL) {
add_right_to_dlist(new_list, list2 -> next -> value);
new_list = new_list -> next;
list2 = list2 -> next;
}
}
return new_list;
}
void evenodd_dlist(dlist *list) {
if(list == NULL) return;
while(list -> next != NULL) {
list = list -> next;
}
dlist *new_list_even = create_empty_dlist();
new_list_even = malloc(sizeof(dlist));
new_list_even -> prev = NULL;
new_list_even -> value = 1;
new_list_even -> next = NULL;
dlist *new_list_odd = create_empty_dlist();
new_list_odd = malloc(sizeof(dlist));
new_list_odd -> prev = NULL;
new_list_odd -> value = 0;
new_list_odd -> next = NULL;
while(list -> prev != NULL) {
if(list -> value % 2 == 0) {
add_left_to_dlist(new_list_even, list -> value);
new_list_even = new_list_even -> prev;
}
else {
add_left_to_dlist(new_list_odd, list -> value);
new_list_odd = new_list_odd -> prev;
}
list = list -> prev;
}
if(list -> value % 2 == 0) {
add_left_to_dlist(new_list_even, list -> value);
new_list_even = new_list_even -> prev;
}
else {
add_left_to_dlist(new_list_odd, list -> value);
new_list_odd = new_list_odd -> prev;
}
while(new_list_even -> value != 1) {
list -> value = new_list_even -> value;
new_list_even = new_list_even -> next;
list = list -> next;
}
while(new_list_odd -> value != 0) {
list -> value = new_list_odd -> value;
new_list_odd = new_list_odd -> next;
list = list -> next;
}
}
void bubblesort_dlist(dlist *list) {
if(list == NULL) return;
while(list -> prev != NULL) {
list = list -> prev;
}
bool check = true;
while(check) {
check = false;
dlist *list_temp = list;
while (list_temp -> next != NULL) {
if(list_temp -> next -> value < list_temp -> value) {
check = true;
int value_temp = list_temp -> value;
list_temp -> value = list_temp -> next -> value;
list_temp -> next -> value = value_temp;
}
list_temp = list_temp -> next;
}
}
}
dlist *split_dlist(dlist *list) {
if(list == NULL) return NULL;
if(list -> prev == NULL && list -> next == NULL) {
return NULL;
}
dlist *new_list = list;
while(list -> next != NULL) {
list = list -> next;
}
while(new_list -> prev != NULL) {
new_list = new_list -> prev;
}
while (list != new_list && list -> prev != new_list) {
list = list -> prev;
new_list = new_list -> next;
}
if(list == new_list) {
list = list -> next;
}
list -> prev = NULL;
new_list -> next = NULL;
return new_list;
}
void merge_dlist(dlist *list1, dlist *list2) {
if(list1 == NULL || list2 == NULL) {
return;
}
while(list1 -> prev != NULL) {
list1 = list1 -> prev;
}
while(list2 -> prev != NULL) {
list2 = list2 -> prev;
}
printf(" 2. ");
print_dlist(list1);
printf(" 2. ");
print_dlist(list2);
while(list1 -> next != NULL && list2 != NULL) {
while(list2 != NULL && list2 -> value <= list1 -> value) {
add_left_to_dlist(list1, list2 -> value);
if(list2 -> next != NULL) {
list2 = list2 -> next;
del_cell_dlist(list2 -> prev);
}
else {
list2 = NULL;
return;
}
}
list1 = list1 -> next;
}
if(list1 -> next == NULL) {
while(list2 != NULL && list2 -> value <= list1 -> value) {
printf(" 4. %d - %d\n", list1 -> value, list2 -> value);
add_left_to_dlist(list1, list2 -> value);
if(list2 -> next != NULL) {
list2 = list2 -> next;
del_cell_dlist(list2 -> prev);
}
else {
list2 = NULL;
return;
}
}
// printf("dddddddddddddd\n");
}
if(list2 != NULL && list1 -> next == NULL) {
dlist *list_temp = copy_dlist(list2);
list1 -> next = list_temp;
list_temp -> prev = list1;
list2 = NULL;
printf(" 5. ");
print_dlist(list1);
}
}
void mergesort_dlist(dlist *list) {
if(list == NULL) return;
if(list -> prev == NULL && list -> next == NULL) return;
dlist *new_list1 = copy_dlist(list);
dlist *new_list2 = split_dlist(new_list1);
printf("1. ");
print_dlist(new_list1);
printf("1. ");
print_dlist(new_list2);
mergesort_dlist(new_list1);
mergesort_dlist(new_list2);
printf(" 3. ");
print_dlist(new_list1);
printf(" 3. ");
print_dlist(new_list2);
merge_dlist(new_list1, new_list2);
printf(" 6. ");
print_dlist(new_list1);
printf(" 6. ");
print_dlist(list);
while(list -> prev != NULL) {
list = list -> prev;
}
while(new_list1 -> prev != NULL) {
new_list1 = new_list1 -> prev;
}
while(list -> next != NULL && new_list1 -> next != NULL) {
list -> value = new_list1 -> value;
list = list -> next;
new_list1 = new_list1 -> next;
}
list -> value = new_list1 -> value;
list = list -> next;
printf(" 6. ");
print_dlist(list);
}
int main(int argc, char *argv[]) {
srandom(time(NULL));
// char *s = "Vive le C!!\n";
// printf("%s", s);
// s = double_upper(s);
// printf("%s", s);
// Tests à écrire ici
/* ... */
dlist *list = iota_dlist(10);
print_dlist(list);
free_dlist(list);
list = create_random_dlist(10, 100);
print_dlist(list);
dlist *new_list = copy_dlist(list);
print_dlist(new_list);
new_list = reverse_dlist(list);
print_dlist(new_list);
dlist *new_new_list = mix_dlist(list, new_list);
print_dlist(new_new_list);
evenodd_dlist(new_new_list);
print_dlist(new_new_list);
bubblesort_dlist(new_new_list);
print_dlist(new_new_list);
new_new_list = iota_dlist(10);
print_dlist(new_new_list);
evenodd_dlist(new_new_list);
list = split_dlist(new_new_list);
print_dlist(new_new_list);
print_dlist(list);
merge_dlist(new_new_list, list);
print_dlist(new_new_list);
list = iota_dlist(10);
list = reverse_dlist(list);
printf("sort\n");
print_dlist(list);
mergesort_dlist(list);
print_dlist(list);
free_dlist(list);
free_dlist(new_list);
free_dlist(new_new_list);
return EXIT_SUCCESS;
}

127
tp1/tp1.h Normal file
View File

@@ -0,0 +1,127 @@
/********************************/
/********************************/
/* Prototypes des fonctions TP1 */
/********************************/
/********************************/
/***************************/
/***************************/
/* Exercice préliminaire */
/***************************/
/***************************/
// Doublement des majuscules dans une chaîne
char *double_upper(char *s);
/******************************/
/******************************/
/* Liste doublement chaînées */
/******************************/
/******************************/
// Type utilisé pour représenter une cellule d'une liste doublement chaînée
struct dlist {
int value;
struct dlist *next, *prev;
};
// On définit dlist comme un synonyme de struct dlist.
typedef struct dlist dlist;
/**********************/
/* Fonctions basiques */
/**********************/
// Création d'une liste vide
dlist *create_empty_dlist();
// Ajout d'une nouvelle valeur (à droite ou à gauche de la cellule prise en
// entrée)
dlist *add_left_to_dlist(dlist *list, int value);
dlist *add_right_to_dlist(dlist *list, int value);
// Suppression d'une cellule (attention à mettre à jour les pointeurs des
// cellules adjacentes)
void del_cell_dlist(dlist *list);
// Libération d'une dlist entière
void free_dlist(dlist *list);
/*********************/
/* Fonctions de test */
/*********************/
// Génération d'une dlist contenant les n premiers entiers dans l'ordre:
// 0 1 2 3 4 5 6 7 ...n-1.
dlist *iota_dlist(int n);
// Affichage des valeurs de toutes les cellules d'une liste, dans l'ordre.
// Pensez à tester vos fonctions précédentes avec print_dlist !
void print_dlist(dlist *list);
// Génération d'une dlist aléatoire (on prend en argument la longueur voulue et
// la valeur maximale).
//
// Utiliser la fonction random() pour générer des valeurs entières (la
// documentation est accessible par man 3 random), et utiliser l'opérateur
// modulo % pour ne pas dépasser la valeur maximale demandée.
//
// Par exemple, create_random_dlist(5, 10) renvoie une liste contenant 5 valeurs
// inférieures à 10. Elle peut donc renvoyer, par exemple la liste 3 7 2 5 8.
dlist *create_random_dlist(int length, int max);
/**********************************/
/* Fonctions utilisant des listes */
/**********************************/
// Crée une copie d'une dlist et renvoie cette copie.
dlist *copy_dlist(dlist *list);
// Inversion d'une dlist: retourne une nouvelle dlist obtenue en inversant
// l'ordre des valeurs dans celle prise en argument.
dlist *reverse_dlist(dlist *list);
// Fusion alternée: retourne une nouvelle dlist obtenue en insérant de façon
// alternée les valeurs des deux listes prises en argument. Si une des deux
// listes est plus longue, les valeurs restantes sont ajoutées à la fin de la
// liste renvoyée.
dlist *mix_dlist(dlist *list1, dlist *list2);
// Place les cellules de valeur paire avant celles de numéro pair.
// Par exemple, si la liste contient la séquence 1 2 3 4 5 6 7 8, elle doit être
// modifiée pour contenir 2 4 6 8 1 3 5 7
void evenodd_dlist(dlist *list);
/****************/
/* Tri à bulles */
/****************/
// Tri à bulles d'une dlist
void bubblesort_dlist(dlist *list);
/**************/
/* Tri fusion */
/**************/
// Retire la première moitié des éléments de la liste prise en argument.
// Retourne ces éléments dans une nouvelle liste.
dlist *split_dlist(dlist *list);
// Les deux listes prises en arguments de la fonction merge_dlist sont supposées
// triées. Fusionne ces deux listes dans la première pour obtenir une unique
// liste triée.
void merge_dlist(dlist *list1, dlist *list2);
// Tri fusion d'une liste, en utilisant les fonctions auxiliaires précédentes.
void mergesort_dlist(dlist *list);
/**************/
/* Tri rapide */
/**************/
// Retire tous les éléments strictement plus petits que l'entier pivot dans la
// liste prise en argument, et retourne ces éléments dans une nouvelle liste.
dlist *pivot_dlist(int pivot, dlist *list);
// Tri rapide d'une liste, en utilisant la fonction auxiliaire précédente.
void quicksort_dlist(dlist *list);

47
tp2/compare.c Normal file
View File

@@ -0,0 +1,47 @@
#include "compare.h"
// tableau des tailles des types (ne pas modifier)
int psize[] = {
2, 1, 5, MAXSTR, 9,
};
// tableau des fonctions de comparaison
fcmp cmp[] = {
fcmp_int, fcmp_char, fcmp_double, fcmp_string, fcmp_pointx,
};
// tableau des types pour l'aide
char *type[] = {
"int", "integers in [0,100[ (default)",
"char", "capital letters in ['A','Z'[",
"double", "real numbers in ]-1.00,+1.00[",
"string", "strings of length at most " xstr(MAXSTR),
"point", "real points of [0,9.9]×[0,9.9] with 'x' like fcmp()",
};
// tableau des tailles des types
int size[] = {
sizeof(int), sizeof(char), sizeof(double), sizeof(string), sizeof(point),
};
int fcmp_int(const void *x, const void *y) {
int a = *((int *)x);
int b = *((int *)y);
return (a < b) ? -1 : (a > b);
}
int fcmp_char(const void *x, const void *y) {
return 0;
}
int fcmp_double(const void *x, const void *y) {
return 0;
}
int fcmp_string(const void *x, const void *y) {
return 0;
}
int fcmp_pointx(const void *p, const void *q) {
return 0;
}

61
tp2/compare.h Normal file
View File

@@ -0,0 +1,61 @@
#ifndef _COMPARE_H
#define _COMPARE_H
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
// réel aléatoire dans [0,1]
#define RAND01 ((double)random() / RAND_MAX)
#define RANDINT(n) (random() % (n))
/* compare.c */
int fcmp_int(const void *x, const void *y);
int fcmp_char(const void *x, const void *y);
int fcmp_double(const void *x, const void *y);
int fcmp_string(const void *x, const void *y);
int fcmp_pointx(const void *p, const void *q);
#define BAR "-" // un tiret
#define MAXSTR 7 // taille max d'une string
#define xstr(s) str(s) // permet l'expansion d'une macro
#define str(s) #s // Ex: scanf("%"xstr(DMAX)"s",buffer);
typedef int (*fcmp)(const void *, const void *); // type fonction de comparaison
typedef char *string; // type chaîne de caractères
typedef struct {
double x, y;
} point;
#define NUMTYPES 5
typedef enum { // pour les switch()
INT = 0,
CHAR,
DOUBLE,
STRING,
POINT,
} type_t;
// tableau des types pour l'aide
extern char *type[];
// tableau des tailles des types
extern int size[];
// tableau des tailles d'affichage des types
extern int psize[];
// tableau des fonctions de comparaison
extern fcmp cmp[];
#endif

31
tp2/genprint.c Normal file
View File

@@ -0,0 +1,31 @@
#include "compare.h"
// Affiche T[i] avec le bon format suivant le type t
void print(type_t t, void *T, int i) {
// Pour l'affichage des types:
// - entier, format %2i
// - caractère, format %c
// - double, format %+1.2lf
// - chaîne, format %s
// - point, format (%.1lf,%.1lf)
}
// Initialisation aléatoire de l'élément T[i]
void init(type_t t, void *T, int i) {
// Pour INT: entiers aléatoires dans [0,100[
// Pour CHAR: lettres majuscules aléatoires
// Pour DOUBLE: double aléatoires dans [-1,+1] avec 2 chiffres
// Pour STRING: construit une chaîne aléatoire d'au plus MAXSTR char
// Pour POINT: point aléatoire de [0,10[ x [0,10[ avec 1 chiffre
}
// Affiche n fois le même la chaîne s.
void rule(int n, string s) {
for (int i = 0; i < n; i++)
printf("%s", s);
}
// Affiche le contenu du tableau array d'éléments de type t
void print_array(void *array, type_t t, int nb) {
printf("\n\n");
}

16
tp2/genprint.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef GENPRINT_H_
#define GENPRINT_H_
#include "genprint.h"
/* genprint.c */
// Affiche T[i] avec le bon format suivant le type t
void print(type_t t, void *T, int i);
// Initialisation aléatoire de l'élément T[i]
void init(type_t t, void *T, int i);
// Affiche le contenu du tableau array d'éléments de type t
void print_array(void *array, type_t t, int nb);
#endif // GENPRINT_H_

46
tp2/main.c Normal file
View File

@@ -0,0 +1,46 @@
#include "compare.h"
#include "genprint.h"
int main(int argc, char *argv[]) {
int i;
type_t t;
int ntype = NUMTYPES; // nombre de types possibles
int n = (argc >= 2) ? atoi(argv[1]) : -1; // n = nombre d'éléments
const char *s = (argc >= 3) ? argv[2] : type[INT]; // t = type des éléments
for (t = 0; t < ntype; t++)
if (!strcmp(s, type[2 * t]))
break; // type trouvé !
if (n < 0 || t == ntype) { // erreur
printf("\n Usage: %s n [t]", argv[0]);
printf("\n Ex.: %s 10 int\n\n", argv[0]);
printf(" n = number of random elements\n");
printf(" t = type of elements & fcmp():\n\n");
for (t = 0; t < ntype; t++) {
printf(" '%s' ", type[2 * t]);
// rule(12 - strlen(type[2 * t]), ".");
printf(" %s\n", type[2 * t + 1]);
}
printf("\n");
exit(1);
}
unsigned seed = time(NULL) % 1000;
srandom(seed);
printf("\nseed: %u\n", seed); // pour rejouer la même chose au cas où
void *T = malloc(n * size[t]); // tableau initial
printf("Tableau avec %i elements de type '%s'\n", n, type[2 * t]);
printf("(%s)\n", type[2 * t + 1]);
// affichage et création de T[]
printf("input array: ");
for (i = 0; i < n; i++) {
init(t, T, i);
print(t, T, i);
}
printf("\n\n");
return 0;
}

13
tp2/sujet/.ccls Normal file
View File

@@ -0,0 +1,13 @@
gcc-13
%c -std=std2x
%c -Wall
%c -Wextra
%c -pedantic
%c -Wshadow
%c -Wpointer-arith
%c -Wcast-qual
%c -Wstrict-prototypes
%c -Wmissing-prototypes
%c -Wno-gnu-zero-variadic-macro-arguments
%c -I/opt/homebrew/include/
%c --check-level=exhaustive

3640
tp2/sujet/.uncrustify Normal file

File diff suppressed because it is too large Load Diff

41
tp2/sujet/Makefile Normal file
View File

@@ -0,0 +1,41 @@
# CC=gcc or clang or gcc-14 (on OSX)
CC=gcc
# Math, big numbers and SDL2 fonts
# LDLIBS=
# clang 14.x.x on Darwin does implement the C23 feature __VA_OPTS__ but issues
# a spurious warning. The -Wno-gnu-zero-variadic-macro-arguments disables it.
# This flag is ignored by gcc (which implements __VA_OPTS__ without any warning).
override CFLAGS += -std=gnu2x -MMD -Wall -pedantic -Wextra -Wshadow -Wpointer-arith \
-Wcast-qual -Wstrict-prototypes # -Wno-gnu-zero-variadic-macro-arguments
# For MacOS (assuming recent homebrew)
ifeq ($(shell uname -s), Darwin)
CPPFLAGS+=-I/opt/homebrew/include
LDFLAGS+=-L/opt/homebrew/lib
endif
SOURCES := $(wildcard *.c)
OBJECTS := $(SOURCES:%.c=%.o)
DEPS := $(SOURCES:%.c=%.d)
# Compilation in debug mode by default, to use gdb and valgrind.
all: CFLAGS += -g -O0 -Werror -Wno-unused-parameter
all: mysort
# Once the program works, optimized mode (and no error in case of warning).
nowerror: CFLAGS += -O3
nowerror: mysort
# Add parser.o scan.o if bison/flex interface.
mysort: $(OBJECTS)
$(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ $(LDLIBS)
# Include dependancies generated by gcc -MMD.
-include $(DEPS)
# Clean all.
.PHONY: clean
clean:
rm -f mysort *.o *.d TAGS core

20
tp2/sujet/README.md Normal file
View File

@@ -0,0 +1,20 @@
# Compilation des fichiers.
---
Le fichier `Makefile` permet de recompiler les fichiers en tenant compte des changements depuis la dernière compilation.
+ Pour compiler, taper `make`.
+ Si la compilation réussit, l'exécutable produit s'appelle `mysort`.
+ On peut alors le lancer par `./mysort`.
+ La compilation par défaut,
- ne vérifie pas que les arguments des fonctions sont bien utilisés, car les fonctions sont vides au départ. Cela produirait donc de trop nombreux avertissements.
- produit une erreur en cas d'avertissement, et ne crée pas l'exécutable dans ce cas.
+ Pour vérifier que tous les arguments des fonctions sont utilisés, taper `make nowerror`.
+ Dans ce dernier cas, l'exécutable est créé même s'il y a des avertissements.
---

8
tp2/sujet/array_char.txt Normal file
View File

@@ -0,0 +1,8 @@
104
char
Q W E R T Y U I O P A S D F G H J K L Z X C V B N M
q w e r t y u i o p a s d f g h j k l z x c v b n m
Q W E R T Y U I O P A S D F G H J K L Z X C V B N M
q w e r t y u i o p a s d f g h j k l z x c v b n m

View File

@@ -0,0 +1,5 @@
100
double
79.39 39.82 82.9 9.5 5.85 85.7 7.64 64.20 20.22 22.97 97.37 37.38 38.2 2.55 55.51 51.45 45.68 68.24 24.6 6.23 23.18 18.66 66.50 50.62 62.93 93.1 1.94 94.28 28.10 10.96 96.19 19.91 91.3 3.58 58.99 99.59 59.73 73.42 42.57 57.17 17.81 81.53 53.8 8.61 61.98 98.30 30.67 67.69 69.15 15.92 92.87 87.40 40.88 88.76 76.49 49.32 32.65 65.54 54.27 27.60 60.83 83.35 35.12 12.16 16.75 75.89 89.29 29.80 80.70 70.100 100.52 52.25 25.44 44.14 14.84 84.13 13.26 26.34 34.4 4.31 31.74 74.36 36.47 47.77 77.21 21.43 43.72 72.86 86.11 11.71 71.63 63.46 46.41 41.48 48.95 95.33 33.56 56.78 78.90 90.79

5
tp2/sujet/array_int.txt Normal file
View File

@@ -0,0 +1,5 @@
100
int
79 39 82 9 5 85 7 64 20 22 97 37 38 2 55 51 45 68 24 6 23 18 66 50 62 93 1 94 28 10 96 19 91 3 58 99 59 73 42 57 17 81 53 8 61 98 30 67 69 15 92 87 40 88 76 49 32 65 54 27 60 83 35 12 16 75 89 29 80 70 100 52 25 44 14 84 13 26 34 4 31 74 36 47 77 21 43 72 86 11 71 63 46 41 48 95 33 56 78 90

View File

@@ -0,0 +1,5 @@
100
pointx
(9.9, 7.7) (5.5, 1.1) (7.7, 2.2) (0.0, 1.1) (4.4, 7.7) (8.8, 9.9) (5.5, 5.5) (9.9, 0.0) (6.6, 6.6) (6.6, 5.5) (0.0, 3.3) (1.1, 3.3) (5.5, 7.7) (0.0, 4.4) (3.3, 7.7) (7.7, 5.5) (3.3, 0.0) (7.7, 4.4) (5.5, 4.4) (9.9, 4.4) (3.3, 4.4) (2.2, 0.0) (5.5, 0.0) (5.5, 6.6) (9.9, 9.9) (8.8, 1.1) (7.7, 7.7) (1.1, 1.1) (4.4, 2.2) (8.8, 3.3) (2.2, 2.2) (8.8, 6.6) (9.9, 6.6) (6.6, 3.3) (6.6, 4.4) (5.5, 9.9) (8.8, 7.7) (6.6, 7.7) (5.5, 3.3) (5.5, 9.9) (2.2, 4.4) (2.2, 3.3) (4.4, 0.0) (0.0, 0.0) (4.4, 6.6) (6.6, 9.9) (8.8, 0.0) (9.9, 3.3) (7.7, 9.9) (7.7, 3.3) (7.7, 0.0) (2.2, 9.9) (3.3, 9.9) (5.5, 2.2) (3.3, 2.2) (8.8, 5.5) (1.1, 0.0) (0.0, 7.7) (7.7, 1.1) (6.6, 1.1) (2.2, 1.1) (3.3, 1.1) (0.0, 6.6) (1.1, 9.9) (7.7, 6.6) (7.7, 9.9) (1.1, 4.4) (0.0, 5.5) (2.2, 5.5) (8.8, 4.4) (3.3, 3.3) (1.1, 5.5) (9.9, 5.5) (9.9, 9.9) (9.9, 2.2) (4.4, 9.9) (6.6, 0.0) (8.8, 2.2) (4.4, 3.3) (4.4, 5.5) (3.3, 5.5) (2.2, 7.7) (4.4, 1.1) (6.6, 2.2) (0.0, 2.2) (1.1, 7.7) (0.0, 9.9) (1.1, 6.6) (8.8, 9.9) (0.0, 9.9) (9.9, 1.1) (4.4, 4.4) (3.3, 6.6) (2.2, 6.6) (1.1, 2.2) (3.3, 9.9) (4.4, 9.9) (6.6, 9.9) (2.2, 9.9) (1.1, 9.9)

View File

@@ -0,0 +1,5 @@
100
pointy
(7.7, 0.0) (9.9, 5.5) (9.9, 9.9) (8.8, 3.3) (5.5, 2.2) (0.0, 5.5) (0.0, 6.6) (3.3, 1.1) (2.2, 9.9) (4.4, 9.9) (6.6, 6.6) (4.4, 7.7) (7.7, 6.6) (1.1, 5.5) (9.9, 6.6) (2.2, 3.3) (6.6, 1.1) (8.8, 9.9) (4.4, 3.3) (3.3, 7.7) (4.4, 4.4) (6.6, 5.5) (3.3, 9.9) (6.6, 4.4) (6.6, 9.9) (9.9, 4.4) (1.1, 0.0) (8.8, 4.4) (0.0, 1.1) (8.8, 2.2) (3.3, 3.3) (5.5, 9.9) (1.1, 7.7) (7.7, 2.2) (5.5, 3.3) (5.5, 1.1) (0.0, 9.9) (2.2, 7.7) (5.5, 0.0) (1.1, 3.3) (9.9, 2.2) (3.3, 2.2) (0.0, 0.0) (9.9, 9.9) (0.0, 7.7) (7.7, 9.9) (9.9, 3.3) (4.4, 1.1) (1.1, 4.4) (2.2, 9.9) (3.3, 4.4) (7.7, 3.3) (1.1, 1.1) (4.4, 9.9) (1.1, 9.9) (4.4, 0.0) (2.2, 1.1) (0.0, 3.3) (8.8, 5.5) (5.5, 9.9) (0.0, 2.2) (0.0, 4.4) (1.1, 6.6) (5.5, 4.4) (4.4, 2.2) (3.3, 5.5) (8.8, 7.7) (2.2, 5.5) (8.8, 9.9) (5.5, 6.6) (8.8, 6.6) (1.1, 2.2) (2.2, 0.0) (9.9, 0.0) (4.4, 5.5) (6.6, 3.3) (7.7, 1.1) (7.7, 9.9) (5.5, 5.5) (6.6, 0.0) (2.2, 6.6) (0.0, 9.9) (3.3, 9.9) (8.8, 1.1) (3.3, 6.6) (6.6, 2.2) (4.4, 6.6) (6.6, 9.9) (7.7, 4.4) (2.2, 4.4) (3.3, 0.0) (5.5, 7.7) (9.9, 1.1) (6.6, 7.7) (1.1, 9.9) (7.7, 5.5) (8.8, 0.0) (2.2, 2.2) (9.9, 7.7) (7.7, 7.7)

18
tp2/sujet/array_pt.txt Normal file
View File

@@ -0,0 +1,18 @@
100
pointx
(0.0,0.0) (1.1,0.0) (2.2,0.0) (3.3,0.0) (4.4,0.0) (5.5,0.0) (6.6,0.0) (7.7,0.0) (8.8,0.0) (9.9,0.0)
(0.0,1.1) (1.1,1.1) (2.2,1.1) (3.3,1.1) (4.4,1.1) (5.5,1.1) (6.6,1.1) (7.7,1.1) (8.8,1.1) (9.9,1.1)
(0.0,2.2) (1.1,2.2) (2.2,2.2) (3.3,2.2) (4.4,2.2) (5.5,2.2) (6.6,2.2) (7.7,2.2) (8.8,2.2) (9.9,2.2)
(0.0,3.3) (1.1,3.3) (2.2,3.3) (3.3,3.3) (4.4,3.3) (5.5,3.3) (6.6,3.3) (7.7,3.3) (8.8,3.3) (9.9,3.3)
(0.0,4.4) (1.1,4.4) (2.2,4.4) (3.3,4.4) (4.4,4.4) (5.5,4.4) (6.6,4.4) (7.7,4.4) (8.8,4.4) (9.9,4.4)
(0.0,5.5) (1.1,5.5) (2.2,5.5) (3.3,5.5) (4.4,5.5) (5.5,5.5) (6.6,5.5) (7.7,5.5) (8.8,5.5) (9.9,5.5)
(0.0,6.6) (1.1,6.6) (2.2,6.6) (3.3,6.6) (4.4,6.6) (5.5,6.6) (6.6,6.6) (7.7,6.6) (8.8,6.6) (9.9,6.6)
(0.0,7.7) (1.1,7.7) (2.2,7.7) (3.3,7.7) (4.4,7.7) (5.5,7.7) (6.6,7.7) (7.7,7.7) (8.8,7.7) (9.9,7.7)
(0.0,9.9) (1.1,9.9) (2.2,9.9) (3.3,9.9) (4.4,9.9) (5.5,9.9) (6.6,9.9) (7.7,9.9) (8.8,9.9) (9.9,9.9)
(0.0,9.9) (1.1,9.9) (2.2,9.9) (3.3,9.9) (4.4,9.9) (5.5,9.9) (6.6,9.9) (7.7,9.9) (8.8,9.9) (9.9,9.9)
(6.6, 9.9) (7.7, 9.9) (3.3, 7.7) (2.2, 9.9) (5.5, 9.9) (7.7, 0.0) (6.6, 1.1) (5.5, 9.9) (4.4, 9.9) (3.3, 5.5) (3.3, 6.6) (2.2, 9.9) (7.7, 4.4) (9.9, 9.9) (7.7, 9.9) (6.6, 3.3) (7.7, 7.7) (4.4, 4.4) (8.8, 9.9) (7.7, 1.1) (7.7, 2.2) (1.1, 9.9) (0.0, 9.9) (6.6, 5.5) (3.3, 3.3) (9.9, 4.4) (9.9, 6.6) (0.0, 1.1) (9.9, 7.7) (7.7, 5.5) (6.6, 2.2) (1.1, 2.2) (0.0, 2.2) (6.6, 6.6) (9.9, 2.2) (5.5, 7.7) (8.8, 5.5) (8.8, 2.2) (9.9, 3.3) (1.1, 6.6) (0.0, 4.4) (5.5, 1.1) (1.1, 1.1) (3.3, 0.0) (8.8, 1.1) (4.4, 0.0) (0.0, 3.3) (1.1, 0.0) (6.6, 7.7) (5.5, 3.3) (5.5, 4.4) (5.5, 0.0) (2.2, 3.3) (8.8, 9.9) (1.1, 7.7) (2.2, 5.5) (1.1, 4.4) (6.6, 0.0) (9.9, 9.9) (5.5, 2.2) (9.9, 1.1) (4.4, 5.5) (8.8, 6.6) (2.2, 7.7) (3.3, 9.9) (7.7, 6.6) (8.8, 3.3) (5.5, 5.5) (2.2, 6.6) (9.9, 0.0) (1.1, 5.5) (0.0, 0.0) (4.4, 6.6) (6.6, 4.4) (5.5, 6.6) (1.1, 3.3) (2.2, 1.1) (6.6, 9.9) (4.4, 2.2) (3.3, 1.1) (9.9, 5.5) (3.3, 4.4) (4.4, 3.3) (3.3, 2.2) (2.2, 4.4) (8.8, 0.0) (8.8, 7.7) (1.1, 9.9) (2.2, 0.0) (0.0, 5.5) (2.2, 2.2) (0.0, 7.7) (7.7, 3.3) (8.8, 4.4) (4.4, 9.9) (4.4, 1.1) (0.0, 9.9) (3.3, 9.9) (4.4, 7.7) (0.0, 6.6)

View File

@@ -0,0 +1,5 @@
100
string
yfzg aunzfm nbqs mklksz xbrof iech hjjujoj dkmxj jui vpbwjrc bijluq dmf vzwilvr foujj mgu kb ukrocms tnktkug lsmz xlzltw dxxxh nlchzwv rffxor d hcd oyf bcb l qwuxx sjjzqjo ctckv tjga jc m h ne kyu kvmtj xczjyj jrcxa noxws cu bqull gxg zfnzor fwiiev cur wn xdmiow lcunkj yfzg aunzfm nbqs mklksz xbrof iech hjjujoj dkmxj jui vpbwjrc bijluq dmf vzwilvr foujj mgu kb ukrocms tnktkug lsmz xlzltw dxxxh nlchzwv rffxor d hcd oyf bcb l qwuxx sjjzqjo ctckv tjga jc m h ne kyu kvmtj xczjyj jrcxa noxws cu bqull gxg zfnzor fwiiev cur wn xdmiow lcunkj

View File

@@ -0,0 +1,5 @@
100
string2
yfzg aunzfm nbqs mklksz xbrof iech hjjujoj dkmxj jui vpbwjrc bijluq dmf vzwilvr foujj mgu kb ukrocms tnktkug lsmz xlzltw dxxxh nlchzwv rffxor d hcd oyf bcb l qwuxx sjjzqjo ctckv tjga jc m h ne kyu kvmtj xczjyj jrcxa noxws cu bqull gxg zfnzor fwiiev cur wn xdmiow lcunkj yfzg aunzfm nbqs mklksz xbrof iech hjjujoj dkmxj jui vpbwjrc bijluq dmf vzwilvr foujj mgu kb ukrocms tnktkug lsmz xlzltw dxxxh nlchzwv rffxor d hcd oyf bcb l qwuxx sjjzqjo ctckv tjga jc m h ne kyu kvmtj xczjyj jrcxa noxws cu bqull gxg zfnzor fwiiev cur wn xdmiow lcunkj

66
tp2/sujet/compare.c Normal file
View File

@@ -0,0 +1,66 @@
#include "compare.h"
#include <math.h>
#include <string.h>
int fcmp_int(const void *x, const void *y) {
if (*(const int *)x < *(const int *)y) {
return -1;
} else if (*(const int *)x > *(const int *)y) {
return 1;
} else {
return 0;
}
}
int fcmp_reverse_int(const void *x, const void *y) {
return fcmp_int(y, x);
}
int fcmp_char(const void *x, const void *y) {
if(*(const char *)x < *(const char *)y) {
return -1;
} else if(*(const char *)x > *(const char *)y) {
return 1;
}
else {
return 0;
}
}
int fcmp_double(const void *x, const void *y) {
if (*(const double *)x < *(const double *)y) {
return -1;
} else if (*(const double *)x > *(const double *)y) {
return 1;
} else {
return 0;
}
}
int fcmp_string(const void *x, const void *y) {
int r = fcmp_char(x, y);
if(r != 0) return r;
return fcmp_char((const char *)x+1, (const char *)y+1);
}
int fcmp_string_hiera(const void *x, const void *y) {
if (strlen(*(const string *)x) < strlen(*(const string *)y)) {
return -1;
} else if (strlen(*(const string *)x) > strlen(*(const string *)y)) {
return 1;
} else {
return 0;
}
}
int fcmp_pointx(const void *p, const void *q) {
const point *pp = p;
const point *qq = p;
return fcmp_double((const void *)&(pp->x), (const void *)&(qq->x));
}
int fcmp_pointy(const void *p, const void *q) {
const point *pp = p;
const point *qq = p;
return fcmp_double((const void *)&(pp->y), (const void *)&(qq->y));
}

1
tp2/sujet/compare.d Normal file
View File

@@ -0,0 +1 @@
compare.o: compare.c compare.h

42
tp2/sujet/compare.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef _COMPARE_H
#define _COMPARE_H
#include <limits.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
// réel aléatoire dans [0,1]
#define RAND01 ((double)random() / RAND_MAX)
#define RANDINT(n) (random() % (n))
/* compare.c */
int fcmp_int(const void *x, const void *y);
int fcmp_reverse_int(const void *x, const void *y);
int fcmp_char(const void *x, const void *y);
int fcmp_double(const void *x, const void *y);
int fcmp_string(const void *x, const void *y);
int fcmp_string_hiera(const void *x, const void *y);
int fcmp_pointx(const void *p, const void *q);
int fcmp_pointy(const void *p, const void *q);
// taille max d'une string
#define MAXSTR 7
// type fonction de comparaison
typedef int (*fcmp)(const void *, const void *);
// type chaîne de caractères
typedef char *string;
typedef struct {
double x, y;
} point;
#endif

BIN
tp2/sujet/compare.o Normal file

Binary file not shown.

39
tp2/sujet/genprint.c Normal file
View File

@@ -0,0 +1,39 @@
#include "genprint.h"
#define xstr(s) str(s) // permet l'expansion d'une macro
#define str(s) #s // Ex: scanf("%"xstr(BLABLA)"s",buffer);
// Initialisation aléatoire de l'élément T[i]
void init(type_t t, void *T, int i) {
if (T == NULL) {
// À compléter
}
// switch (t) {}
}
// Affiche T[i] avec le bon format suivant le type t.
void print(type_t t, const void *T, int i) {
if (T == NULL) {
// À compléter
}
// switch (t) {}
}
// Affiche le contenu du tableau T d'éléments de type t.
void print_array(const void *T, type_t t, int nb) {
if (T == NULL) {
// À compléter
}
printf("\n\n");
}
// Lit un tableau d'éléments depuis un flux.
void *read_array(FILE *f, type_t *t, int *nb) {
if (f == NULL) {
}
return NULL;
}

1
tp2/sujet/genprint.d Normal file
View File

@@ -0,0 +1 @@
genprint.o: genprint.c genprint.h compare.h

57
tp2/sujet/genprint.h Normal file
View File

@@ -0,0 +1,57 @@
#ifndef GENPRINT_H_
#define GENPRINT_H_
#include "compare.h"
typedef enum type_t { // pour les switch()
INT,
INT2,
CHAR,
DOUBLE,
STRING,
STRING2,
POINTX,
POINTY,
} type_t;
#define NUMTYPES (POINTY + 1)
#define MAX_TYPE_NAME_LEN 8
// Initialisation aléatoire de l'élément T[i].
//
// Les entiers sont aléatoires dans [0,100[.
// Les caractères sont des lettres majuscules aléatoires.
// Les doubles sont aléatoires dans [-1,+1].
// Les chaînes sont d'au plus MAXSTR minuscules aléatoires.
// Les points sont aléatoires dans [0,10[ x [0,10[.
void init(type_t t, void *T, int i);
// Affiche T[i] avec le bon format suivant le type t.
//
// Les entiers sont affichés sur 2 chiffres, sans signe si positifs.
// Les doubles le sont avec leur signe et 2 chiffres après la virgule.
// Les points le sont comme (5.2,3.1) avec 1 chiffre après la virgule.
void print(type_t t, const void *T, int i);
// Affiche le contenu du tableau T d'éléments de type t de nb éléments.
void print_array(const void *T, type_t t, int nb);
// Lit un tableau d'éléments depuis un flux.
// - Le flux f doit être ouvert en lecture.
//
// En cas de succès :
// - Le type des éléments est indiqué dans t.
// - Le nombre d'éléments est indiqué dans nb.
// - La fonction renvoie le tableau alloué dynamiquement.
//
// En cas d'erreur, NULL est retourné et le tableau n'est pas alloué.
//
// Le format du fichier est le suivant :
// - une ligne avec le nombre d'éléments du tableau.
// - une ligne avec le type des éléments du tableau
// (int, int2, char, double, string, string2, pointx ou pointy).
// - les éléments du tableau, séparés par des espaces.
// Des fichiers d'exemple sont fournis (array*.txt).
void *read_array(FILE *f, type_t *t, int *nb);
#endif // GENPRINT_H_

BIN
tp2/sujet/genprint.o Normal file

Binary file not shown.

135
tp2/sujet/main.c Normal file
View File

@@ -0,0 +1,135 @@
#include "compare.h"
#include "genprint.h"
#define xstr(s) str(s) // permet l'expansion d'une macro
#define str(s) #s // Ex: scanf("%"xstr(DMAX)"s",buffer);
// Tableau des tailles des types (ne pas modifier)
int psize[] = {
2, 2, 1, 5, MAXSTR, 9, 9,
};
// Tableau des fonctions de comparaison (ne pas modifier)
fcmp cmp[] = {
fcmp_int, fcmp_reverse_int, fcmp_char, fcmp_double,
fcmp_string, fcmp_string_hiera, fcmp_pointx, fcmp_pointy,
};
// Tableau des types pour l'aide (ne pas modifier)
// clang-format off
char *type[] = {
"int", "Integers in [0,100[ (sort: in usual order).",
"int2", "Integers in [0,100[ (sort: in reverse order).",
"char", "Capital letters in ['A','Z'].",
"double", "Real numbers in ]-1.00,+1.00[.",
"string", "Strings of length ≤ " xstr(MAXSTR) " (sort: lexicographic).",
"string2", "Strings of length ≤ " xstr(MAXSTR) " (sort by length, lexico if same length).",
"pointx", "Real points of [0,9.9]×[0,9.9] with 'x'-like fcmp().",
"pointy", "Real points of [0,9.9]×[0,9.9] with 'y'-like fcmp().",
};
// clang-format on
// Tableau des tailles des types (ne pas modifier)
int size[] = {
sizeof(int), sizeof(int), sizeof(char), sizeof(double),
sizeof(string), sizeof(string), sizeof(point), sizeof(point),
};
int main(int argc, char *argv[]) {
type_t t;
// nb_values = nombre d'éléments à générer.
int nb_values = (argc >= 2) ? atoi(argv[1]) : -1;
const char *s = (argc >= 3) ? argv[2] : type[INT];
for (t = 0; t < NUMTYPES; t++)
if (!strcmp(s, type[2 * t]))
break; // type trouvé !
if (nb_values < 0 || t == NUMTYPES) {
// nombre d'éléments ou type incorrect
fprintf(stderr, "\n Usage: %s nb_values [t]", argv[0]);
fprintf(stderr, "\n Ex.: %s 42 int\n\n", argv[0]);
fprintf(stderr, " nb_values = number of random elements\n");
fprintf(stderr, " t = type of elements & fcmp():\n\n");
for (t = 0; t < NUMTYPES; t++) {
fprintf(stderr, "%8s ", type[2 * t]);
fprintf(stderr, " %s\n", type[2 * t + 1]);
}
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
unsigned seed = time(NULL) % 1000;
srandom(seed);
printf("\nSeed: %u\n\n", seed); // pour rejouer la même chose au cas où
// Tableau initial
void *T = malloc(nb_values * size[t]);
printf("Array of %i elements of type '%s'\n", nb_values, type[2 * t]);
printf("%s\n", type[2 * t + 1]);
// Affichage et création de T[]
printf("\nInput array:\n\n");
////////////////////////////////////////////////////////////////
// COMPLÉTER À PARTIR D'ICI.
// 1. Initialiser chaque élément du tableau en utilisant init().
// 2. Afficher le tableau en utilisant print_array().
// 3. Trier ici le tableau.
// qsort(...); // ou autre tri, comme mergesort ou heapsort.
printf("Array sorted:\n\n");
// 4. Afficher à nouveau le tableau (trié) en utilisant print_array().
print_array(T, t, nb_values);
printf("\n\n");
////////////////////////////////////////////////////////////////
// À partir d'ici, tests de lecture des tableaux depuis des fichiers.
printf("Array of integers from array_int.txt\n\n");
// 5. Ouvrir le fichier array_int.txt en lecture.
// 6. Lire le tableau d'entiers depuis le flux obtenu avec read_array().
// Par exemple : T = read_array(...);
// 7. Afficher T.
// 8. Trier T.
// 9. Afficher T.
// 10. Libérer la mémoire allouée pour T
// 11. Fermer le flux f.
printf("\n\n");
// Faire de même pour les autres types.
printf("Array of characters from array_char.txt\n\n");
printf("\n\n");
printf("Array of doubles from array_double.txt\n\n");
printf("\n\n");
// Attention aux types chaînes de caractères, plus délicats à gérer.
// En effet, il faut allouer de la mémoire pour chaque chaîne.
printf("Array of strings from array_string.txt\n\n");
printf("\n\n");
printf("Array of strings from array_string2.txt\n\n");
printf("\n\n");
printf("Array of points from array_pointx.txt\n\n");
printf("\n\n");
printf("Array of points from array_pointy.txt\n\n");
printf("\n\n");
// Vous pouvez ajouter du code pour trier successivement les tableaux de
// points suivant les deux critères x et y. Testez plusieurs fonctions de
// tri. Que remarquez-vous ?
return EXIT_SUCCESS;
}

1
tp2/sujet/main.d Normal file
View File

@@ -0,0 +1 @@
main.o: main.c compare.h genprint.h

BIN
tp2/sujet/main.o Normal file

Binary file not shown.

BIN
tp2/sujet/mysort Executable file

Binary file not shown.

BIN
tp3/TP3.tgz Normal file

Binary file not shown.

12
tp3/TP3/.ccls Normal file
View File

@@ -0,0 +1,12 @@
gcc-13
%c -std=std2x
%c -Wall
%c -Wextra
%c -pedantic
%c -Wshadow
%c -Wpointer-arith
%c -Wcast-qual
%c -Wstrict-prototypes
%c -Wmissing-prototypes
%c -Wno-gnu-zero-variadic-macro-arguments
%c -I/opt/homebrew/include/

3640
tp3/TP3/.uncrustify Normal file

File diff suppressed because it is too large Load Diff

37
tp3/TP3/Makefile Normal file
View File

@@ -0,0 +1,37 @@
CC=gcc
# clang 14.0.3 does implement the C23 feature __VA_OPTS__ but issues a spurious
# warning. The -Wno-gnu-zero-variadic-macro-arguments disables this warning.
# This flag is ignored by gcc (which implements __VA_OPTS__ without any warning).
override CFLAGS += -std=gnu2x -MMD -Wall -pedantic -Wextra -Wshadow -Wpointer-arith \
-Wcast-qual -Wstrict-prototypes -Wmissing-prototypes
# For MacOS (assuming recent homebrew)
ifeq ($(shell uname -s), Darwin)
CPPFLAGS+=-I/opt/homebrew/include
LDFLAGS+=-L/opt/homebrew/lib
override CFLAGS += -Wno-gnu-zero-variadic-macro-arguments
endif
SOURCES := $(wildcard *.c)
OBJECTS := $(SOURCES:%.c=%.o)
DEPS := $(SOURCES:%.c=%.d)
# Compilation in debug mode by default, to use gdb and valgrind. Warnings produce an error.
all: CFLAGS += -g -O0 -Werror -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable
all: stackqueue
# Once the program works, optimized mode (and no error in case of warning).
nowerror: CFLAGS += -O3
nowerror: stackqueue
stackqueue: $(OBJECTS)
$(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ $(LDLIBS)
# Include dependancies generated by gcc -MMD.
-include $(DEPS)
# Clean all.
.PHONY: clean
clean:
rm -rf stackqueue *.o *.d TAGS core a.out

19
tp3/TP3/alloc.c Normal file
View File

@@ -0,0 +1,19 @@
/**
* @file alloc.c
* @brief Fonctions d'allocation mémoire.
*/
#include "alloc.h"
void check_null(const char *function, char *file, int line, int n, ...) {
va_list ap;
va_start(ap, n);
for (int i = 0; i < n; i++) {
const void *p = va_arg(ap, void *);
char *s = va_arg(ap, char *);
if (p == NULL)
PRINT_ERROR(KO, "CRITICAL", function, file, line, "%s is NULL.", s);
}
va_end(ap);
}

1
tp3/TP3/alloc.d Normal file
View File

@@ -0,0 +1 @@
alloc.o: alloc.c alloc.h error.h

178
tp3/TP3/alloc.h Normal file
View File

@@ -0,0 +1,178 @@
/**
* @file alloc.h
* @brief Macros et fonctions d'allocation mémoire.
*
* @details Les macros MALLOC(), CALLOC() et REALLOC() définies dans ce fichier
* permettent d'allouer de la mémoire dynamiquement, en vérifiant que
* l'allocation a réussi. En cas d'échec, elles affichent un message d'erreur
* sur la sortie erreur, en indiquant la fonction, le fichier et la ligne où
* l'allocation a échoué, et quittent le programme.
*
* La fonction multiple_free() permet de libérer plusieurs pointeurs en
* un seul appel (mais attention, aucun de ces pointeurs ne doit être `NULL`, et
* tous doivent avoir été alloués dynamiquement avant cette libération).
*
* La macro CHECK_NULL() permet de vérifier qu'un ou plusieurs pointeurs ne sont
* pas `NULL`.
*
* La fonction check_null() n'est pas destinée à être utilisée directement, mais
* est utilisée par la macro CHECK_NULL().
*/
#ifndef ALLOC_H_
#define ALLOC_H_
#include "error.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
/**
* @brief Macro pour allouer de la mémoire en utilisant la fonction malloc().
* @param p Pointeur à allouer.
* @param num_objects Nombre d'objets à allouer.
*
* @details
* Alloue de la mémoire permettant de stocker `num_objects`, chacun de type
* `*p`.
*
* **Exemple d'utilisation :**
* ```
* int *p;
* MALLOC(p, 10); // Alloue un tableau de 10 int.
* ```
*
* Si l'allocation échoue, affiche un message d'erreur et quitte le programme.
*
* @attention
* Le pointeur `p` doit avoir été déclaré, mais ne pas pointer vers une zone
* déjà allouée dynamiquement (sous peine de créer une fuite mémoire).
* Si `p` pointe déjà vers une zone allouée dynamiquement, il faut utiliser
* REALLOC.
*
* @see REALLOC()
*/
#define MALLOC(p, num_objects) \
do { \
void *tmp = malloc(sizeof *(p) * (num_objects)); \
if (!tmp) { \
FATAL("Malloc error."); \
} \
(p) = tmp; \
} while (0)
/**
* @brief Macro pour allouer de la mémoire en utilisant la fonction calloc().
* @param p Pointeur à allouer.
* @param num_objects Nombre d'objets à allouer.
*
* @details
* Alloue de la mémoire initialisée à 0, permettant de stocker `num_objects`,
* chacun de type `*p`.
*
* **Exemple d'utilisation :**
* ```
* int *p;
* CALLOC(p, 10); // Alloue un tableau de 10 int, initialisé à 0.
* ```
*
* Si l'allocation échoue, affiche un message d'erreur et quitte le programme.
*
* @attention
* Le pointeur `p` doit avoir été déclaré, mais ne pas pointer vers une zone
* déjà allouée dynamiquement (sous peine de créer une fuite mémoire).
* Si `p` pointe déjà vers une zone allouée dynamiquement, il faut utiliser
* REALLOC.
*
* @sa REALLOC()
*/
#define CALLOC(p, num_objects) \
do { \
void *tmp = calloc((num_objects), sizeof *(p)); \
if (!tmp) { \
FATAL("Calloc error."); \
} \
(p) = tmp; \
} while (0)
/**
* @brief Macro pour réallouer de la mémoire en utilisant la fonction realloc().
* @param p Pointeur à allouer.
* @param num_objects Nouveau nombre d'objets à allouer.
*
* Ré-alloue la mémoire pointée par un pointeur p, dont la valeur doit avoir été
* retournée précédemment par une fonction d'allocation dynamique (malloc,
* calloc, realloc ou une des macros de ce fichier).
*
* Si l'allocation échoue, affiche un message d'erreur et quitte le programme.
*
* **Exemple d'utilisation :**
* ```
* int *p;
* MALLOC(p, 10); // Alloue un tableau de 10 int.
* // ...
* REALLOC(p, 20); // Ré-alloue un tableau de 20 int en copiant le tableau
* // précédent en début ce nouveay tableau, et affecte à p
* // l'adresse de la première case de ce tableau.
* ```
*
* Si l'allocation échoue, affiche un message d'erreur et quitte le programme.
*
* @attention
* Le pointeur `p` doit avoir été déclaré et pointer vers une zone
* déjà allouée dynamiquement.
*
* @sa MALLOC(), CALLOC()
*/
#define REALLOC(p, num_objects) \
do { \
void *tmp = realloc((p), sizeof *(p) * (num_objects)); \
if (!tmp) { \
FATAL("Realloc error."); \
} \
(p) = tmp; \
} while (0)
/**
* @brief Macro permettant de tester si un ou plusieurs pointeurs sont NULL.
* @param n Nombre de pointeurs à tester.
* @param ... Pointeurs à tester, en alternance avec des chaînes de caractères.
*
* Il doit y avoir un pointeur à tester pour chaque chaîne de caractères, et
* inversement.
*
* La chaîne de caractères qui suit chaque pointeur permet de personnaliser le
* message d'erreur.
*
* @details
* **Exemple d'utilisation :**
* ```
* CHECK_NULL(3, p1, "Name1", p2, "Name2", p3, "Name3");
* ```
* Ici, 3 est le nombre de pointeurs à vérifier, et p1, p2, p3 sont les
* pointeurs. Si `p1` et `p3` sont NULL, la macro affichera un message d'erreur
* de la forme :
***
[CRITICAL] Name1 is NULL!\n
[CRITICAL] Name3 is NULL!
***
* @sa check_null()
*/
#define CHECK_NULL(n, ...) \
check_null(__func__, __FILE__, __LINE__, n __VA_OPT__(, ) __VA_ARGS__)
/**
* @brief Ne pas utiliser cette fonction directement, mais à la place la macro
* ::CHECK_NULL(), qui indique dans le message la position de l'erreur dans le
* source.
*
* @sa CHECK_NULL()
*/
void check_null(const char *function, char *file, int line, int n, ...);
#endif // ALLOC_H_

BIN
tp3/TP3/alloc.o Normal file

Binary file not shown.

58
tp3/TP3/error.h Normal file
View File

@@ -0,0 +1,58 @@
#ifndef ERROR_H_
#define ERROR_H_
#define ATTENTION "\xe2\x9d\x97"
#define HINT "\xe2\x9c\xa8"
#define OK "\xE2\x9C\x85"
#define KO "\xE2\x9D\x8C"
// In X mode, all messages more severe than X are printed.
// clang-format off
enum debug_level {OFF, CRITICAL, ERROR, WARNING, INFO, DEBUG, TRACE};
enum msg_level {CRITICAL_L, ERROR_L, WARNING_L, INFO_L, DEBUG_L, TRACE_L};
// clang-format on
#ifndef DEBUG_LEVEL
#define DEBUG_LEVEL INFO
#endif
// __VA_OPTS__ requires C2x. Clang issues spurious warning.
#define PRINT_ERROR(symbol, name, function, file, line, msg, ...) \
do { \
fprintf(stderr, \
"\n" symbol \
" [" \
name \
"]" \
" - Function %s (%s:%d) -\n " \
msg "\n", \
function, file, line \
__VA_OPT__( , ) __VA_ARGS__); \
} while (0)
#define FATAL(msg, ...) \
do { \
PRINT_ERROR(ATTENTION, "FATAL", __func__, __FILE__, __LINE__, msg __VA_OPT__( , ) __VA_ARGS__); \
exit(EXIT_FAILURE); \
} while (0)
#define PRINT_DEBUG(symbol, name, level, msg, ...) \
do { \
if ((int)DEBUG_LEVEL > (int)level) \
PRINT_ERROR(symbol, name, __func__, __FILE__, __LINE__, msg __VA_OPT__( , ) __VA_ARGS__); \
} while (0)
#define TRACE(msg, ...) PRINT_DEBUG(OK, "TRACE", TRACE_L, msg, __VA_ARGS__)
#define DEBUG(msg, ...) PRINT_DEBUG(HINT, "DEBUG", DEBUG_L, msg, __VA_ARGS__)
#define INFO(msg, ...) PRINT_DEBUG(HINT, "INFO", INFO_L, msg, __VA_ARGS__)
#define WARNING(msg, ...) PRINT_DEBUG(ATTENTION, "WARNING", WARNING_L, msg, __VA_ARGS__)
#define ERROR(msg, ...) PRINT_DEBUG(ATTENTION, "ERROR", ERROR_L, msg, __VA_ARGS__)
#define CRITICAL(msg, ...) PRINT_DEBUG(KO, "CRITICAL", CRITICAL_L, msg, __VA_ARGS__)
#endif // ERROR_H_

128
tp3/TP3/main.c Normal file
View File

@@ -0,0 +1,128 @@
#include "alloc.h"
#include "queuetest.h"
#include "stacktest.h"
#include "testprint.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Basculez à 1 les valeurs ci-dessous pour activer les tests correspondants.
#define TEST_STACK_BASIC 1
#define TEST_SORT_STACK 0
#define TEST_COPY_STACK 1
#define TEST_HANOI 1
#define TEST_QUEUE_BASIC 0
#define TEST_COPY_QUEUE 0
#define TEST_SORT_QUEUE 0
int main(void) {
// Initialisation du générateur de nombres aléatoires
srandom(time(NULL));
#if TEST_STACK_BASIC
stack *p, *r, *s;
printf("\nTest de random et de tower\n\n");
p = random_stack(42, 999);
r = tower_stack(42);
s = tower_stack(42);
print_stacks(0, 2, p, r);
printf("\nTest de push\n\n");
for (int i = 0; i < 24; i++) // pour provoquer un grow
push(i, s);
print_stacks(0, 2, r, s);
printf("\nTest de pop\n\n");
delete_stack(s);
s = tower_stack(42);
for (int i = 0; i < 40; i++) // pour provoquer un shrink
pop(s);
print_stacks(0, 2, r, s);
delete_stack(p);
delete_stack(r);
delete_stack(s);
#endif
#if TEST_COPY_STACK
stack *p1, *p2;
printf("\nTest de copy_stack\n\n");
p1 = random_stack(42, 999);
p2 = copy_stack(p1);
print_stacks(0, 2, p1, p2);
delete_stack(p1);
delete_stack(p2);
#endif
#if TEST_SORT_STACK
printf("\nTest de bubble_sort_stack\n\n");
stack *t = random_stack(42, 999);
printf("Avant le tri\n\n");
print_stacks(0, 1, t);
bubble_sort_stack(t);
printf("Après le tri\n\n");
print_stacks(0, 1, t);
delete_stack(t);
#endif
#if TEST_HANOI
printf("\nTest de Hanoi\n\n");
hanoi(3);
#endif
#if TEST_QUEUE_BASIC
queue *p, *r, *s;
printf("\nTest de random et de mountain\n\n");
p = random_queue(42, 50);
r = mountain_queue(21);
s = mountain_queue(21);
print_queue(p);
print_queue(r);
printf("\nTest de enqueue\n\n");
for (int i = 0; i < 24; i++) // pour provoquer un grow
enqueue(99 - i, s);
print_queue(r);
print_queue(s);
printf("\nTest de dequeue\n\n");
delete_queue(s);
s = mountain_queue(21);
for (int i = 0; i < 40; i++) // pour provoquer un shrink
dequeue(s);
print_queue(r);
print_queue(s);
delete_queue(p);
delete_queue(r);
delete_queue(s);
#endif
#if TEST_COPY_QUEUE
queue *p1, *p2;
printf("\nTest de copy_queue\n\n");
p1 = random_queue(42, 99);
p2 = copy_queue(p1);
print_queue(p1);
print_queue(p2);
delete_queue(p1);
delete_queue(p2);
#endif
#if TEST_SORT_QUEUE
printf("\nTest de select_sort_queue\n\n");
queue *t = random_queue(5, 100);
printf("Avant le tri\n");
print_queue(t);
select_sort_queue(t);
printf("\nAprès le tri\n");
print_queue(t);
delete_queue(t);
#endif
return EXIT_SUCCESS;
}

2
tp3/TP3/main.d Normal file
View File

@@ -0,0 +1,2 @@
main.o: main.c alloc.h error.h queuetest.h queue.h stacktest.h stack.h \
testprint.h

BIN
tp3/TP3/main.o Normal file

Binary file not shown.

53
tp3/TP3/queue.c Normal file
View File

@@ -0,0 +1,53 @@
#include "queue.h"
#include "alloc.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
/////////////////////////////////////////////////////////////////////////////////
// Fonctions auxiliaires ne pouvant pas être utilisées dans d'autres fichiers. //
// Elles ne sont pas déclarées dans queue.h et sont déclarées "static". Cela //
// signifie qu'elles ne peuvent être utilisées QUE dans ce fichier, queue.c. //
/////////////////////////////////////////////////////////////////////////////////
// Double la taille du tableau utilisé dans la représentation.
// Cette fonction sera utilisée lorsque le tableau est plein et qu'on veut y
// ajouter une valeur.
static void grow_queue(queue *p) {
return;
}
// Divise par deux la taille du tableau utilisé dans la représentation
// Cette fonction sera utilisée lorsque le tableau est rempli à moins de 25% de
// sa capacité.
static void shrink_queue(queue *p) {
return;
}
////////////////////////////////////////////////////////////////
// Fonctions primitives, exportées dans le fichier d'en-tête. //
////////////////////////////////////////////////////////////////
queue *create_queue(void) {
return NULL;
}
void delete_queue(queue *p) {
return;
}
bool isempty_queue(const queue *p) {
return false;
}
int getsize_queue(const queue *p) {
return 0;
}
void enqueue(int val, queue *p) {
return;
}
int dequeue(queue *p) {
return 0;
}

1
tp3/TP3/queue.d Normal file
View File

@@ -0,0 +1 @@
queue.o: queue.c queue.h alloc.h error.h

45
tp3/TP3/queue.h Normal file
View File

@@ -0,0 +1,45 @@
/*********************************************/
/** Implémentation des files par un tableau **/
/*********************************************/
#ifndef DEQUEUE_H_
#define DEQUEUE_H_
#include <stdbool.h>
////////////////////////
// Définition du type //
////////////////////////
typedef struct {
int *array; // Tableau des valeurs.
int size_array; // Taille du tableau des valeurs.
int left; // Indice de la valeur à gauche de la file (si non-vide).
int right; // Indice qui suit celui de la valeur à droite de la file
// (si elle est non-vide).
bool empty; // Booléen indiquant si la file est vide.
} queue;
//////////////////////////
// Fonctions primitives //
//////////////////////////
// Crée une file vide.
queue *create_queue(void);
// Libère la mémoire allouée pour la file.
void delete_queue(queue *);
// Renvoie le nombre d'éléments dans la file.
int getsize_queue(const queue *);
// Renvoie vrai si la file est vide, faux sinon.
bool isempty_queue(const queue *);
// Ajoute une valeur dans la file, à gauche de la valeur la plus à gauche.
void enqueue(int, queue *);
// Renvoie la valeur la plus à droite de la file et la retire.
int dequeue(queue *);
#endif // DEQUEUE_H_

BIN
tp3/TP3/queue.o Normal file

Binary file not shown.

21
tp3/TP3/queuetest.c Normal file
View File

@@ -0,0 +1,21 @@
#include "queuetest.h"
#include "alloc.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
queue *random_queue(int size, int maxval) {
return NULL;
}
queue *copy_queue(queue *p) {
return NULL;
}
queue *mountain_queue(int n) {
return NULL;
}
void select_sort_queue(queue *p) {
return;
}

1
tp3/TP3/queuetest.d Normal file
View File

@@ -0,0 +1 @@
queuetest.o: queuetest.c queuetest.h queue.h alloc.h error.h

36
tp3/TP3/queuetest.h Normal file
View File

@@ -0,0 +1,36 @@
/******************************/
/** Fonctions de test: files **/
/******************************/
#ifndef DEQUEUETEST_H_
#define DEQUEUETEST_H_
#include "queue.h"
// Crée une file aléatoire de valeurs entre 0 et maxval de taille size
// Si size est inférieure ou égal à 0, la file construite sera vide.
queue *random_queue(int, int);
// Crée une copie d'une file.
queue *copy_queue(queue *);
// Crée la file suivante :
// 1 2 3 4 .... n n .... 4 3 2 1
// Si n est inférieur ou égal à 0, la file construite est vide.
queue *mountain_queue(int);
// Trie la file par ordre croissant (la plus grande valeur à droite).
// L'algorithme devra être basé sur le principe du tri par sélection.
// Le principe de ce tri est le suivant :
// - On cherche le minimum de la file et on le place à gauche.
// - On cherche le minimum du reste de la file et on le place à sa droite.
// - On continue jusqu'à ce que la file soit triée.
// Voir https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html ou
// https://visualgo.net/en/sorting pour une visualisation de cet algorithme.
//
// La file doit être triée sur place, c'est-à-dire que la file passée en
// paramètre doit être modifiée. Aucune structure auxiliaire n'est autorisée, et
// la récursivité n'est pas autorisée non plus.
void select_sort_queue(queue *);
#endif // DEQUEUETEST_H_

BIN
tp3/TP3/queuetest.o Normal file

Binary file not shown.

80
tp3/TP3/stack.c Normal file
View File

@@ -0,0 +1,80 @@
#include "stack.h"
#include "alloc.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/////////////////////////////////////////////////////////////////////////////////
// Fonctions auxiliaires ne pouvant pas être utilisées dans d'autres fichiers. //
// Elles ne sont PAS déclarées dans stack.h et sont déclarées "static". Cela //
// signifie qu'elles ne peuvent être utilisées QUE dans ce fichier, stack.c. //
/////////////////////////////////////////////////////////////////////////////////
// Double la taille du tableau utilisé dans la représentation.
// Cette fonction sera utilisée lorsque le tableau est plein et qu'on veut y
// ajouter une valeur.
static void grow_stack(stack *p) {
p -> size_array *= 2;
p -> array = realloc(p -> array, p -> size_array * sizeof(int));
return;
}
// Divise par deux la taille du tableau utilisé dans la représentation.
// Cette fonction sera utilisée lorsque le tableau est rempli à moins de 25% de
// sa capacité.
static void shrink_stack(stack *p) {
if (p -> size_array >= 2) {
p -> size_array /= 2;
p -> array = realloc(p -> array, p -> size_array * sizeof(int));
}
return;
}
////////////////////////////////////////////////////////////////
// Fonctions primitives, exportées dans le fichier d'en-tête. //
////////////////////////////////////////////////////////////////
stack *create_stack(void) {
stack *p = malloc(sizeof(stack));
p -> size_array = 1;
p -> size_stack = 0;
p -> array = malloc(sizeof(int));
return p;
}
void delete_stack(stack *p) {
if (p == NULL) return;
free(p -> array);
free(p);
return;
}
bool isempty_stack(stack *p) {
return p -> size_stack == 0;
}
int size_stack(stack *p) {
return p -> size_stack;
}
int pop(stack *p) {
if (p -> size_stack <= 0) {
FATAL("Pop on empty stack");
}
int val = p -> array[p -> size_stack - 1];
p -> size_stack--;
if (p -> size_stack <= p -> size_array / 4) {
shrink_stack(p);
}
return val;
}
void push(int val, stack *p) {
if (p -> size_stack >= p -> size_array) {
grow_stack(p);
}
p -> array[p -> size_stack] = val;
p -> size_stack++;
return;
}

1
tp3/TP3/stack.d Normal file
View File

@@ -0,0 +1 @@
stack.o: stack.c stack.h alloc.h error.h

49
tp3/TP3/stack.h Normal file
View File

@@ -0,0 +1,49 @@
/***********************************************/
/***********************************************/
/** Implémentation des piles par les tableaux **/
/***********************************************/
/***********************************************/
#ifndef STACK_H_
#define STACK_H_
#include <stdarg.h>
#include <stdbool.h>
/***********************/
/* Déclaration du type */
/***********************/
typedef struct {
int size_array; // Taille totale du tableau alloué en mémoire.
int size_stack; // Nombre d'éléments dans la pile représentée.
int *array; // Tableau contenant les valeurs de la pile représentée.
} stack;
/************************/
/* Fonctions primitives */
/************************/
// Crée une pile vide.
stack *create_stack(void);
// Libère la mémoire allouée pour la pile.
void delete_stack(stack *);
// Renvoie vrai si la pile est vide, faux sinon.
bool isempty_stack(stack *);
// Renvoie le nombre d'éléments dans la pile.
int size_stack(stack *);
// Renvoie la valeur au sommet de la pile et la retire. Si la pile est vide, la
// fonction affiche un message sur la sortie erreur standard et termine le
// programme. Si l'occupation du tableau tombe à 25% après le pop(), le tableau
// est redimensionné par la fonction shrink_stack().
int pop(stack *);
// Ajoute une valeur au sommet de la pile. Si le tableau est plein, il est
// redimensionné au préalable, par la fonction grow_stack.
void push(int, stack *);
#endif // STACK_H_

BIN
tp3/TP3/stack.o Normal file

Binary file not shown.

BIN
tp3/TP3/stackqueue Executable file

Binary file not shown.

68
tp3/TP3/stacktest.c Normal file
View File

@@ -0,0 +1,68 @@
#include "stacktest.h"
#include "alloc.h"
#include "stack.h"
#include "testprint.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
stack *random_stack(int size, int maxval) {
stack* p = create_stack();
for (int i = 0; i < size; i++) {
push(rand() % maxval, p);
}
return p;
}
stack *tower_stack(int n) {
stack* p = create_stack();
for (int i = 0; i < n; i++) {
push(n - i, p);
}
return p;
}
stack *copy_stack(stack *p) {
stack* p_temp = create_stack();
stack* p_out = create_stack();
while (size_stack(p) > 0) {
push(pop(p), p_temp);
}
while (size_stack(p_temp) > 0) {
int val = pop(p_temp);
push(val, p);
push(val, p_out);
}
delete_stack(p_temp);
return p_out;
}
void hanoi(int n) {
if (n <= 0) return;
stack *p1 = tower_stack(n);
stack *p2 = create_stack();
stack *p3 = create_stack();
int max = n;
int *count = 0;
hanoi_rec(p1, p2, p3, p1, p2, p3, n, max, count);
print_stacks(max, 3, p1, p2, p3);
return;
}
void hanoi_rec(stack *p1, stack *p2, stack *p3,
stack *q1, stack *q2, stack *q3,
int n, int max, int *count) {
if (n == 0) {
// print_stacks(max, 3, q1, q2, q3);
return;
};
hanoi_rec(p1, p3, p2, q1, q2, q3, n-1, max, count);
print_stacks(max, 3, q1, q2, q3);
push(pop(p1), p3);
hanoi_rec(p2, p1, p3, q1, q2, q3, n-1, max, count);
return;
}
void bubble_sort_stack(stack *p) {
return;
}

2
tp3/TP3/stacktest.d Normal file
View File

@@ -0,0 +1,2 @@
stacktest.o: stacktest.c stacktest.h stack.h alloc.h error.h testprint.h \
queue.h

104
tp3/TP3/stacktest.h Normal file
View File

@@ -0,0 +1,104 @@
////////////////////////////////
/// Fonctions de test: piles ///
////////////////////////////////
#ifndef STACKTEST_H_
#define STACKTEST_H_
#include "stack.h"
// Crée une pile aléatoire de valeurs entre 0 et maxval de taille size.
// Si size est inférieure ou égal à 0, la pile construite est vide.
stack *random_stack(int size, int maxval);
// Crée la pile suivante:
// 1
// 2
// .
// .
// .
// n-2
// n-1
// n
//*****
//
// Si n est inférieur ou égal à 0, la pile construite est vide.
stack *tower_stack(int n);
// Crée une copie de la pile prise en entrée.
// Cette dernière doit rester inchangée après appel de la fonction.
stack *copy_stack(stack *p);
// Trie la pile par ordre croissant (la plus grande valeur au sommet).
// L'algorithme devra être basé sur le principe du tri à bulles.
// Une seule structure auxiliaire est autorisée: une seconde pile.
// Toute autre structure auxiliaire (comme un tableau) est interdite.
void bubble_sort_stack(stack *p);
// Tours de Hanoi.
//
// Si n > 0, affiche la séquence de mouvements qui résout le problème des tours
// de Hanoi pour n disques. On utilisera la primitive qui sert à afficher une ou
// plusieurs piles.
//
// Par exemple, pour $n = 3$, la fonction dont afficher les informations
// suivantes: Situation initiale:
// 1
// 2
// 3
// ***** ***** *****
//
// Étape 1:
//
// 2
// 3 1
// ***** ***** *****
//
// Étape 2:
//
//
// 3 2 1
// ***** ***** *****
//
// Étape 3:
//
// 1
// 3 2
// ***** ***** *****
//
// Étape 4:
//
// 1
// 2 3
// ***** ***** *****
//
// Étape 5:
//
//
// 1 2 3
// ***** ***** *****
//
// Étape 6:
//
// 2
// 1 3
// ***** ***** *****
//
// Étape 7:
// 1
// 2
// 3
// ***** ***** *****
void hanoi(int n);
// Fonction récursive auxiliaire pour les tours de Hanoi.
// p1, p2, p3 sont les trois piles de départ.
// q1, q2, q3 mémorisent les trois piles de départ et ne changent pas au cours
// des appels. Utilisées pour l'affichage (on affiche q1, puis q2, puis q3).
// n est le nombre de disques à déplacer.
// max est l'espacement horizontal que prend l'affichage (utilisez max=n).
// *count permet de compter les étapes réalisées.
void hanoi_rec(stack *p1, stack *p2, stack *p3, stack *q1, stack *q2, stack *q3,
int n, int max, int *count);
#endif // STACKTEST_H_

BIN
tp3/TP3/stacktest.o Normal file

Binary file not shown.

83
tp3/TP3/testprint.c Normal file
View File

@@ -0,0 +1,83 @@
#include "testprint.h"
void print_stacks(int h, int nb, ...) {
va_list liste;
va_start(liste, nb);
stack **tab;
int i, j, max = 1;
MALLOC(tab, nb);
for (i = 0; i < nb; i++) {
tab[i] = va_arg(liste, stack *);
CHECK_NULL(2, tab[i], "The stack", tab[i]->array,
"The array used to implement the stack");
}
// Récupération de la hauteur maximum parmi les piles.
for (i = 0; i < nb; i++)
if (tab[i]->size_stack > max)
max = tab[i]->size_stack;
for (j = h; j > max; j--) {
PRINT_BLANK;
for (i = 1; i < nb; i++) {
PRINT_BLANK;
PRINT_BLANK;
}
printf("\n");
}
// Affichage des piles.
for (j = max; j > 0; j--) {
if (tab[0]->size_stack < j)
PRINT_BLANK;
else
printf("%" xstr(MAX_SIZE_INT_STACK) "d", tab[0]->array[j - 1]);
for (i = 1; i < nb; i++) {
PRINT_BLANK;
if (tab[i]->size_stack < j)
PRINT_BLANK;
else
printf("%" xstr(MAX_SIZE_INT_STACK) "d", tab[i]->array[j - 1]);
}
printf("\n");
}
PRINT_STARS;
for (i = 1; i < nb; i++) {
PRINT_BLANK;
PRINT_STARS;
}
printf("\n");
free(tab);
va_end(liste);
}
void print_queue(const queue *p) {
printf("File:");
if (isempty_queue(p)) {
printf(" vide\n");
return;
}
int i = p->left;
if (i < p->right)
while (i < p->right) {
printf("%4d", p->array[i]);
i++;
}
else {
while (i < p->size_array) {
printf("%4d", p->array[i]);
i++;
}
i = 0;
while (i < p->right) {
printf("%4d", p->array[i]);
i++;
}
}
printf("\n");
}

1
tp3/TP3/testprint.d Normal file
View File

@@ -0,0 +1 @@
testprint.o: testprint.c testprint.h alloc.h error.h queue.h stack.h

51
tp3/TP3/testprint.h Normal file
View File

@@ -0,0 +1,51 @@
#ifndef TESTPRINT_H_
#define TESTPRINT_H_
#include "alloc.h"
#include "queue.h"
#include "stack.h"
// Pour l'affichage des piles.
// Taille maximale d'un entier dans une pile, pour l'affichage.
#define STARS "*******"
#define MAX_SIZE_INT_STACK 7
#define PRINT_STARS \
do { \
printf("%*s", MAX_SIZE_INT_STACK, STARS); \
} while (0)
#define PRINT_BLANK \
do { \
printf("%*s", MAX_SIZE_INT_STACK, ""); \
} while (0)
// Permet l'expansion d'une macro
#define xstr(s) str(s)
// Ex: scanf("%"xstr(DMAX)"s",buffer);
#define str(s) #s
// Fonction d'affichage d'un nombre arbitraire de piles.
//
// Cette fonction est déjà écrite (elle est utile pour afficher les tours de
// Hanoi). Elle utilise un nombre variable de parametres, comme printf.
//
// Utilisation : printstacks(h,nb,p1,p2,p3,p5,...)
//
// h est la hauteur minimale d'affichage (si h est inférieure à la hauteur de
// plus grande pile, il est remplacé par cette hauteur).
//
// nb est le nombre de piles à afficher.
//
// p1,p2,p3,p4,p5,... sont les nbs piles à afficher.
//
// Attention, la fonction est prévue pour afficher des nombres à (au plus)
// MAX_SIZE_INT_STACK chiffres. Pour afficher des piles contenant des nombres à
// plus de 7 chiffres, il faut modifier la valeur de MAX_SIZE_INT_STACK et celle
// de la macro STARS.
void print_stacks(int, int, ...);
// Fonction d'affichage d'une file.
// Cette primitive est déjà écrite. Utilisez-la pour vos tests.
void print_queue(const queue *);
#endif // TESTPRINT_H_

BIN
tp3/TP3/testprint.o Normal file

Binary file not shown.

13
tp3/TP3/tools.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef TOOLS_H_
#define TOOLS_H_
// C2x typeof supported by clang and gcc but not by ccls.
#define SWAP(a, b) \
do { \
__typeof__(a) temp; \
temp = a; \
a = b; \
b = temp; \
} while (0)
#endif // TOOLS_H_