[résolu et amélioré !!]Problème avec math.h

Problème avec math.h [résolu et amélioré !!] - C - Programmation

Marsh Posté le 31-12-2006 à 18:35:38    

Voila, je suis sous Mandriva 2007 avec gcc version 4.1.1 20060724 (prerelease) (4.1.1-3mdk).
je fais un prog pour calculer les nombres premiers dont voici le code source :

Code :
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main(void)
  4. {
  5. int i,x;
  6. double q,fq;
  7. int l;
  8. printf("calculer les nombres premiers jusq'a : \n" );
  9. scanf("%d",&l);
  10. int t[l];
  11. x=2;
  12. t[0]=2;
  13. printf("on rentre dans DO\n" );
  14. do
  15.   {
  16.    printf(" on incrémente x :" );
  17.    x++;
  18.    printf(" x=%d\n",x);
  19.    for(i=0;i<l;i++)
  20.     {
  21.      printf("  on est dans FOR et i vaut %d ",i);
  22.      printf("donc t[i] vaut %d\n",t[i]);
  23.      printf("  on divise x par t[i] donc q= %d / %d",x,t[i]);
  24.      q = x / t[i];
  25.      printf("donc q vaut %d\n",q);
  26.      fq = floor(q);
  27.      if(fq == q)
  28.       {
  29.        t[i+1] = x;
  30.       }
  31.     }
  32.   printf("on sort de DO donc on test si x<l\n" );
  33.   }
  34. while(x<l);
  35. printf("fin\n" );
  36. return 0;
  37. }


 
quand je compile il me met ça :

Citation :

/home/nicolas/tmp/cc1miL25.o: In function `main':
nbprm.c: (.text+0x136): undefined reference to `floor'
collect2: ld returned 1 exit status


