[C] Besoin d'aide (débutant)

Besoin d'aide (débutant) [C] - Programmation

Marsh Posté le 11-04-2001 à 22:26:06    

Salut,
je viens de commencer la prog en C et j'aimerais faire un programme pour calculer les factorielles. Ca serait sympa de me proposer des solutions (avec des instructions simples que je serait susceptible de connaître (j'ai un faible niveau)).
Merci d'avance.


---------------
FHR
Reply

Marsh Posté le 11-04-2001 à 22:26:06   

Reply

Marsh Posté le 11-04-2001 à 22:41:27    

Le mieux est d'essayer de faire un truc et si tu comprends pas pourquoi ça marche pas, tu postes l'erreur trouvée.

Reply

Marsh Posté le 12-04-2001 à 01:57:39    

Déja trouve un bon algorithme ... ensuite commence ton prgms, tu vas ça vient tout seul :D

Reply

Marsh Posté le 12-04-2001 à 05:42:12    

void factoriel(int nombre)
{
  long result = 1;
  while(nombre > 0)
  {
     result = result * nombre;
     nombre--;
  }
}

Reply

Marsh Posté le 12-04-2001 à 08:30:18    

long factoriel(int nombre)  
{  
  long result = 1;  
  while(nombre > 0)  
  {  
     result = result * nombre;  
     nombre--;  
  }  
return (result);
}  
Ca serait pas plutot ca??

Reply

Marsh Posté le 12-04-2001 à 08:42:31    

Vi, ce serait plutôt ça :)
 
Par contre, le gars dit qu'il est débutant, l'a peut être pas encore vu les fonctions, n'allez pas lui filer la trouille avec vos void bidule (void) :p
 
je sais bien, y a un début à tout mais bon ... Dans ce cas, z'auriez pu employer des pointeurs ? D'ailleurs, si une âme charitable peut donner un exemple avec un *, je serais interressé


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 12-04-2001 à 09:10:49    

unsigned long factoriel(long n)
{
 if (n==1) return 1;
 
 return n*factoriel(n-1);
}

 

[edit]--Message édité par XDMJ--[/edit]

Reply

Marsh Posté le 12-04-2001 à 09:14:01    

en récursif c'est plus simple(si tu connais le principe sinon oublie)
 
long factoriel(int var1)  
{
int var2;
 
if var1 = 1
   return (1)
else
   var2 = var1--
   return (var1*factoriel(var2))
end if
}


---------------
cris
Reply

Marsh Posté le 12-04-2001 à 09:29:00    

Arglllll !!!! si tôt le matin comme ça, z'êtes inhumains les gars !!!
 
Arggghhhhhh, je veux mourir !!!!!!!
 
:p :p :p


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 12-04-2001 à 13:46:06    

je comprend pas tout mais je vous remercie tous d'avoir répondu.
je pense que je vais attendre d'avoir avancé pour réessayer (je voulais faire ce prog parce que mon frère me l'avait montré)
 
merci encore


---------------
FHR
Reply

Marsh Posté le 12-04-2001 à 13:46:06   

Reply

Marsh Posté le 12-04-2001 à 13:58:26    

T'en va pas, fhr, attend !
Je reprend l'exemple de TricTrac pour le simplifier un peu, voilà ton programme au + simple :
 
#include<stdio.h>
 
main()
{
 /* déclarations */
 long result = 0 ; /* variable int de type long */
 int nombre = 0 ;
 
 /* traitement */
 printf ("donnez la valeur de nombre :" );
 scanf ("%d", &nombre);
 while (nombre > 0)
 {
  result = result * nombre; /* ou encore result *= nombre */
  nombre = nombre - 1;   /* ou encore - -nombre */
 }
 
 /* fin */
 printf ("Resultat : %ld", result);
}


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 12-04-2001 à 14:05:24    

ARGLLLLL !!!! scuzy, scuzy, j'ai fait une grosseu bourde !
 
Dans mon bloc d'initialisation, remplace :
 
long result = 0;  par
long result = 1;
 
Sinon result *= nombre donnera toujours 0 ...
 
pffff, désolé, mea culpa, m'assassinez pas les gars
 
pour une fois, j'étais content de sortir ma science, moi qui apprend le C aussi ...
 
j'sais po, c'est le "long" qui m'a surpris ... J'suis un petit joueur, moi, c'est pour ça que j'ai pas besoin de plus qu'un "int" pour mes nombres !!!
 
:) :) :)


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 12-04-2001 à 15:13:06    

bon ben j'rajoute le miens !!!
 :pt1cable:  
 
double fact(double nb)
{
double valeur=1;
for(int i = 1 ; i <= nb ; i++)
  valeur *= i;
 
return valeur;
}

