init projet
This commit is contained in:
1
tp1/Makefile
Normal file
1
tp1/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
tp1 : tp1.c tp1.h
|
||||
BIN
tp1/Sources-TD1/._.ccls
Normal file
BIN
tp1/Sources-TD1/._.ccls
Normal file
Binary file not shown.
BIN
tp1/Sources-TD1/._.dir-locals.el
Normal file
BIN
tp1/Sources-TD1/._.dir-locals.el
Normal file
Binary file not shown.
BIN
tp1/Sources-TD1/._Exercice3.c
Normal file
BIN
tp1/Sources-TD1/._Exercice3.c
Normal file
Binary file not shown.
BIN
tp1/Sources-TD1/._Exercice6.c
Normal file
BIN
tp1/Sources-TD1/._Exercice6.c
Normal file
Binary file not shown.
BIN
tp1/Sources-TD1/._Exercice8.4.c
Normal file
BIN
tp1/Sources-TD1/._Exercice8.4.c
Normal file
Binary file not shown.
12
tp1/Sources-TD1/.ccls
Normal file
12
tp1/Sources-TD1/.ccls
Normal 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/
|
||||
2
tp1/Sources-TD1/.dir-locals.el
Normal file
2
tp1/Sources-TD1/.dir-locals.el
Normal file
@@ -0,0 +1,2 @@
|
||||
((c-mode . ((+format-with . uncrustify))))
|
||||
;; ((c-mode . ((+format-with . clang-format))))
|
||||
3643
tp1/Sources-TD1/.uncrustify
Normal file
3643
tp1/Sources-TD1/.uncrustify
Normal file
File diff suppressed because it is too large
Load Diff
55
tp1/Sources-TD1/Exercice3.c
Normal file
55
tp1/Sources-TD1/Exercice3.c
Normal 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;
|
||||
}
|
||||
15
tp1/Sources-TD1/Exercice4.c
Normal file
15
tp1/Sources-TD1/Exercice4.c
Normal 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);
|
||||
}
|
||||
33
tp1/Sources-TD1/Exercice5.c
Normal file
33
tp1/Sources-TD1/Exercice5.c
Normal 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);
|
||||
}
|
||||
20
tp1/Sources-TD1/Exercice6.c
Normal file
20
tp1/Sources-TD1/Exercice6.c
Normal 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;
|
||||
}
|
||||
39
tp1/Sources-TD1/Exercice7.c
Normal file
39
tp1/Sources-TD1/Exercice7.c
Normal 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;
|
||||
}
|
||||
39
tp1/Sources-TD1/Exercice8.1.c
Normal file
39
tp1/Sources-TD1/Exercice8.1.c
Normal 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);
|
||||
}
|
||||
39
tp1/Sources-TD1/Exercice8.2.c
Normal file
39
tp1/Sources-TD1/Exercice8.2.c
Normal 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);
|
||||
}
|
||||
39
tp1/Sources-TD1/Exercice8.3.c
Normal file
39
tp1/Sources-TD1/Exercice8.3.c
Normal 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);
|
||||
}
|
||||
45
tp1/Sources-TD1/Exercice8.4.c
Normal file
45
tp1/Sources-TD1/Exercice8.4.c
Normal 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);
|
||||
}
|
||||
440
tp1/tp1.c
Normal file
440
tp1/tp1.c
Normal 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
127
tp1/tp1.h
Normal 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
47
tp2/compare.c
Normal 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
61
tp2/compare.h
Normal 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
31
tp2/genprint.c
Normal 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
16
tp2/genprint.h
Normal 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
46
tp2/main.c
Normal 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
13
tp2/sujet/.ccls
Normal 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
3640
tp2/sujet/.uncrustify
Normal file
File diff suppressed because it is too large
Load Diff
41
tp2/sujet/Makefile
Normal file
41
tp2/sujet/Makefile
Normal 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
20
tp2/sujet/README.md
Normal 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
8
tp2/sujet/array_char.txt
Normal 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
|
||||
5
tp2/sujet/array_double.txt
Normal file
5
tp2/sujet/array_double.txt
Normal 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
5
tp2/sujet/array_int.txt
Normal 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
|
||||
5
tp2/sujet/array_pointx.txt
Normal file
5
tp2/sujet/array_pointx.txt
Normal 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)
|
||||
5
tp2/sujet/array_pointy.txt
Normal file
5
tp2/sujet/array_pointy.txt
Normal 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
18
tp2/sujet/array_pt.txt
Normal 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)
|
||||
5
tp2/sujet/array_string.txt
Normal file
5
tp2/sujet/array_string.txt
Normal 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
|
||||
5
tp2/sujet/array_string2.txt
Normal file
5
tp2/sujet/array_string2.txt
Normal 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
66
tp2/sujet/compare.c
Normal 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
1
tp2/sujet/compare.d
Normal file
@@ -0,0 +1 @@
|
||||
compare.o: compare.c compare.h
|
||||
42
tp2/sujet/compare.h
Normal file
42
tp2/sujet/compare.h
Normal 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
BIN
tp2/sujet/compare.o
Normal file
Binary file not shown.
39
tp2/sujet/genprint.c
Normal file
39
tp2/sujet/genprint.c
Normal 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
1
tp2/sujet/genprint.d
Normal file
@@ -0,0 +1 @@
|
||||
genprint.o: genprint.c genprint.h compare.h
|
||||
57
tp2/sujet/genprint.h
Normal file
57
tp2/sujet/genprint.h
Normal 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
BIN
tp2/sujet/genprint.o
Normal file
Binary file not shown.
135
tp2/sujet/main.c
Normal file
135
tp2/sujet/main.c
Normal 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
1
tp2/sujet/main.d
Normal file
@@ -0,0 +1 @@
|
||||
main.o: main.c compare.h genprint.h
|
||||
BIN
tp2/sujet/main.o
Normal file
BIN
tp2/sujet/main.o
Normal file
Binary file not shown.
BIN
tp2/sujet/mysort
Executable file
BIN
tp2/sujet/mysort
Executable file
Binary file not shown.
BIN
tp3/TP3.tgz
Normal file
BIN
tp3/TP3.tgz
Normal file
Binary file not shown.
12
tp3/TP3/.ccls
Normal file
12
tp3/TP3/.ccls
Normal 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
3640
tp3/TP3/.uncrustify
Normal file
File diff suppressed because it is too large
Load Diff
37
tp3/TP3/Makefile
Normal file
37
tp3/TP3/Makefile
Normal 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
19
tp3/TP3/alloc.c
Normal 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
1
tp3/TP3/alloc.d
Normal file
@@ -0,0 +1 @@
|
||||
alloc.o: alloc.c alloc.h error.h
|
||||
178
tp3/TP3/alloc.h
Normal file
178
tp3/TP3/alloc.h
Normal 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
BIN
tp3/TP3/alloc.o
Normal file
Binary file not shown.
58
tp3/TP3/error.h
Normal file
58
tp3/TP3/error.h
Normal 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
128
tp3/TP3/main.c
Normal 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
2
tp3/TP3/main.d
Normal 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
BIN
tp3/TP3/main.o
Normal file
Binary file not shown.
53
tp3/TP3/queue.c
Normal file
53
tp3/TP3/queue.c
Normal 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
1
tp3/TP3/queue.d
Normal file
@@ -0,0 +1 @@
|
||||
queue.o: queue.c queue.h alloc.h error.h
|
||||
45
tp3/TP3/queue.h
Normal file
45
tp3/TP3/queue.h
Normal 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
BIN
tp3/TP3/queue.o
Normal file
Binary file not shown.
21
tp3/TP3/queuetest.c
Normal file
21
tp3/TP3/queuetest.c
Normal 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
1
tp3/TP3/queuetest.d
Normal file
@@ -0,0 +1 @@
|
||||
queuetest.o: queuetest.c queuetest.h queue.h alloc.h error.h
|
||||
36
tp3/TP3/queuetest.h
Normal file
36
tp3/TP3/queuetest.h
Normal 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
BIN
tp3/TP3/queuetest.o
Normal file
Binary file not shown.
80
tp3/TP3/stack.c
Normal file
80
tp3/TP3/stack.c
Normal 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
1
tp3/TP3/stack.d
Normal file
@@ -0,0 +1 @@
|
||||
stack.o: stack.c stack.h alloc.h error.h
|
||||
49
tp3/TP3/stack.h
Normal file
49
tp3/TP3/stack.h
Normal 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
BIN
tp3/TP3/stack.o
Normal file
Binary file not shown.
BIN
tp3/TP3/stackqueue
Executable file
BIN
tp3/TP3/stackqueue
Executable file
Binary file not shown.
68
tp3/TP3/stacktest.c
Normal file
68
tp3/TP3/stacktest.c
Normal 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
2
tp3/TP3/stacktest.d
Normal 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
104
tp3/TP3/stacktest.h
Normal 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
BIN
tp3/TP3/stacktest.o
Normal file
Binary file not shown.
83
tp3/TP3/testprint.c
Normal file
83
tp3/TP3/testprint.c
Normal 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
1
tp3/TP3/testprint.d
Normal 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
51
tp3/TP3/testprint.h
Normal 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
BIN
tp3/TP3/testprint.o
Normal file
Binary file not shown.
13
tp3/TP3/tools.h
Normal file
13
tp3/TP3/tools.h
Normal 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_
|
||||
Reference in New Issue
Block a user