je comprend pas parce que j'inclue bien math.h , partout sur le web j'ai lu qu'il fallait l'inclure pour ce servir de  floor.
comment faut faire ??? :(  
 
merci d'avance !!!
 
PS : J'ai essayer de remplacer floor par d'autrers fonctions censées être présente dans math.h mais j'ai toujours le même message  :(

Message cité 1 fois
Message édité par nicodu95 le 04-01-2007 à 12:08:38
Reply

Marsh Posté le 31-12-2006 à 18:35:38   

Reply

Marsh Posté le 31-12-2006 à 19:10:56    

D'apres la page man (http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man3/floor.3.html) il faut aussi inclure la librairie de math a la compiltation/edition des liens -lm en ligne de commande
Y as tu pensé?

Reply

Marsh Posté le 31-12-2006 à 19:18:59    

non !! je teste !!
edit : je crois que ça marche !!!


Message édité par nicodu95 le 31-12-2006 à 19:20:05
Reply

Marsh Posté le 01-01-2007 à 00:30:17    

nicodu95 a écrit :


je comprend pas parce que j'inclue bien math.h , partout sur le web j'ai lu qu'il fallait l'inclure pour ce servir de  floor.
comment faut faire ??? :(


Inclure un header te permet juste d'avoir le prototype des fonctions. Le code exécutable des fonctions, lui, se trouve dans les diverses librairies. En général il se trouve dans la librairie standard "/usr/lib/libc.a" qui est automatiquement liée mais s'il se trouve dans une autre librairie, par exemple "/usr/lib/libm.a" c'est à toi de demander à relier la librairie en question lors de la compilation
cc prog.c /usr/lib/libm.a -o prog
 
Le raccourci "-lxxx" est un alias vers "/usr/lib/libxxx.a" donc -lm <=> /usr/lib/libm.a


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 01-01-2007 à 14:24:36    

merci pour votre aide rapide et bonne année !!!
mais pourquoi je n'est pas à faire ça pour stdio.h ??

Reply

Marsh Posté le 01-01-2007 à 14:39:42    

nicodu95 a écrit :

merci pour votre aide rapide et bonne année !!!
mais pourquoi je n'est pas à faire ça pour stdio.h ??

La bibliothèque standard du C est une collection de fonctions. Le langage C ne précise pas comment doit êre implémentée cette bibliothèque.

 

Néanmoins, le plus souvent, les fonctions de <math.h> sont séparées des autres, probablement parce qu'elles représentent un 'poids' important, qui pourrait surcharger inutilement une application qui n'utiliserait pas ces fonctions.

 

Donc, toutes les fonctions, sauf mathématiques, sont dans une bibliothèque C 'de base' qui est automatiquement liée à l'application, et, si besoin est, on ajoute (à la main : par exemple -lm) la bibliothèque mathématique.


Message édité par Emmanuel Delahaye le 01-01-2007 à 14:40:53

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 01-01-2007 à 16:12:40    

nicodu95 a écrit :

je comprend pas parce que j'inclue bien math.h , partout sur le web j'ai lu qu'il fallait l'inclure pour ce servir de  floor.


Surtout que "floor" n'est franchement pas utile pour trouver un nombre premier. Arrondir une division en virgule flottante puis regarder si le résultat arrondi est égal au résultat brut pour savoir si la division peut se faire... Autant regarder directement si le reste de la division (qu'on récupère avec l'opérateur modulo %) vaut 0 !!!
 
Par ailleurs, j'ai un sérieux doute sur la réussite globale de ton algo. En ligne 27, il y a une division de x (int) par t[i] (int). La division se fera donc intégralement dans le type le plus "large" présent ici, c.a.d. "int" et le résultat, forcément "int" sera placé dans "q".
C'est comme si t'écrivais "double q=20 / 7" => Tu auras "q" = 2.0000" alors que t'espères très certainement "q=2,857"...
De toute façon, un nombre premier étant un nombre indivisible, il n'y a aucune division à faire en virgule flottante donc les types "double" sont totalement inutiles.
 
Enfin ton algo pourrait être sèrieusement optimisé. En effet, en ligne 22 tu fais une boucle de 0 à l pour diviser ton nombre testé par tous les nombres premiers déjà calculés ce qui est totalement inutile. En effet, si tu trouves un nombre "m" tel que "x / m = n" avec "m > n" cela signifie que tu auras forcément trouvé "n" bien avant "m" puisque t'auras en équivalence "x / n = m"...
Donc tu peux sans soucis arrêter ta boucle dès que "fq" devient plus petit que "t[i]"... Il existe même un algo (crible d'Erastothène) où on n'a aucune division à faire et il serait parfaitement adapté à ton cas puisque cet algo barre dans une liste de nombre (ton tableau "t" ) tous les nombres non-premiers par simple balayage du tableau...
 
De plus, que représente "t" ? Pour moi cela devrait être l'ensemble des nombres premiers déjà trouvés (enfin cela me parait logique car s'il fallait se baser sur tes commentaires pour comprendre ton algo...). Or, tu places "x" dans "t[...]" dès que t'as trouvé un résultat où la division réussit... donc au final t'auras dans le tableau "t" l'ensemble des nombres non-premiers. Quoique ça marche aussi puisqu'en affichant tous les nombres qui ne sont pas dans "t" tu n'auras que des nombres premiers...
 
Pas mal de choses à revoir...


Message édité par Sve@r le 01-01-2007 à 17:40:52

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 01-01-2007 à 19:47:11    

oui je sais le code qui est la ne marche pas par contre celui la marche :

Code :
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main(void)
  4. {
  5. FILE *TXT;
  6. int i,l,z,a;
  7. double q,x;
  8. printf("calculer les nombres premiers jusq'a : \n" );
  9. scanf("%d",&l);
  10. double t[l];
  11. x=2;
  12. t[0]=x;
  13. z=0;
  14. a=z;
  15. TXT = fopen("nbprm.csv","w" );
  16. tef:do
  17.   {
  18.     x++;
  19.    //printf("x=%f - début\n",x);
  20.    for(i=0;i<z;i++)
  21.     {
  22.      //printf("t[i]=%f\n",t[i]);
  23.      q = x / t[i];
  24.      //printf("q=%f\n",q);
  25.      //printf("floor(q)=%f\n",floor(q));
  26.      if(floor(q) == q)
  27.       {
  28.        //printf("x n'est pas premier\n" );
  29.        if(x<l)
  30.         { /*printf("on repart au début - fin\n" );*/ goto tef; }
  31.        goto fincalc;
  32.       }
  33.     }
  34.    printf(" %d ",(int)x);
  35.    fprintf(TXT,"%d,",(int)x);
  36.    if(a==15)
  37.     { printf(" \n" ); fprintf(TXT,";\n" ); a=0;}
  38.    t[i+1] = x;
  39.    //printf("t[i+1]=%f - fin\n",t[i+1]);
  40.    z++;
  41.    a++;
  42.   }
  43. while(x<l);
  44. fincalc: printf("\nfin\n" );
  45. fclose(TXT);
  46. return 0;
  47. }


je sais déja faire du php et du java mais ça fais 2 jours que j'essaye le C à travers cette algo  ;)
par contre tes idées d'opti m'intéressent et c'est justement une "adaptation" du crible d'érasthotène :)

Message cité 1 fois
Message édité par nicodu95 le 01-01-2007 à 19:50:38
Reply

Marsh Posté le 01-01-2007 à 19:57:32    

Houlala, quel style/algo abominable

Reply

Marsh Posté le 01-01-2007 à 21:28:49    

ouh purée, oscours [:psywalk]

Reply

Marsh Posté le 01-01-2007 à 21:28:49   

Reply

Marsh Posté le 01-01-2007 à 22:18:54    

nicodu95 a écrit :

oui je sais le code qui est la ne marche pas par contre celui la marche :

Code :
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main(void)
  4. {
  5. FILE *TXT;
  6. int i,l,z,a;
  7. double q,x;
  8. printf("calculer les nombres premiers jusq'a : \n" );
  9. scanf("%d",&l);
  10. double t[l];
  11. x=2;
  12. t[0]=x;
  13. z=0;
  14. a=z;
  15. TXT = fopen("nbprm.csv","w" );
  16. tef:do
  17.   {
  18.     x++;
  19.    //printf("x=%f - début\n",x);
  20.    for(i=0;i<z;i++)
  21.     {
  22.      //printf("t[i]=%f\n",t[i]);
  23.      q = x / t[i];
  24.      //printf("q=%f\n",q);
  25.      //printf("floor(q)=%f\n",floor(q));
  26.      if(floor(q) == q)
  27.       {
  28.        //printf("x n'est pas premier\n" );
  29.        if(x<l)
  30.         { /*printf("on repart au début - fin\n" );*/ goto tef; }
  31.        goto fincalc;
  32.       }
  33.     }
  34.    printf(" %d ",(int)x);
  35.    fprintf(TXT,"%d,",(int)x);
  36.    if(a==15)
  37.     { printf(" \n" ); fprintf(TXT,";\n" ); a=0;}
  38.    t[i+1] = x;
  39.    //printf("t[i+1]=%f - fin\n",t[i+1]);
  40.    z++;
  41.    a++;
  42.   }
  43. while(x<l);
  44. fincalc: printf("\nfin\n" );
  45. fclose(TXT);
  46. return 0;
  47. }



Heureusement que Taz ne passe plus sur le topic C
Rarement vu un code aussi "pur"... et ces "goto" qui sont... superbes !!!
 
Par ailleurs ca m'étonnerait beaucoup que l'instruction "x++" fonctionne avec "x" de type double. D'ailleurs c'est réellemement une super idée que d'avoir tout mis en double juste pour un simple problème de division. Et enfin c'est encore plus super de travailler en double alors qu'un nombre premier se calcule à partir d'une division entière réussie ou pas => autrement dit les double sont totalement inutiles.  
 

nicodu95 a écrit :

par contre tes idées d'opti m'intéressent et c'est justement une "adaptation" du crible d'érasthotène :)