Reply

Marsh Posté le 12-04-2001 à 15:14:18    

La Viper ...
 
JE TE HAIS !!!!!! :p :p :p :p :p :p


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 12-04-2001 à 16:41:28    

Aricoh regarde ma fonction un peu plus haut ... d'après moi elle est super simple à comprendre. :)

Reply

Marsh Posté le 12-04-2001 à 16:45:18    

bon c super de mettre des super algo aussi durs que ça....
la viper, pour info ton prog peut planter....
mets la valuer 0 a ton nombre, et tu obtient une jolie boucle infinie; c assez sympa...
sinon les commentaires aricoh c utiles que qd il faut expliquer qq chose de difficiles (style des maths) parce que la paraphrase au final ça alourdi et ça diminu la visibilité (tu verras plus tard)

Reply

Marsh Posté le 12-04-2001 à 16:46:39    

hou bordel j'ai pas d'oeil j'ai rien dis la viper

Reply

Marsh Posté le 12-04-2001 à 17:37:15    

Petoulachi, heu le gars qui a créé ce topic a dit en ouverture qu'il débutait dans le C
 
Tout le monde a commencé à sortir son code via des fonctions et autres
 
Le gars, il est probable qu'il n'ait pas encore vu les fonctions justement.
 
T'imagines s'il en est juste à apprendre printf ou getchar() ?
 
Ben s'il débute, pas la peine de lui pondre des structures non plus quoi !


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 12-04-2001 à 22:07:30    

Merci les gars (surtout Aricoh, ta version est celle que je comprend le mieux).
En effet, j'en suis pas très loin en C (print, scanf getchar(), boucles while, for, do while, et pis les switchs et les if)
Qu'est ce que vous me recommandez comme bouquin (là j'ai le Micro-Application PC Poche : Language C) mais si il y a mieux, dites-le moi (il parait que le Kernigan & Ritchie est bien).
Merci encore.
 
ps : Aricoh tu parles de structures : je viens de commencer le chapitre "types de données complexes : tableaux et structures"


---------------
FHR
Reply

Marsh Posté le 13-04-2001 à 01:08:51    

Pour les débutants, il y a  
"Le livre du C premier language" de Claude Delanoy chez Eyrolles.
ISBN:2-212-08838-8

Reply

Marsh Posté le 13-04-2001 à 07:50:31    

Céline (oups, pardon) Dion a raison, le livre de Delannoy est une bénédiction quand on débute
 
Idéal pour aborder le C avant d'attaquer les choses sérieuses avec le livre de Kernighan & Richie, le C Norme ANSI
 
:)
 
Vala les gars, je l'avais dit, c t po la peine de sortir votre science ou votre formule "qu'y a que vous qui captez" :p :p :p


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 13-04-2001 à 11:33:56    

et non ma fonction est bien buggé ... voilà ce qui arrive quand on s'amuse à coder sans reflechir !!
 
par contre personne à vu le truc !!! ct pas une boucle infinie ..
mais un probleme de typage ..
 
dans la boucle for(.;..;..) i doit etre un double (4octets) et non un int (2octets) pour que ce soit compatible avec le return entre autre..
 
voilà, au final ca donne ca ...
 
double fact(double nb)  
{  
double valeur=1;  
for(double i = 1 ; i <= nb ; i++)  
  valeur *= i;  
 
return valeur;  
}

Reply

Marsh Posté le 13-04-2001 à 11:58:20    

re,
 
en fait, pour l'explication :
 
unsigned long double fact(unsigned double nb)  
{  
unsigned long double valeur=1;  
for(unsigned double i = 1 ; i <= nb ; i++)  
  valeur *= i;  
 
return valeur;  
}
 
serait la fonction la plus judicieuse.
En effet, tout depend du compilo qu'on utilise. Sous VC++ 6.
 
Type Size  
char, unsigned char, signed char 1 byte  
short, unsigned short 2 bytes  
int, unsigned int 4 bytes  
long, unsigned long 4 bytes  
float 4 bytes  
double 8 bytes  
long double 8 bytes  
 
il ne faut pas oublier que le factoriel est tjrs positif, on peut enlever le signe (-) et gagner des bits grace a "unsigned"
Sur ce compilo long double et double sont sur 8 octets, mais ca peut varier suivant les compilo, donc autant mettre long double plutot que double. Pkoi mettre ces typages ??? bien parceque le nombre qu'on rendre dans la fonction fact peut etre tres grand et donc codé sur plusieurs octets .. (8 maxi). Avec un entier (2 ou 4 octets suivant les compilo) on arrive vite à saturation d'ou au mieux valeur erronée au pire plantage.
 
