#include #include #include struct int_couple { int a; int b; }; struct int_couple minmax(int n, int tab[]) { struct int_couple res = { tab[0], tab[0] }; // FIXME ce code est foireux si n == 0, // proposez une solution pour le rendre robuste a ce cas precis. for (int i = 1; i < n; i++) { if (tab[i] > res.b) res.b = tab[i]; if (tab[i] < res.a) res.a = tab[i]; } return res; } int exo1(int argc, char* argv[]) { int tab[argc]; for (int i = 0; i < argc; i++) tab[i] = atoi(argv[i]); struct int_couple mm = minmax(argc, tab); printf("min %d, max %d\n", mm.a, mm.b); return 0; } /////////////////////////////////////////// // Ceci est une valeur de epsilon franchement arbitraire #define EPSILON 0.00001 struct coefs { double a; double b; double c; }; struct roots { double r1; double r2; }; double resolv(double x, struct coefs poly) { return poly.a * x * x + poly.b * x + poly.c; } void print_poly(struct coefs poly) { printf("f(x) = %lgx**2 + %lgx + %lg\n", poly.a, poly.b, poly.c); } struct coefs scan_poly() { struct coefs p; printf("Veuillez saisir les 3 coeficients de f séparés par un espace:\n"); scanf("%lf %lf %lf", &p.a, &p.b, &p.c); return p; } struct roots real_roots(struct coefs p, double epsilon) { double delta = p.b * p.b - 4 * p.a * p.c; if (delta > epsilon) { struct roots r = { ((-p.b - sqrt(delta)) / 2 * p.a), ((-p.b + sqrt(delta)) / 2 * p.a) }; return r; } double s; if (fabs(delta) <= epsilon) { // On est proche de zero, on considere que c'est une racine double s = -p.b / 2 * p.a; } else { // L'equitation n'a pas de solution, je n'ai pas insite en cours // mais on peut retourner deux nombres qui ne sont 'pas' des nombres (NaN, Not A Number); s = nan(0); } struct roots r = { s, s }; return r; } struct cplx { double r, i; }; struct roots_cplx { struct cplx r1, r2; }; struct roots_cplx cplx_roots(struct coefs p, double epsilon) { // En pratique on aurait modife la fonction precedente, pour les besoin de la correction // je reecris la fonction. double delta = p.b * p.b - 4 * p.a * p.c; if (delta > epsilon) { struct roots_cplx r = { { ((-p.b - sqrt(delta)) / (2 * p.a)), 0 }, { ((-p.b + sqrt(delta)) / (2 * p.a)), 0 } }; return r; } double s = -p.b / (2 * p.a); struct roots_cplx r = { { s, 0 }, { s, 0 } }; if (delta < epsilon) { // solutions complexes r.r1.i = sqrt(-delta) / (2 * p.a); r.r2.i = -sqrt(-delta) / (2 * p.a); } return r; } void print_cplx(struct cplx n) { if (n.i == 0) printf("%lg", n.r); else printf("%lg+%lgi", n.r, n.i); } void print_roots(struct roots r) { if (r.r1 == r.r2) { // ce sont les exactement les memes nombres par construction, // C'est donc un des rares cas ou l'égalite (==) est ok. printf("racine double = %lg\n", r.r1); } else { printf("racines = { %lg, %lg }\n", r.r1, r.r2); } } void print_roots_cplx(struct roots_cplx r) { if (r.r1.r == r.r2.r && r.r1.i == 0 && r.r1.i == 0) { // ce sont les exactement les memes nombres par construction, // C'est donc un des rares cas ou l'égalite (==) est ok. printf("racine double = "); print_cplx(r.r1); } else { printf("racines = { "); print_cplx(r.r1); printf(", "); print_cplx(r.r2); printf(" }\n"); } } int exo2(int argc, char* argv[]) { struct coefs p; double x; if (argc <= 3) { p = scan_poly(); } else { p.a = atof(argv[1]); p.b = atof(argv[2]); p.c = atof(argv[3]); } print_poly(p); if (argc <= 4) { printf("veuillez saisir une valeur de x:\n"); scanf("%lg", &x); } else { x = atof(argv[4]); } printf("f(%lg) = %lg", x, resolv(x, p)); print_roots(real_roots(p, EPSILON)); print_roots_cplx(cplx_roots(p, EPSILON)); return 0; } /////////////////////////////////////////////////////////////////////////////// struct point { // Remarque, cette structure point ressemble comme deux goutes d'eau // a la structure racine. Cependant elle ne servent pas les memes besoin, // c'est donc pas plus mal qu'elles soient differentes. double x, y; }; struct point scan_point() { struct point p; printf("Veuillez saisir les coordonees d'un point séparés par un espace:\n"); scanf("%lf %lf", &p.x, &p.y); return p; } void print_point(struct point p) { printf("(%lf ; %lf)", p.x, p.y); } double norm(struct point p1, struct point p2) { double a = p2.x - p1.x; double b = p2.y - p1.y; return sqrt(a*a + b*b); } struct triangle { struct point sommets[3]; // Un triangle a 3 cotes, on aurait pu les nommer a, b, c ... mais bon }; enum ttype { SCALENE, ISOCELE, RECTANGLE, EQUILATERAL, ISOCELE_RECTANGLE // Attention ici c'est une astuce ! On rappelle qu'une enumeration n'est rien de plus // qu'un entier nomme (qui commence a zero). Je me suis arrange pour que le nombre de cote // de meme longueur tombe bien avec la position dans l'enumeration. De plus si on ajoute 2 // a un type de triangle on obtien le meme type en rectangle. Le reste du code devient donc // trivial. Ce genre d'astuce n'est pas forcement evident a trouver ... mais c'est la vie. }; enum ttype type_triangle(struct triangle t) { // Je vous laisse introduire epsilon comme des grands (exemple dans l'exo precedent) double a = norm(t.sommets[0], t.sommets[1]); double b = norm(t.sommets[1], t.sommets[2]); double c = norm(t.sommets[2], t.sommets[0]); enum ttype type = (a == b) + (b == c) + (c == a); if (a*a + b*b == c*c || b*b + c*c == a*a || c*c + a*a == b*b) type += 2; return type; } void print_ttype(enum ttype type) { // ceci est aussi une astuce pour eviter de faire un switch. Il me semble l'avoir montre en cours, // si ce n'est pas le cas, voila, c'est fait ! char* names[] = { "INCONNU", "SCALENE", "ISOCELE", "RECTANGLE", "EQUILATERAL", "ISOCELE_RECTANGLE" }; if (type > ISOCELE_RECTANGLE || type < SCALENE) type = -1; printf("%s", names[type + 1]); // J'ai decale tout le monde de + 1 pour inserer le texte inconnu, // cependant dans ce code, il ne devrait jamais apparaitre } int exo3(int argc, char* argv[]) { struct point a = scan_point(); struct point b = scan_point(); printf("La distance de "); print_point(a); printf(" a "); print_point(b); printf(" est %lg\n", norm(a, b)); struct triangle tri = { { a, b, scan_point() } }; print_ttype(type_triangle(tri)); return 0; }