OVH Cloud OVH Cloud

DEBUTANT EN C

12 réponses
Avatar
MOST
Bonjour a tous
Débutant en c j'ai écrit un truc qui sert pas a grand chose sinon classer en
ordre croissant décroissant et pyramidal le contenu d'une variable
voir le code à la suite. n'étant pas spécialement content de mon code je
m'adresse au pro du c++ que vous êtes pour me donner une piste
pour optimiser mon code, notament pour récuperer la taille de TabValue car
quand je fais un ntaille = TabValue.size() ca le fais pas probleme de typage
des variables sans aucun doute mais je vois pas :(

d'avance merci a vous
Michaël

adresse mail : diablofr_arrobase_live.fr.

#include <stdio.h>
#include <stdlib.h>

// DEFINITION DE VRAI ET FAUX
#define TRUE 1
#define FALSE 0
#define s32 signed long


// chaine originale c'est celle que tu m'a donné

//s32 TabValue[] = { 0, 10, 22, 33, 44, 55, 66, 77, 80 };


// Déclaration du tableau
// j'ai rajouté deux éléments et j'ai mélangé les entiers sinon c'était
trop facile ;-)
// les deux éléments rajoutés c'est pour la pyramide

s32 TabValue[] = { 22, 10, 44, 33, 66, 55, 80, 77, 134 , 3, 19 , 12 , 99,
121 , 130} ;


// ***********************************************************************/
// * DECLARATION DES VARIABLES

int i; // compteur
int k;
int pyram =0; // pour l'impression pyramidale
int num; // option du menu
int ntaille; // recupera la taille du tableau
int cpt = 1;
// **********************************************************************/

// FONCTION DE TRI PYRAMIDAL
void tri_pyramidal(int *t, int n)
{
int j = 0; // pour la boucle
int tmp = 0; //permet la permuation
int en_ordre; // condition de boucle
while(en_ordre) // boucle
{
en_ordre = FALSE; // en ordre = faux pour boucler
for(j =0 ; j < n-1 ; j++) // si t[j] > t[j+1] si la case tabvalue
en cours est plus grande que la case suivante de TabValue alors
{
if (t[j] < t[j+1]) // si t[j] < t[j+1] si la case TabValue en
cours est plus petite que la case suivante de TabValue alors
{
tmp = t[j+1]; // permutation = Tabvalue +1
t[j+1] = t[j]; // Tabvalue + 1 = TabValue en cours
t[j] = tmp; // TabValue en cours = permutation
en_ordre = TRUE; // en ordre = Vrai Fin de la procédure de
tri
}
}
}
}


// FONCTION DE TRI CROISSANT

void tri_croissant(int *t,int n)
// EXPLICATION
// t = TabValue, n = taille de TabValue
{

int j =0; // pour la boucle
int tmp = 0; // permet la permutation
int en_ordre; // condition de boucle
while(en_ordre) // boucle
{
en_ordre = FALSE; // en ordre = faux pour boucler
for (j = 0 ; j < n-1 ; j++) // si j est plus petit que la taille du
tableau -1 on incrémente
{
if (t[j] > t[j+1]) // si t[j] > t[j+1] si la case tabvalue en
cours est plus grande que la case suivante de TabValue alors
{
tmp = t[j+1]; // temp = t[j+1] soit temp = case suivante de
TabValue
t[j+1] = t[j]; // Case suivante de TabValue = case
précédente de TabValue parce que son contenu est forcément plus petit
t[j] = tmp; // Case en cours de TabValue = à la valeur temp
mise de coté plus haut
en_ordre = TRUE; // en_ordre = Vrai fin de la procédure de
tri
}
}

}

}



// FONCTION DE TRI DECROISSANT
void tri_decroissant(int *t, int n)
{
int j = 0; // pour la boucle
int tmp = 0; //permet la permuation
int en_ordre; // condition de boucle
while(en_ordre) // boucle
{
en_ordre = FALSE; // en ordre = faux pour boucler
for(j =0 ; j < n-1 ; j++) // si t[j] > t[j+1] si la case tabvalue
en cours est plus grande que la case suivante de TabValue alors
{
if (t[j] < t[j+1]) // si t[j] < t[j+1] si la case TabValue en
cours est plus petite que la case suivante de TabValue alors
{
tmp = t[j+1]; // permutation = Tabvalue +1
t[j+1] = t[j]; // Tabvalue + 1 = TabValue en cours
t[j] = tmp; // TabValue en cours = permutation
en_ordre = TRUE; // en ordre = Vrai Fin de la procédure de
tri
}
}
}
}