Pour des raisons evidentes de comparaison, i doit etre du meme type que nb. Si on compare un int avec un double avec des petits chiffres ca ne pose pas de probleme mais si on veut comparer deux grosses valeurs, le int ne pourra pas suivre, d'où plantage.
 
Il faut aussi penser que le resultat que retourne notre fonction sera plus grand que la valeur d'entrer .. et donc surement qu'il aura besoin d'etre codé sur plus de bits que la valeur passé en parametre. d'ou le long attribué à valeur. Sans ca, la valeur renvoyée pourrait etre erronnée. Tout ca dans un soucis faire comprendre les problemes des variables, nous pouvons utiliser le type __int32 disponible sous VC++.
 
comme fact ne peut avoir que des int en entrée et sortie ... et en esperant que la valeur en entrée et bien respectée.
 
unsigned _int64 fact(unsinged _int32 nb)
{
 unsigned _int64 valeur = 1;
 for(unsigned _int32 i = 1 ; i <= nb ; i++)
    valeur *= i;
 
return valeur;
}
 
mais là, j'ai pas testé !.

Reply

Marsh Posté le 13-04-2001 à 11:59:43    

la viper j'avais vu ça, mais le C ne sait pas faire de transtypage ? (desole je suis plus dans le java)
sinon pour debuter , si tu prog sous linux, tu peux aussi te servir des pages de man

Reply

Marsh Posté le 13-04-2001 à 12:11:16    

pour ce qui est du transtypage ... c'est possible oui.
on peut meme forcer une variable d'un type precis a se coder dans un autre type mais que dans un sens ... du plus grand vers plus petit. Je m'explique.
 
double i;
 
(int) i = 10*2; //possible
 
mais
 
int i;
 
(double) i = 10*2; // je suis pas sur que ca fonctionne !
 
tout simplement parceque lors du lancement de l'appli ou de la fonction, le systeme alloue de la memoire à la variable. Et le nombre d'octets alloués à la variable depend de son type de depart.. alors si ta variable est un int (2octets) tu ne peux pas la forcer a passer en double (4octets) sinon tu risques de detruire des données en memoire.. par contre l'inverse est possible...
 
autre chose ...
int i;
i = 4.25/3;
 
> le resultat sera un entier et non un reel, le C sait gerer ce type de possibilité. ca revient donc a i = 4/3. Attention, il y aura une perte d'information!
 
Il faut etre assez rigoureux en C justement parce que les typages ont une part importante dans ce langage. Contrairement à d'autre langage de haut niveau.
Les bugs dû à des problemes de mémoires sont tres frequents !

Reply

Marsh Posté le 13-04-2001 à 12:16:09    

[C] Besoin d'aide (débutant)
 
c'est le titre de ce topic ... hum ...
 
ah ouaip, ça l'fait !!! :) :) :)
 
t'inquiètes fhr, je te contacte par mail ce soir ++


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le 13-04-2001 à 13:49:37    

Aricoh > si tu veux.


---------------
FHR
Reply

Marsh Posté le 13-04-2001 à 20:56:00    

la viper a écrit a écrit :

et non ma fonction est bien buggé ... voilà ce qui arrive quand on s'amuse à coder sans reflechir !!
 
par contre personne à vu le truc !!! ct pas une boucle infinie ..
mais un probleme de typage ..




Si je peux me permettre... on s'en fout. C est très permissif du point de vue typage. Ta fonction fonctionne très bien, le compilateur y aurait inséré tous les cast nécessaires.
 
A mon avis, la fonction suivante très bien :
 
double fact(int nb)
{
    double valeur = 1.0;
    for (int i = 1 ; i <= nb ; i++) {
        valeur *= (double) i;
    }
 
    return valeur;  
}
 
Sachant qu'écrire "1" au lieu de "1.0" marche tout aussi bien (mais c'est moins propre à mes yeux), et caster i en double n'est pas strictement nécessaire (si le programmeur ne le fait pas, le compilateur le fera implicitement pour lui ; mais personnellement, j'ai horreur de tout ce qui est implicite...).
 
Et pour finir, inutile que le paramètre d'entrée soit un double ! Factorielle 70 est déjà supérieur à 10 puissance 100, alors...
 
Par contre, le comportement de la fonction est mauvais si le paramètre d'entrée est négatif...

Reply

Marsh Posté le 14-04-2001 à 14:07:52    

Je viens de trouver une solution simple mais qui marche bien(grâce à Aricoh) :
#include<stdio.h>
 