Une "adaptation personnalisée" alors... car le crible d'Erasthotène ne fait aucune division alors que toi t'arrêtes pas d'en faire !!!
 
Crible d'Erasthotène: Tu commences par initialiser tout ton tableau "t" à 0 signifiant "inconnu". Puis tu mets t[0] et t[1] à "-1" signifiant "pas premiers".
Puis tu pars de "2" et tu recherches la première valeur de ton tableau à "0" (donc ici c'est t[2]) que tu mets à "1" car premier. Puis tu prends tous les multiples de "2" (t[4], t[6], t[8] etc)... jusqu'à la fin et tu les flagues à "-1" (pas premiers).
Puis tu continues à chercher la valeur suivante de ton tableau à "0" (t'arrives donc à t[3]) que tu mets à "1" car premier et tous ses multiples (t[6], t[9] etc) à "-1" car non premiers. Puis tu cherches la valeur suivante à "0" qui est t[5] (car t[4] a été flagué à "-1" lors du traitement de t[2]) et tous les multiples (t[10], t[15], etc...) à "-1" puis la valeur suivante (t[7]) et etc...
 
Dès que t'es arrivé à "l", toutes les valeurs de ton tableau à "1" sont premières !!!


Message édité par Sve@r le 01-01-2007 à 22:20:53

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 01-01-2007 à 23:28:09    

merci pour tes conseils   ;)  ça fais deux jours que je "fais" du C :sweat:  
je vais regarder ça demain  :jap:  
merci  :)  
 
PS : c'est vrai qu'en faisons que des multiplication ça vas être plus rapide :cry:  
 
 :hello:

Reply

Marsh Posté le 02-01-2007 à 13:56:26    

nicodu95 a écrit :