// fonction principal
int main(void)
{


// présentation
printf("Programme : Algorithmes De Tri / %c Version 01 Le
23/11/2011\n",184);
printf("R%calis%c par: MICHAEL AMZEL \n", 130, 130);
printf("Encadr%c par: CHRISTOPHE NAZARET \n\n",130);


// rappel du contenu de TabValue
printf ("\n\nVoici le contenu de la variable TabValue.\n\n");
for (i = 0 ; i < 15 ; i++)
{
printf("%d ", TabValue[i]);
ntaille = ntaille++;
}

printf("\n\n");
// liste des algorithmes de tri
printf("\n1. Le tri par ordre Croissant\n");
printf("2. Le tri par ordre D%ccroissant\n",130);
printf("3. Le tri pyramidale\n");
// choisir l'algorithme à appliquer

// boucle pour tester l'entrée clavier saisie par l'utilisateur
do {
printf("\nVeuillez saisir le num%cro de l'algorithme de tri %c appliquer
: ",130,133); // affichage du message : Veuillez saisie le numéro de
l'algorithme de tri a appliquer
scanf("%d",&num); // recupere la saisie clavier
if ((num>6)||(num<1)) printf("\n(!) Ce num%cro ne figure pas dans la
liste !\n",130);} // message d'erreur comme quoi le numéro n'est pas dans le
choix des options possible
while((num>3)||(num<1)); // verifie que l'option entrée fais partie de
la liste


// appliquer l'algorithme choisi
//on passe en argument : TabValue, la Taille de TabValue et le numéro de
l'option comme ca y a qu'une fonction de tri au lieu d'en avoir trois
if (num==1) tri_croissant(TabValue, ntaille);
if (num==2) tri_decroissant(TabValue, ntaille);
if (num==3) pyram =1; tri_pyramidal(TabValue, ntaille);

// si pyram = 0 alors on affiche le resultat normalement pour le tri
croissant et décroissant
if(pyram == 0)
{
// résultat pour tri croissant et décroissant
printf("\nTRI%cS! : ",144); // AFFICHE LE MESSAGE SUIVANT : TRIES
MAIS AVEC UN ACCENT
for (i=0 ; i<ntaille ;i++) // BOUCLE SUR LA LECTURE DE TabValue
printf("%d ",TabValue[i]); printf("\n\n"); // affiche la case
mémoire TabValue en cours et passe à la ligne suivante

}
else
// Si pyram = 1 alors on affiche le tri pyramidal
// EDITION TRI PYRAMIDAL
{
int ligne = 0;// pour la boucle
int valeur = (ntaille /2) -1;
int caselue = 0; // lecture de la case memoire en cours
for (i = 0 ; i < valeur ; i++) // boucle pour la lecture du
tableau tant que i< ntaille alors on ajoute 1 à i
{
for(ligne = 0 ; ligne < i ; ligne++) // boucle pour la
pyramide si ligne < i alors on ajoute 1 à ligne
{
printf("%d ",TabValue[caselue]); // affichage de la
valeur TabValue en cours
if (caselue < ntaille ) // si caselue < ntaille
alors
{
caselue++; // on increment caselue
}

}
printf("\n"); // on passe a la ligne suivante
}
}

system("PAUSE"); // on fait une pause après l'affichage du résultat
return 0; //on renvoie 0 et on termine le programme
}// fin du programme

10 réponses

1 2
Avatar
Pascal J. Bourguignon
"MOST" writes:

Bonjour a tous
Débutant en c



Alors pourquoi poser une question sur fr.comp.lang.c++ au lieu de
fr.comp.lang.c ? C et C++ sont deux langages différents.


j'ai écrit un truc qui sert pas a grand chose sinon classer en
ordre croissant décroissant et pyramidal le contenu d'une variable
voir le code à la suite. n'étant pas spécialement content de mon code je
m'adresse au pro du c++ que vous êtes pour me donner une piste
pour optimiser mon code, notament pour récuperer la taille de TabValue car
quand je fais un ntaille = TabValue.size() ca le fais pas probleme de typage
des variables sans aucun doute mais je vois pas :(




Il y a trop de commentaires inutiles.

Il y a trop de variables globales.


#define s32 signed long
Utiliser typedef pour définir un type!
typedef signed long s32;



int en_ordre; // condition de boucle
while(en_ordre) // boucle

Comportement indéfini: on ne sait pas si en_ordre sera initialisé à vrai
ou faux.



printf("R%calis%c par: MICHAEL AMZEL n", 130, 130);

Ceci assume un encodage pour les caractères accentué. Ça ne marchera
pas, par exemple, si l'utilisateur a
$ env|grep LC
LC_CTYPE=en_US.UTF-8

Utiliser une bibliothèque de localisation et éviter tout caractère
non-ASCII dans les sources.

#include <libintl.h>

printf("%sn",gettext("Realized by MICHAEL AMZEL."));



Lire "The Art of Unix Programming"
http://catb.org/~esr/writings/taoup/html/
En particulier le chapitre 11.

Il serait plus pratique d'implémenter le programme comme un filtre:

ma-sort [--version|--croisant|--decroisant|--pyramidal] < input.data > output.data




if (num==3) pyram =1; tri_pyramidal(TabValue, ntaille);

La syntaxe de if est:

ifstatement ::= if ( <condition> ) <statement> [ else <statement> ] .




system("PAUSE"); // on fait une pause après l'affichage du résultat

Ne pas utiliser system(3), c'est une fonction dangereuse en terme de
sécurité. Ne pas implémenter de pause dans le programme lui-même! Si
une pause est nécessaire, on appelle le programme en envoyant la sortie
dans more:

ma-sort --pyramidal < input.data | more


#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <libgen.h> // basename


typedef enum { false=0,true=1 } bool;
typedef signed long s32;
#define s32_format "%ld"


// Error handling.
// We just exit in case of error.
// In a more sophisticated program, we could use setjmp and longjmp to
// handle errors.

const char* pname="ma-sort";

void error(const char* message,...){
va_list ap;
va_start(ap,message);
fprintf(stderr,"%s: ",pname);
vfprintf(stderr,message,ap);
fprintf(stderr,"n");
va_end(ap);
exit(1);
}



// The Table abstract data type.

typedef struct {
int count;
int allocated;
s32* elements;
} table;


table* table_new(int allocated){
table* t=malloc(sizeof(*t));
if(t){
t->count=0;
t->allocated=allocated;
t->elements=malloc(sizeof(t->allocated*(*(t->elements))));
if(!(t->elements)){
free(t);
t=0;
}
}
if(!t){
error("Out of memory");
}
return(t);
}

void table_expand(table* t,int new_allocated){
s32* new_elements=malloc(sizeof(new_allocated*(*new_elements)));
if(new_elements){
int i;
for(i=0;i<t->count;i++){
new_elements[i]=t->elements[i];
}
free(t->elements);
t->elements=new_elements;
t->allocated=new_allocated;
}else{
error("Out of memory");
}
}

void table_add_element(table* t,s32 element){
if(t->count>=t->allocated){
table_expand(t,t->allocated*2);
}
t->elements[t->count++]=element;
}


table* table_read(FILE* input){
table* t=table_new(1000);
while(!feof(input)){
s32 element;
fscanf(input,s32_format,&element);
table_add_element(t,element);
}
return(t);
}

void table_print(FILE* output,table* t){
int i;
for(i=0;i<t->count;i++){
fprintf(output,s32_format "n",t->elements[i]);
}
}


// The algorithm abstract data type.
// It has two methods, one to sort the table, one to print it.

typedef void (*sort_routine)(table*);
typedef void (*print_routine)(FILE*,table*);

typedef struct {
sort_routine sort;
print_routine print;
} algorithm;



// the methods:

int croissant(const void* a,const void* b){
const s32* sa=a;
const s32* sb=b;
return((*sa<*sb)?-1:((*sa==*sb)?0:1));
}


int decroissant(const void* a,const void* b){
const s32* sa=a;
const s32* sb=b;
return((*sa>*sb)?-1:((*sa==*sb)?0:1));
}

void sort_croissant(table* t){
qsort(t->elements,t->count,sizeof(t->elements[0]),croissant);
}

void sort_decroissant(table* t){
qsort(t->elements,t->count,sizeof(t->elements[0]),decroissant);
}

void sort_pyramidal(table* t){
// I didn't see any difference between tri_pyramidal and tri_decroissant...
sort_decroissant(t);
}

void pyramidal_table_print(FILE* output,table* t){
int slot=0;
int limit=t->count/2-1;
int i;
for(i=0;i<limit;i++){
int line;
for(line=0;line<i;line++){
fprintf(output,s32_format " ",t->elements[slot]);
if(slot<limit){
slot++;
}
}
fprintf(output,"n");
}
}


algorithm croissant_algo;
algorithm decroissant_algo;
algorithm pyramidal_algo;

void initialize_algorithms(void){
croissant_algo.sort=sort_croissant;
croissant_algo.print=table_print;

decroissant_algo.sort=sort_decroissant;
decroissant_algo.print=table_print;

pyramidal_algo.sort=sort_croissant;
pyramidal_algo.print=pyramidal_table_print;
}


// The main program:

void version(const char* pname){
// add gettext and the localization file if wanted.
printf("%s Program: Sort algorithms / Version 01 on 2011-11-23n",pname);
printf("Realized by MICHAEL AMZELn");
printf("Directed by CHRISTOPHE NAZARETnn");
}


void usage(const char* pname){
const char* options[]={"--help","--version","--croissant","--decroissant","--pyramidal",0};
char sep='[';
int i;
printf("%s usage:n",pname);
printf(" %s ",pname);
for(i=0;options[i];i++){
printf("%c%s",sep,options[i]);
sep='|';
}
printf("] < input > outputn");
}



algorithm* analyse_options(int argc,const char** argv){
char* tmp=malloc(1+strlen(argv[0]));
strcpy(tmp,argv[0]);
pnameºsename(tmp);

switch(argc){
case 1:
return(&croissant_algo);
case 2:
if(strcmp("--version",argv[1])==0){
version(pname);
exit(0);
}else if(strcmp("--croissant",argv[1])==0){
return(&croissant_algo);
}else if(strcmp("--decroissant",argv[1])==0){
return(&decroissant_algo);
}else if(strcmp("--pyramidal",argv[1])==0){
return(&pyramidal_algo);
}else if(strcmp("--help",argv[1])==0){
usage(pname);
exit(0);
}else{
error("Invalid option, try:n %s --help",pname);
}
break;
default:
usage(pname);
exit(1);
}
}



int main(int argc,const char** argv){

initialize_algorithms();
algorithm* selected=analyse_options(argc,argv);

table* t=table_read(stdin);
selected->sort(t);
selected->print(stdout,t);

return(0);
}


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Avatar
MOST
Merci d'avoir pris le temps de corriger mes erreurs de débutant
je teste ta solution
Amicalement
Michaël


"Pascal J. Bourguignon" a écrit dans le message de
news:
"MOST" writes:

Bonjour a tous
Débutant en c



Alors pourquoi poser une question sur fr.comp.lang.c++ au lieu de
fr.comp.lang.c ? C et C++ sont deux langages différents.


j'ai écrit un truc qui sert pas a grand chose sinon classer en
ordre croissant décroissant et pyramidal le contenu d'une variable
voir le code à la suite. n'étant pas spécialement content de mon code je
m'adresse au pro du c++ que vous êtes pour me donner une piste
pour optimiser mon code, notament pour récuperer la taille de TabValue
car
quand je fais un ntaille = TabValue.size() ca le fais pas probleme de
typage
des variables sans aucun doute mais je vois pas :(




Il y a trop de commentaires inutiles.

Il y a trop de variables globales.


#define s32 signed long
Utiliser typedef pour définir un type!
typedef signed long s32;



int en_ordre; // condition de boucle
while(en_ordre) // boucle

Comportement indéfini: on ne sait pas si en_ordre sera initialisé à vrai
ou faux.



printf("R%calis%c par: MICHAEL AMZEL n", 130, 130);

Ceci assume un encodage pour les caractères accentué. Ça ne marchera
pas, par exemple, si l'utilisateur a
$ env|grep LC
LC_CTYPE=en_US.UTF-8

Utiliser une bibliothèque de localisation et éviter tout caractère
non-ASCII dans les sources.

#include <libintl.h>

printf("%sn",gettext("Realized by MICHAEL AMZEL."));



Lire "The Art of Unix Programming"
http://catb.org/~esr/writings/taoup/html/
En particulier le chapitre 11.

Il serait plus pratique d'implémenter le programme comme un filtre:

ma-sort [--version|--croisant|--decroisant|--pyramidal] < input.data >
output.data




if (num==3) pyram =1; tri_pyramidal(TabValue, ntaille);

La syntaxe de if est:

ifstatement ::= if ( <condition> ) <statement> [ else <statement> ] .




system("PAUSE"); // on fait une pause après l'affichage du résultat

Ne pas utiliser system(3), c'est une fonction dangereuse en terme de
sécurité. Ne pas implémenter de pause dans le programme lui-même! Si
une pause est nécessaire, on appelle le programme en envoyant la sortie
dans more:

ma-sort --pyramidal < input.data | more


#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <libgen.h> // basename


typedef enum { false=0,true=1 } bool;
typedef signed long s32;
#define s32_format "%ld"


// Error handling.
// We just exit in case of error.
// In a more sophisticated program, we could use setjmp and longjmp to
// handle errors.

const char* pname="ma-sort";

void error(const char* message,...){
va_list ap;
va_start(ap,message);
fprintf(stderr,"%s: ",pname);
vfprintf(stderr,message,ap);
fprintf(stderr,"n");
va_end(ap);
exit(1);
}



// The Table abstract data type.

typedef struct {
int count;
int allocated;
s32* elements;
} table;


table* table_new(int allocated){
table* t=malloc(sizeof(*t));
if(t){
t->count=0;
t->allocated=allocated;
t->elements=malloc(sizeof(t->allocated*(*(t->elements))));
if(!(t->elements)){
free(t);
t=0;
}
}
if(!t){
error("Out of memory");
}
return(t);
}

void table_expand(table* t,int new_allocated){
s32* new_elements=malloc(sizeof(new_allocated*(*new_elements)));
if(new_elements){
int i;
for(i=0;i<t->count;i++){
new_elements[i]=t->elements[i];
}
free(t->elements);
t->elements=new_elements;
t->allocated=new_allocated;
}else{
error("Out of memory");
}
}

void table_add_element(table* t,s32 element){
if(t->count>=t->allocated){
table_expand(t,t->allocated*2);
}
t->elements[t->count++]=element;
}


table* table_read(FILE* input){
table* t=table_new(1000);
while(!feof(input)){
s32 element;
fscanf(input,s32_format,&element);
table_add_element(t,element);
}
return(t);
}

void table_print(FILE* output,table* t){
int i;
for(i=0;i<t->count;i++){
fprintf(output,s32_format "n",t->elements[i]);
}
}


// The algorithm abstract data type.
// It has two methods, one to sort the table, one to print it.

typedef void (*sort_routine)(table*);
typedef void (*print_routine)(FILE*,table*);

typedef struct {
sort_routine sort;
print_routine print;
} algorithm;



// the methods:

int croissant(const void* a,const void* b){
const s32* sa=a;
const s32* sb=b;
return((*sa<*sb)?-1:((*sa==*sb)?0:1));
}


int decroissant(const void* a,const void* b){
const s32* sa=a;
const s32* sb=b;
return((*sa>*sb)?-1:((*sa==*sb)?0:1));
}

void sort_croissant(table* t){
qsort(t->elements,t->count,sizeof(t->elements[0]),croissant);
}

void sort_decroissant(table* t){
qsort(t->elements,t->count,sizeof(t->elements[0]),decroissant);
}

void sort_pyramidal(table* t){
// I didn't see any difference between tri_pyramidal and
tri_decroissant...
sort_decroissant(t);
}

void pyramidal_table_print(FILE* output,table* t){
int slot=0;
int limit=t->count/2-1;
int i;
for(i=0;i<limit;i++){
int line;
for(line=0;line<i;line++){
fprintf(output,s32_format " ",t->elements[slot]);
if(slot<limit){
slot++;
}
}
fprintf(output,"n");
}
}


algorithm croissant_algo;
algorithm decroissant_algo;
algorithm pyramidal_algo;

void initialize_algorithms(void){
croissant_algo.sort=sort_croissant;
croissant_algo.print=table_print;

decroissant_algo.sort=sort_decroissant;
decroissant_algo.print=table_print;

pyramidal_algo.sort=sort_croissant;
pyramidal_algo.print=pyramidal_table_print;
}


// The main program:

void version(const char* pname){
// add gettext and the localization file if wanted.
printf("%s Program: Sort algorithms / Version 01 on
2011-11-23n",pname);
printf("Realized by MICHAEL AMZELn");
printf("Directed by CHRISTOPHE NAZARETnn");
}


void usage(const char* pname){
const char*
options[]={"--help","--version","--croissant","--decroissant","--pyramidal",0};
char sep='[';
int i;
printf("%s usage:n",pname);
printf(" %s ",pname);
for(i=0;options[i];i++){
printf("%c%s",sep,options[i]);
sep='|';
}
printf("] < input > outputn");
}



algorithm* analyse_options(int argc,const char** argv){
char* tmp=malloc(1+strlen(argv[0]));
strcpy(tmp,argv[0]);
pnameºsename(tmp);

switch(argc){
case 1:
return(&croissant_algo);
case 2:
if(strcmp("--version",argv[1])==0){
version(pname);
exit(0);
}else if(strcmp("--croissant",argv[1])==0){
return(&croissant_algo);
}else if(strcmp("--decroissant",argv[1])==0){
return(&decroissant_algo);
}else if(strcmp("--pyramidal",argv[1])==0){
return(&pyramidal_algo);
}else if(strcmp("--help",argv[1])==0){
usage(pname);
exit(0);
}else{
error("Invalid option, try:n %s --help",pname);
}
break;
default:
usage(pname);
exit(1);
}
}



int main(int argc,const char** argv){

initialize_algorithms();
algorithm* selected=analyse_options(argc,argv);

table* t=table_read(stdin);
selected->sort(t);
selected->print(stdout,t);

return(0);
}


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Avatar
MOST
Désolé j'ai oublié de préciser que pour cet exercice je n'avais pas le droit
d'utiliser la commande qsort
ordre du prof :(


"Pascal J. Bourguignon" a écrit dans le message de
news:
"MOST" writes:

Bonjour a tous
Débutant en c



Alors pourquoi poser une question sur fr.comp.lang.c++ au lieu de
fr.comp.lang.c ? C et C++ sont deux langages différents.


j'ai écrit un truc qui sert pas a grand chose sinon classer en
ordre croissant décroissant et pyramidal le contenu d'une variable
voir le code à la suite. n'étant pas spécialement content de mon code je
m'adresse au pro du c++ que vous êtes pour me donner une piste
pour optimiser mon code, notament pour récuperer la taille de TabValue
car
quand je fais un ntaille = TabValue.size() ca le fais pas probleme de
typage
des variables sans aucun doute mais je vois pas :(




Il y a trop de commentaires inutiles.

Il y a trop de variables globales.


#define s32 signed long
Utiliser typedef pour définir un type!
typedef signed long s32;



int en_ordre; // condition de boucle
while(en_ordre) // boucle

Comportement indéfini: on ne sait pas si en_ordre sera initialisé à vrai
ou faux.



printf("R%calis%c par: MICHAEL AMZEL n", 130, 130);

Ceci assume un encodage pour les caractères accentué. Ça ne marchera
pas, par exemple, si l'utilisateur a
$ env|grep LC
LC_CTYPE=en_US.UTF-8

Utiliser une bibliothèque de localisation et éviter tout caractère
non-ASCII dans les sources.

#include <libintl.h>

printf("%sn",gettext("Realized by MICHAEL AMZEL."));



Lire "The Art of Unix Programming"
http://catb.org/~esr/writings/taoup/html/
En particulier le chapitre 11.

Il serait plus pratique d'implémenter le programme comme un filtre:

ma-sort [--version|--croisant|--decroisant|--pyramidal] < input.data >
output.data




if (num==3) pyram =1; tri_pyramidal(TabValue, ntaille);

La syntaxe de if est:

ifstatement ::= if ( <condition> ) <statement> [ else <statement> ] .




system("PAUSE"); // on fait une pause après l'affichage du résultat

Ne pas utiliser system(3), c'est une fonction dangereuse en terme de
sécurité. Ne pas implémenter de pause dans le programme lui-même! Si
une pause est nécessaire, on appelle le programme en envoyant la sortie
dans more:

ma-sort --pyramidal < input.data | more


#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <libgen.h> // basename


typedef enum { false=0,true=1 } bool;
typedef signed long s32;
#define s32_format "%ld"


// Error handling.
// We just exit in case of error.
// In a more sophisticated program, we could use setjmp and longjmp to
// handle errors.

const char* pname="ma-sort";

void error(const char* message,...){
va_list ap;
va_start(ap,message);
fprintf(stderr,"%s: ",pname);
vfprintf(stderr,message,ap);
fprintf(stderr,"n");
va_end(ap);
exit(1);
}



// The Table abstract data type.

typedef struct {
int count;
int allocated;
s32* elements;
} table;


table* table_new(int allocated){
table* t=malloc(sizeof(*t));
if(t){
t->count=0;
t->allocated=allocated;
t->elements=malloc(sizeof(t->allocated*(*(t->elements))));
if(!(t->elements)){
free(t);
t=0;
}
}
if(!t){
error("Out of memory");
}
return(t);
}

void table_expand(table* t,int new_allocated){
s32* new_elements=malloc(sizeof(new_allocated*(*new_elements)));
if(new_elements){
int i;
for(i=0;i<t->count;i++){
new_elements[i]=t->elements[i];
}
free(t->elements);
t->elements=new_elements;
t->allocated=new_allocated;
}else{
error("Out of memory");
}
}

void table_add_element(table* t,s32 element){
if(t->count>=t->allocated){
table_expand(t,t->allocated*2);
}
t->elements[t->count++]=element;
}


table* table_read(FILE* input){
table* t=table_new(1000);
while(!feof(input)){
s32 element;
fscanf(input,s32_format,&element);
table_add_element(t,element);
}
return(t);
}

void table_print(FILE* output,table* t){
int i;
for(i=0;i<t->count;i++){
fprintf(output,s32_format "n",t->elements[i]);
}
}


// The algorithm abstract data type.
// It has two methods, one to sort the table, one to print it.

typedef void (*sort_routine)(table*);
typedef void (*print_routine)(FILE*,table*);

typedef struct {
sort_routine sort;
print_routine print;
} algorithm;



// the methods:

int croissant(const void* a,const void* b){
const s32* sa=a;
const s32* sb=b;
return((*sa<*sb)?-1:((*sa==*sb)?0:1));
}


int decroissant(const void* a,const void* b){
const s32* sa=a;
const s32* sb=b;
return((*sa>*sb)?-1:((*sa==*sb)?0:1));
}

void sort_croissant(table* t){
qsort(t->elements,t->count,sizeof(t->elements[0]),croissant);
}

void sort_decroissant(table* t){
qsort(t->elements,t->count,sizeof(t->elements[0]),decroissant);
}

void sort_pyramidal(table* t){
// I didn't see any difference between tri_pyramidal and
tri_decroissant...
sort_decroissant(t);
}

void pyramidal_table_print(FILE* output,table* t){
int slot=0;
int limit=t->count/2-1;
int i;
for(i=0;i<limit;i++){
int line;
for(line=0;line<i;line++){
fprintf(output,s32_format " ",t->elements[slot]);
if(slot<limit){
slot++;
}
}
fprintf(output,"n");
}
}


algorithm croissant_algo;
algorithm decroissant_algo;
algorithm pyramidal_algo;

void initialize_algorithms(void){
croissant_algo.sort=sort_croissant;
croissant_algo.print=table_print;

decroissant_algo.sort=sort_decroissant;
decroissant_algo.print=table_print;

pyramidal_algo.sort=sort_croissant;
pyramidal_algo.print=pyramidal_table_print;
}


// The main program:

void version(const char* pname){
// add gettext and the localization file if wanted.
printf("%s Program: Sort algorithms / Version 01 on
2011-11-23n",pname);
printf("Realized by MICHAEL AMZELn");
printf("Directed by CHRISTOPHE NAZARETnn");
}


void usage(const char* pname){
const char*
options[]={"--help","--version","--croissant","--decroissant","--pyramidal",0};
char sep='[';
int i;
printf("%s usage:n",pname);
printf(" %s ",pname);
for(i=0;options[i];i++){
printf("%c%s",sep,options[i]);
sep='|';
}
printf("] < input > outputn");
}



algorithm* analyse_options(int argc,const char** argv){
char* tmp=malloc(1+strlen(argv[0]));
strcpy(tmp,argv[0]);
pnameºsename(tmp);

switch(argc){
case 1:
return(&croissant_algo);
case 2:
if(strcmp("--version",argv[1])==0){
version(pname);
exit(0);
}else if(strcmp("--croissant",argv[1])==0){
return(&croissant_algo);
}else if(strcmp("--decroissant",argv[1])==0){
return(&decroissant_algo);
}else if(strcmp("--pyramidal",argv[1])==0){
return(&pyramidal_algo);
}else if(strcmp("--help",argv[1])==0){
usage(pname);
exit(0);
}else{
error("Invalid option, try:n %s --help",pname);
}
break;
default:
usage(pname);
exit(1);
}
}



int main(int argc,const char** argv){

initialize_algorithms();
algorithm* selected=analyse_options(argc,argv);

table* t=table_read(stdin);
selected->sort(t);
selected->print(stdout,t);

return(0);
}


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Avatar
Pascal J. Bourguignon
"MOST" writes:

Désolé j'ai oublié de préciser que pour cet exercice je n'avais pas le droit
d'utiliser la commande qsort
ordre du prof :(



Ce n'est pas grave. Le principe important, c'est que trier par ordre
croissant ou décroissant doit se faire avec la même routine de tri, en
passant une fonction de comparaison différente.

Donc il suffit que tu implémente une routine de tri unique similaire à
qsort, pour la remplacer.


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
Avatar
Wykaaa
MOST a écrit :


// DEFINITION DE VRAI ET FAUX
#define TRUE 1
#define FALSE 0



Juste une remarque.

Plutôt :
enum boolean {FALSE=0, TRUE=1};
Avatar
Olivier Miakinen
Le 03/12/2011 00:42, Wykaaa répondit à MOST :

// DEFINITION DE VRAI ET FAUX
#define TRUE 1
#define FALSE 0



Juste une remarque.

Plutôt :
enum boolean {FALSE=0, TRUE=1};



Note que Pascal Bourguignon, dans sa réponse très complète et très
détaillée, l'avait déjà signalé. Il avait même propose mieux :

<cit. <news:
typedef enum { false=0,true=1 } bool;
</cit.>
Avatar
Wykaaa
Olivier Miakinen a écrit :
Le 03/12/2011 00:42, Wykaaa répondit à MOST :
// DEFINITION DE VRAI ET FAUX
#define TRUE 1
#define FALSE 0


Juste une remarque.

Plutôt :
enum boolean {FALSE=0, TRUE=1};



Note que Pascal Bourguignon, dans sa réponse très complète et très
détaillée, l'avait déjà signalé. Il avait même propose mieux :

<cit. <news:
typedef enum { false=0,true=1 } bool;
</cit.>



Oooops. Je n'avais pas lu en détail sa réponse. Désolé.
Avatar
MOST
En tous les cas Encore une fois un Grand Merci à vous tous, pour avoir pris
le temps de me répondre
Cordialement
Michaël

"Wykaaa" a écrit dans le message de news:
4edaace6$0$5690$
Olivier Miakinen a écrit :
Le 03/12/2011 00:42, Wykaaa répondit à MOST :
// DEFINITION DE VRAI ET FAUX
#define TRUE 1
#define FALSE 0


Juste une remarque.

Plutôt :
enum boolean {FALSE=0, TRUE=1};



Note que Pascal Bourguignon, dans sa réponse très complète et très
détaillée, l'avait déjà signalé. Il avait même propose mieux :

<cit. <news:
typedef enum { false=0,true=1 } bool;
</cit.>



Oooops. Je n'avais pas lu en détail sa réponse. Désolé.

Avatar
Marc
Olivier Miakinen wrote:

typedef enum { false=0,true=1 } bool;



Si quelqu'un inclut <stdbool.h>, ça risque d'être douloureux.
Avatar
Pascal J. Bourguignon
Marc writes:

Olivier Miakinen wrote:

typedef enum { false=0,true=1 } bool;



Si quelqu'un inclut <stdbool.h>, ça risque d'être douloureux.



Heureusement.

--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
1 2