main()  
{  
 
char response;
 
do
{
long double result = 1 ;
double nombre;
 
 
printf("Donnez la valeur du nombre :" );
scanf("%lf", &nombre);
getchar();
for(nombre; nombre >0; nombre--)
{
result *= nombre;
 
}
 
printf ("Resultat : %Lg\n", result);
printf("Voulez-vous continuer (o/n) ?" );
response = getchar();
 
}while(response=='o');
 
}
 
ça marche bien mais après 170! ça marque un truc du genre : 1.#INF
 
je pense que ça vient du format de printf employé : si vous pouviez m'aider...


---------------
FHR
Reply

Marsh Posté le 14-04-2001 à 22:44:25    

Aricoh: C  un débutant(comme moi), donc je lui conseille un livre pour débutant. Et pour la vanne vaseuse, je croyais que j'allais échapper à ce genre de truc lourd sur prog et bah :(

Reply

Marsh Posté le 16-04-2001 à 13:59:07    

UUUUUUUUUUPPPPPPPPPPPP !!!!!!!!!


---------------
FHR
Reply

Marsh Posté le 16-04-2001 à 15:38:22    

SVP, aidez moi pour que mon prog (cf plus haut) aille au dessus de 170! .Merci d'avance


---------------
FHR
Reply

Marsh Posté le 16-04-2001 à 15:46:55    

C'est normal, les double sont limités à 10^308

Reply

Marsh Posté le 16-04-2001 à 22:17:44    

vi !170 c'est bcp ...
 
la pluspart des calculatrice font pas plus que !70 si je me rappelle bien...

Reply

Marsh Posté le 17-04-2001 à 01:34:46    

Oui, puisque (comme je l'ai dit plus haut), 70! est supérieur à 10^100, or la plupart des calculatrices expriment l'exposant sur 2 chiffres décimaux.
 
En C (comme l'a dit Verdoux), le plus grand nombre en virgule flottant qu'un double peut exprimer est de l'ordre de 10^308. Or !170 est de cet ordre de grandeur-là. Donc c'est normal qu'il te donne ce résultat. "1.#INF" ça veut dire plus l'infini.
 
Si tu veux aller plus loin, il faut que tu changes de type de données, n'utilises pas un double, mais (par exemple) un "long double" (si ton compilateur le permet). Sinon, tu n'as pas d'autres choix que de créer ton propre type flottant, d'implémenter toutes les opérations dessus.
 
Bonne chance ! ;) :pt1cable:

Reply

Marsh Posté le 17-04-2001 à 01:43:18    

Ma HP48 va jusqu'à 253! (elle limite à 10^500) ;)

Reply

Marsh Posté le 17-04-2001 à 01:59:14    

J'ai dit "la plupart" !
Mais évidemment, si tu prends la calcu de compèt....  :sarcastic:  ;)  
 
Sinon, fhr, tu peux peut-être essayer de passer en Java, il y a une classe BigDecimal qui permet d'utiliser des réels sans borne supérieure (mais attention aux temps de calculs... J'ai essayé un jour d'utiliser cette classe pour calculer un Mandelbrot, je ne vous raconte pas...  :crazy: )

Reply

Marsh Posté le 17-04-2001 à 02:07:04    

Par exemple:

Code :
  1. import java.lang.*;
  2. import java.math.*;
  3. public class test {
  4. public static BigInteger fact(BigInteger n) {
  5.  BigInteger r = BigInteger.ONE;
  6.  for(;!(n.equals(BigInteger.ONE));n = n.subtract(BigInteger.ONE)) r = r.multiply(n);
  7.  return r;
  8. }
  9. public static void main(String args[])
  10. {
  11. System.out.println(fact(new BigInteger(args[0])).toString());
  12. }
  13. };
 

[edit]--Message édité par Verdoux--[/edit]

Reply

Marsh Posté le 17-04-2001 à 02:10:18    

11 secondes pour calculer 10000! sur un C450.
 
Et il y a 35661 chiffres ;)

 

[edit]--Message édité par Verdoux--[/edit]

Reply

Marsh Posté le 17-04-2001 à 08:25:32    

Dion a écrit a écrit :

Aricoh: C  un débutant(comme moi), donc je lui conseille un livre pour débutant. Et pour la vanne vaseuse, je croyais que j'allais échapper à ce genre de truc lourd sur prog et bah :(




 
Oups, oui, j'ai un humour de merde je sais
 
le r'frais pu, promis juré craché ... ptttttou !!!! :)
 
Concernant la limite de 170 en factorielle indiquée par FHR, c'est sous Linux et en utilisant un double que ça se produit.
Je vous raconte pas sous Windows (ME), ça affiche plein de zéros dès qu'on demande la factorielle de 40 (même moins) !


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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