ça fais deux jours que je "fais" du C :sweat:


BIENVENUE DANS LE MONDE MAGIQUE !!!
 

nicodu95 a écrit :

c'est vrai qu'en faisons que des multiplication ça vas être plus rapide :cry:


Disons qu'en conservant les valeurs déjà calculées, c'est effectivement plus rapide.
Pour savoir si un nombre est premier, pas de secret. Tu le divises jusqu'à ce que le résultat soit plus petit que le diviseur. Si t'as trouvé aucune division exacte, alors il est premier.
En revanche, pour calculer tous les nombres premiers d'une liste, ben tu pars du premier de la liste et tu barres tous ses multiples puis tu va sur le second etc. Ce sera hyper plus rapide que de diviser chaque nombre par l'ensemble de ses diviseurs...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 02-01-2007 à 19:49:34    

:hello:

 

voila , et ça marche :

Code :
  1. #include <stdio.h>
  2. int main(void)
  3. {
  4.   int i,l,j;
  5.   printf("calculer les nombres premiers jusq'a : \n" );
  6.   scanf("%d",&l);
  7.   int t[l]; //on crée un tableau d'entier de la taille voule par l'utilisateur
  8.   // état 0 --> état inconnu
  9.   // état 1 --> nombre premier
  10.   // état -1 --> nombre non-premier
  11.   for(i=0;i<l;i++) t[i]=0; //on ne connais pas l'état des nombres dans le tableau
  12.   t[0]=-1; // 0 n'est pas premier
  13.   t[1]=-1; // de même pour 1 :D
  14.   for(i=2;i<l;i++) //on parcour donc le tableau ...
  15.    {
  16.     if(t[i]==0) //... à la recherche des nombres dont l'état est inconnu
  17.      {
  18.       t[i]=1; //le nombre courant est premier
  19.       for(j=i;j<l/i;j++) t[i*j]=-1; //donc on passe tout ses multiples à -1
  20.      }
  21.    }
  22.   for(i=0;i<l;i++) //on parcour de nouveau le tableau ...
  23.    {
  24.     if(t[i]==1) printf("%d\n",i);//... à la recherche des nombres premiers que l'on affiche
  25.    }
  26. }


Par contre , si je demande les nombres premiers jusqu'à 1000, il m'affiche 999 et pour 100, 99  :heink:
je pense que c'est à la ligne 20 :

Code :
  1. j<l/i

mais je sais pas par quoi le remplacer , si c'est ça  :(

 

edit : et c'est effectivement beaucoup plus rapide que le premier, merci Sve@r :jap: :D
edit2 : :( je peux rien calculer à partir de 2095000 (au miller près) ,au dessus , j'ai le droit à ça :

Citation :

Program received signal SIGSEGV, Segmentation fault.
0x08048488 in main ()

dans GDB, sans GDB j'ai : "erreur de segmentation" et bien sur le programme ne s'exécute pas :(

Message cité 2 fois
Message édité par nicodu95 le 02-01-2007 à 20:13:19
Reply

Marsh Posté le 02-01-2007 à 19:59:54    

nicodu95 a écrit :

:hello:  
 
voila , et ça marche :

Code :
  1. #include <stdio.h>
  2. int main(void)
  3. {
  4.   int i,l,j;
  5.   printf("calculer les nombres premiers jusq'a : \n" );
  6.   scanf("%d",&l);
  7.   int t[l]; //on crée un tableau d'entier de la taille voule par l'utilisateur
  8.   // état 0 --> état inconnu
  9.   // état 1 --> nombre premier
  10.   // état -1 --> nombre non-premier
  11.   for(i=0;i<l;i++) t[i]=0; //on ne connais pas l'état des nombres dans le tableau
  12.   t[0]=-1; // 0 n'est pas premier
  13.   t[1]=-1; // de même pour 1 :D
  14.   for(i=2;i<l;i++) //on parcour donc le tableau ...
  15.    {
  16.     if(t[i]==0) //... à la recherche des nombres dont l'état est inconnu
  17.      {
  18.       t[i]=1; //le nombre courant est premier
  19.       for(j=i;j<l/i;j++) t[i*j]=-1; //donc on passe tout ses multiples à -1
  20.      }
  21.    }
  22.   for(i=0;i<l;i++) //on parcour de nouveau le tableau ...
  23.    {
  24.     if(t[i]==1) printf("%d\n",i);//... à la recherche des nombres premiers que l'on affiche
  25.    }
  26. }


Par contre , si je demande les nombres premiers jusqu'à 1000, il m'affiche 999 et pour 100, 99  :heink:  
je pense que c'est à la ligne 20 :

Code :
  1. j<l/i

mais je sais pas par quoi le remplacer , si c'est ça  :(


 
et si je demande les nombres premiers jusqu'à 12 884 901 888, il se passe quoi ?


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 03-01-2007 à 07:11:10    

nicodu95 a écrit :

Code :
  1. for(i=0;i<l;i++) t[i]=0; //on ne connais pas l'état des nombres dans le tableau
  2.   t[0]=-1; // 0 n'est pas premier
  3.   t[1]=-1; // de même pour 1 :D


 
Fais donc démarrer ta boucle d'initialisation à "2" puisque tu t'occupes ensuite de "0" et "1"...
 

nicodu95 a écrit :

Par contre , si je demande les nombres premiers jusqu'à 1000, il m'affiche 999 et pour 100, 99  :heink:  
je pense que c'est à la ligne 20 :

Code :
  1. for(j=i;j<l/i;j++) t[i*j]=-1;

mais je sais pas par quoi le remplacer , si c'est ça  :(


Ben oui - Pour "l=100" et "i=3", tu fais "for (j=3; j < 33 (division entière de 100 / 3); j++)" donc il ne passera pas par l'étape "j=33" puisqu'il s'arrête à 32 donc tu ne taperas pas dans "t[99]"
 
Tu peux remplacer par "j<= l/i"... mais faudra faire gaffe au cas où "i*j == l" car là, tu dépasseras ton espace alloué quand tu taperas dans "t[i * j]" (le tableau va de t[0] jusqu'à t[l - 1]).
 
De plus, tu auras à chaque tour de boucle
- une division "l/i
- une multiplication "i * j"
 
tu peux éviter TOUS CES PROBLEMES d'un seul coup par:

Code :
  1. for (j=i * i; j < l; j+=i) t[j]=-1;


Remarque: tu m'as fait réaliser que, effectivement, on pouvait faire partir le multiple à "i * i" alors que, au départ, j'ai cru que l'algo était faux car moi je l'aurais fait partir à "i * 2" (c'est d'ailleurs ce que j'ai dit dans mon post précédent). Mais quand on y réfléchit 2 mn, on comprend facilement que tous les multiples entre "i" et "i * i" sont déjà flagués par les multiples des premiers inférieurs à "i"
 :jap:  
 

nicodu95 a écrit :

edit2 : :( je peux rien calculer à partir de 2095000 (au miller près) ,au dessus , j'ai le droit à ça :[quote]Program received signal SIGSEGV, Segmentation fault.


Ben t'es limité déjà par la valeur maximale du "int" signé (tu peux remplacer par "unsigned long" ou même "unsigned long long" si ton compilo accepte)... mais surtout faut bien penser que ton tableau "t[l]" est alloué dans la pile. Tu crois que la pile est si énorme que ça ???
Tu peux essayer de mettre ton tableau "t" en "static" ce qui le place dans une zone plus grande que la pile mais le mieux est de le remplacer par un pointeur pointant vers une zone mémoire allouée par malloc => tu remplaces "int t[l]" par "int *t" puis tu écrits en dessous "t=malloc(l * sizeof(int))". Il est bien à ce moment là de vérifier que "t" ne vaut pas NULL car sinon ça veut dire que le malloc a échoué donc c'est pas la peine de continuer. Et à la fin du code tu écris "free(t)".
 
 
 

Harkonnen a écrit :

et si je demande les nombres premiers jusqu'à 12 884 901 888, il se passe quoi ?


Rhaaa soit indulgent  :hello: ... ça fait 2 jours qu'il fait du C - Il a réussi son algo et c'est tout ce qui compte... :sol:

Message cité 1 fois
Message édité par Sve@r le 03-01-2007 à 10:08:31

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 03-01-2007 à 10:51:45    

Sve@r a écrit :


 
Rhaaa soit indulgent  :hello: ... ça fait 2 jours qu'il fait du C - Il a réussi son algo et c'est tout ce qui compte... :sol:


ben chuis indulgent, mais bon, c'est bien beau d'utiliser scanf() pour une entrée (ce qui est une erreur, fgets() rulaize), mais faudrait voir aussi à valider cette entrée [:el g]

Reply

Marsh Posté le 03-01-2007 à 11:42:06    

Harkonnen a écrit :

ben chuis indulgent, mais bon, c'est bien beau d'utiliser scanf() pour une entrée ce qui est une erreur


 
Là faut accuser tous les bouquins de C. Tous parlent de "scanf" comme le moyen de faire saisir qqchose [:spamafaute] (zut je galère et j'arrive pas à trouver ce smiley !!!)

Harkonnen a écrit :

mais faudrait voir aussi à valider cette entrée


Citation :

- je ne peux rien lui apprendre, il est trop impatient
- il apprendra la patience - Etais-je différent quand tu as commencé à m'enseigner ???


Star Wars V - L'empire contre-attaque


Message édité par Sve@r le 03-01-2007 à 12:12:16

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 03-01-2007 à 12:04:50    

Citation :


et si je demande les nombres premiers jusqu'à 12 884 901 888, il se passe quoi ?


il se passe rien  :pt1cable:  , de même pour 2^32  :pt1cable:

 

sinon j'ai remplacer j<l/i par i*j<l que j'ai trouvé pendant la nuit  :lol:
sinon ça marche impec maintenant avec tes modifs sve@r  :jap:  merci  :jap:

Citation :

Là faut accuser tous les bouquins de C. Tous parlent de "scanf" comme le moyen de faire saisir qqchose


ouais et pas que les bouquins , même sur les tutos sur le web on vois ça .
ah aussi à la compil' il me mais un warning pour malloc :

Citation :

nbprm2.c:10: warning: incompatible implicit declaration of built-in function %u2018malloc%u2019


et apropos de scanf c'est quoi le danger ??
merci à tous pour votre aide   :jap:  :jap:

Message cité 3 fois
Message édité par nicodu95 le 03-01-2007 à 12:05:49
Reply

Marsh Posté le 03-01-2007 à 12:19:01    

nicodu95 a écrit :

ah aussi à la compil' il me mais un warning pour malloc


Si tu te documentes pas un peu sur les fonctions que t'utilises (man malloc) t'auras le même problème pour toute fonction qui n'est pas de type "int" pour lequel tu n'as pas mis son "#include" qui va bien...
Quand le compilo arrive sur une fonction inconnue (malloc, fopen, etc) il la met de type "int" par défaut. Puis il y a l'édition de liens avec la lib C (là où malloc est codé) et comme malloc n'est pas "int" => warning: incompatible implicit declaration of built-in function
Solution 1: prototyper toutes les fonctions que t'utilises comme il faut
Solution 2: inclure le header donné au début du man dans lequel la fonction en question a été prototypée par son créateur (je crois que pour malloc c'est <stdlib.h> )
 

nicodu95 a écrit :

et apropos de scanf c'est quoi le danger ??


Exécute le truc suivant

#include <stdio.h>
int main()
{
    int age;
    char nom[20];
 
    printf("Quel est votre age ?\n" );
    scanf("%d", &age);
 
    printf("Quel est votre nom ?\n" );
    scanf("%s", nom);
 
    printf("Vous vous appelez[%s] et vous avez %d ans\n", nom, age);
    return 0;
}


 
Ca m'étonnerait que le programme attende que tu aies saisi ton nom pour t'afficher le dernier "printf". Cependant rajoute un simple "getchar()" juste après la saisie de l'âge et ça fonctionnera.
Pour plus de détails, voir http://forum.hardware.fr/hfr/Progr [...] 9666_1.htm => Lis le topic en entier et attarde-toi sur le post de Emmanuel Delahaye du 28/12 à 00h45 et sur mon post du 28/12 à 11h10...
 

nicodu95 a écrit :

ouais et pas que les bouquins , même sur les tutos sur le web on vois ça .


<philosophie>C'est le problème de tout apprentissage: L'esprit humain ne peut pas progresser autrement qu'en détruisant en partie ce qui a été fait avant. Cela n'est pas seulement vrai pour l'Humanité dans son histoire, c'est aussi vrai pour tout individu. Comment comprendre que c'est la Terre qui tourne autour du Soleil si on n'a pas d'abord vu le Soleil en mouvement autour de la Terre ? Même si l'idée première qu'on se fait de cette vision est fausse, elle servira ensuite à comprendre plus facilement la réalité.
C'est en étudiant les théories (fausses) d'Aristote sur les 5 éléments et leur position immuable (la pierre composée uniquement de terre tend à rejoindre la terre et coule tandis que le bois composé en partie d'air tend en partie à rejoindre l'air et peut donc flotter) qu'Archimède a pu découvrir le principe de la flottabilité...</philosophie>
 
C'est pareil pour l'apprentissage du C. Il est nécessaire pour les premiers TP d'avoir une fonction de saisie et une fonction d'affichage, et la saisie doit prendre en compte le type de la variable saisie d'où la première fonction qu'on apprend qui est "scanf()". Puis, plus tard, une fois qu'on commence à être habitué au C et à ses impératifs, on revient sur "scanf()" et on explique qu'en fait, ce n'est pas du tout conseillé. Mais à ce niveau là, le débutant connait maintenant "fgets()" et "sscanf()" et sait s'en servir et peut comprendre en quoi "scanf()" n'est pas vraiment tiptop...

Message cité 1 fois
Message édité par Sve@r le 03-01-2007 à 15:11:50

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 03-01-2007 à 15:16:35    

nicodu95 a écrit :


il se passe rien  :pt1cable:  , de même pour 2^32  :pt1cable:


sans blague ? [:petrus75]
allez, maintenant tu as 15 mn pour expliquer pourquoi, je releve la copie à 15:30


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 03-01-2007 à 15:18:22    

nicodu95 a écrit :


et apropos de scanf c'est quoi le danger ??


aucun controle de dépassement du buffer


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 03-01-2007 à 16:00:17    

Harkonnen a écrit :

aucun controle de dépassement du buffer


si mal utilisé, ce qui est le cas dans 99% de cas...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 03-01-2007 à 21:25:25    

Sve@r a écrit :


<philosophie>[...]</philosophie>
 
C'est pareil pour l'apprentissage du C. Il est nécessaire pour les premiers TP d'avoir une fonction de saisie et une fonction d'affichage, et la saisie doit prendre en compte le type de la variable saisie d'où la première fonction qu'on apprend qui est "scanf()". Puis, plus tard, une fois qu'on commence à être habitué au C et à ses impératifs, on revient sur "scanf()" et on explique qu'en fait, ce n'est pas du tout conseillé. Mais à ce niveau là, le débutant connait maintenant "fgets()" et "sscanf()" et sait s'en servir et peut comprendre en quoi "scanf()" n'est pas vraiment tiptop...


 
Je crois bien qu'aucune philosophication d'aucune sorte n'éclipsera le fait qu'une bonne partie de la bibliothèque C est mal foutue, voire inutilisable.

Reply

Marsh Posté le 03-01-2007 à 21:42:07    

++fab a écrit :

Je crois bien qu'aucune philosophication d'aucune sorte n'éclipsera le fait qu'une bonne partie de la bibliothèque C est mal foutue, voire inutilisable.


Ah ??? Certains vont être très intéressés par un développement plus argumenté de cette affirmation...
 
"Mal foutue" c'est encore possible car la lib a été créée aux alentours de 1970 par tatonnements successifs... mais inutilisable ???


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 03-01-2007 à 22:09:44    

Sve@r a écrit :

Ah ??? Certains vont être très intéressés par un développement plus argumenté de cette affirmation...


Ah. Et bien laisse les autres parler -- et mon affirmation commence par "Je crois".
 

Sve@r a écrit :

"Mal foutue" c'est encore possible car la lib a été créée aux alentours de 1970 par tatonnements successifs... mais inutilisable ???


Appelle un chat un chat. S'il ne faut pas utiliser une fonction (comme tu le dis de scanf), c'est qu'elle est mal foutue.
Inutilisable, c'est ce qui est décrété à propos de certaines fonctions de la bibliothèque C, sur certains projets pour lesquels je travaille.
 

Reply

Marsh Posté le 04-01-2007 à 01:22:32    

++fab a écrit :

Je crois bien qu'aucune philosophication d'aucune sorte n'éclipsera le fait qu'une bonne partie de la bibliothèque C est mal foutue, voire inutilisable.


Faut pas exagérer. Il y a  

  • une fonction interdite : gets()
  • des fonctions non-réenrantes : strtok(), toutes celles qui ont une variable statique...
  • une famille de fonction difficile à maitriser : *scanf()
  • une fonction bizarre : strncpy()


ce serait intéressant de compléter cette liste, mais je ne pense pas qu'on atteigne 'une bonne partie' de la bibliothèque standard...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 04-01-2007 à 07:34:22    

Tu peux rajouter strncat -- voir l'avis de Charlie Gordon à ce sujet ;)
 
Et puis strcpy et strcat, qui ne convenait apparemment pas puisqu'on s'est senti obligé de créer leur version "sécurisé". Je ne juge pas ceux qui l'on fait -- j'aurais sans doute pas fait mieux -- mais ça me fait quand même sourire.
 
on atteind pas "une bonne partie", mais on tape quand même dans les plus connues :/

Reply

Marsh Posté le 04-01-2007 à 10:17:35    

Emmanuel Delahaye a écrit :

  • une fonction bizarre : strncpy()

Ah ??? En quoi est-elle bizarre ça m'intéresse ??? La seule particularité que je lui connaisse qui la différencie des autres fonctions d'écriture de chaîne c'est qu'il lui arrive de ne pas mettre le '\0' (si le nombe "n" est atteint avant la fin de la copie). C'est ça ???
 

++fab a écrit :

Et puis strcpy et strcat, qui ne convenait apparemment pas puisqu'on s'est senti obligé de créer leur version "sécurisé".


Personnellement je ne suis pas d'accord. Ces fonctions ont créé des trous de sécurité parce que ceux qui les utilisaient les utilisaient mal sans vérifier que la variable réceptrice était sufisemment grande pour recevoir la copie ou, pire, en y mettant des choses provenant de l'extèrieur comme "argv[x]"
C'est donc parce que les programmeurs ont mal fait leur boulot qu'on a dû créer des fonctions le faisant à leur place, ok. Mais ce n'est pas la faute à strcpy() si on l'utilise mal...
Lorsque le C a été créé, son principe était "il accepte tout sans contrôle pour que ce soit très rapide donc à chacun de faire ses propres vérif". On ne peut donc pas en vouloir à ceux qui ont écrit "strcpy()" de n'avoir rien contrôlé...
 
Bon évidemment ce que j'en dis c'est ce que j'en sais...

Message cité 1 fois
Message édité par Sve@r le 04-01-2007 à 10:47:45

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 04-01-2007 à 11:26:37    

bon euh en faite c'est pas trop le sujet , la bibliothèque C , ok ++fab ??
si tu veux tu crée un topic sur ce sujet mais tu viens pas polluer le mien !!! ;)

Reply

Marsh Posté le 04-01-2007 à 11:44:26    

++fab a écrit :

Tu peux rajouter strncat -- voir l'avis de Charlie Gordon à ce sujet ;)


Je connais ses positions. Personellement, je n'ai pas de problèmes avec cette fonction. Il sufit de lire la doc. Son comportement est on ne peut plus logique. Ce n'est pas le cas de strncpy() qui est tyrès déroutante et que je préfère ne pas utiliser (strncat() est AMA plus adaptée)

Citation :


Et puis strcpy et strcat, qui ne convenait apparemment pas puisqu'on s'est senti obligé de créer leur version "sécurisé". Je ne juge pas ceux qui l'on fait -- j'aurais sans doute pas fait mieux -- mais ça me fait quand même sourire.


Je ne suis pas certain que les fonction strn*() aient été conçues comme des version 'sécurisées'. Il s'agit plutôt d'un mécanisme d'extraction de sous-chaine un peu maladroit...

Citation :

on atteind pas "une bonne partie", mais on tape quand même dans les plus connues :/


OK. Et alors ? C'est grave ? Si le C ne te plait pas, personne ne t'oblige à en faire. Si les fonctions ne te plaisent pas, écrit les tiennes (je ne me suis pas gêné)
 
http://mapage.noos.fr/emdel/clib.htm
Module STR
 
 
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 04-01-2007 à 11:49:09    

Sve@r a écrit :

Ah ??? En quoi est-elle bizarre ça m'intéresse ??? La seule particularité que je lui connaisse qui la différencie des autres fonctions d'écriture de chaîne c'est qu'il lui arrive de ne pas mettre le '\0' (si le nombe "n" est atteint avant la fin de la copie). C'est ça ???


Oui, et c'est assez troublant comme mécanisme. En fait il suffit de passer size_dest-1 et ça marche, car la chaine de destination est complétée de zéros.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 04-01-2007 à 11:50:17    

nicodu95 a écrit :

bon euh en faite c'est pas trop le sujet , la bibliothèque C , ok ++fab ??
si tu veux tu crée un topic sur ce sujet mais tu viens pas polluer le mien !!! ;)


Oui, c'est vrai, ça... Désolé d'avoir contribué à la pollution... Si un modo a le courage de déplacer les posts...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 04-01-2007 à 11:51:55    

on peut pas déplacer les posts, juste les topics :D

Reply

Marsh Posté le 04-01-2007 à 12:49:40    

nicodu95 a écrit :

bon euh en faite c'est pas trop le sujet , la bibliothèque C , ok ++fab ??
si tu veux tu crée un topic sur ce sujet mais tu viens pas polluer le mien !!! ;)


T'avais pas une copie à rendre avant 15h45 toi ??? [:ddr555]


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 04-01-2007 à 17:01:14    

sisi mais j'attend la correction  :whistle:  Harko ???  :ange:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed