probleme dans mon programme [HELP!] - C++ - Programmation
Marsh Posté le 20-12-2005 à 17:35:13
jet-acide a écrit : |
Tout le code entre la ligne 1. et la ligne 60. (pour les autres lignes, ça va).
Achète toi un bon bouquin genre Accelerated C++ de Koenig & Moo ou télécharge Thinking in C++ de Bruce Eckel.
Marsh Posté le 20-12-2005 à 18:05:29
merci alerim de ta réponse rapide et directe... et ironique xD (vaut mieux bien prendre cette 1ere réponse...)
Quelq'un n'aurait pas une réponse moins... "recommence tout T nul!"...?
//Pas la peine de répondre si c juste pour se foutre de moi!
Marsh Posté le 20-12-2005 à 18:08:42
"télécharge Thinking in C++ de Bruce Eckel."
Pour commencer je préfère un bouquin en français
Marsh Posté le 20-12-2005 à 18:09:25
Je me fous pas de toi, mais malheureusement c'est vrai, il n'y a pas une ligne de code qu'il faudrait pas complètement réécrire ! Ton truc ne compile pas, il y a des choses complètement inventées que tu n'as pu lire nul part et on ne programme pas en inventant, mais avec un vrai bon bouquin à côté de soit.
Dire ce qui ne va pas dans ton code ça serait te donner un cours complet tellement il y a de choses à dire. Donc le mieux c'est de te conseiller de lire un vrai bouquin sur le sujet, comme tous les vrais programmeurs l'ont fait un jour (et le font en permanence d'ailleur, un bouquin ça sert pas qu'aux débutants loin de là).
Marsh Posté le 20-12-2005 à 18:12:58
jet-acide a écrit : "télécharge Thinking in C++ de Bruce Eckel." |
Je ne sais pas s'il a été traduit mais si t'es pas capable de lire de l'anglais technique, tu vas pas aller loin en info (et l'anglais technique en info est loin d'être difficile).
Maintenant si tu veux pas faire d'effort, c'est ton problème.
Marsh Posté le 20-12-2005 à 18:18:56
" il n'y a pas une ligne de code qu'il faudrait pas complètement réécrire ! Ton truc ne compile pas"
Je l'ai pourtant compilé et puis quand un nombre est divisible par 2 il marche tres bien...
Bon ok je n'insiste pas, je vais lire un bouquin complet, mais j'ai surtout besoin de bon exemples de programmes simples en C++
"te donner un cours complet" : si tu veux lol
STP dis-moi ce que j'ai "inventé" pour que je le refasse plus!
Marsh Posté le 20-12-2005 à 18:23:13
Si tu cherches des exemples de programmes en C++ tu peux trouver pleins de codes sources sur le net. Encore faut-il trouver des trucs écrits correctement et ça c'est pas gagné... Donc le mieux c'est un bouquin.
Sinon Google : filetype:cc ou filetype:cpp pour trouver des codes sources en C++.
Marsh Posté le 20-12-2005 à 18:26:53
c'est quoi ce titre de topic ?
(et sinon, "le premier langage à apprendre est l'anglais" est une phrase incontournable sur ce forum)
Marsh Posté le 20-12-2005 à 18:30:30
A première vue, alerim a raison, la première erreur est au niveau conceptuel: toute l'algorithmique est à refaire.
Exemple:
Citation : Premature optimisation is the root of all evil |
Avant de te soucier d'optimiser, commence déjà par faire marcher ton truc.
Accessoirement, si t'es en C++ tu es censé inclure <iostream>, pas <iostream.h>
Marsh Posté le 20-12-2005 à 18:46:36
Je me suis inspiré du même programme que j'avais fait en... TI Basic
(Le C++ sur ordi est plus rapide qu'une calculatrice)
Sauf qu'il était nikel en TI Basic, mais dur à transcrire en C++ quand on y connait rien...
flottants : d'accord int est mieux mais c au cas ou qqn rentre 1 nombre à virgule : je veux pas que mon prog dise que 5.2 est premier bar ex...
<iostream.h> : include mis par défaut par mon compileur (devCpp)
Marsh Posté le 21-12-2005 à 09:17:35
jet-acide a écrit : Je me suis inspiré du même programme que j'avais fait en... TI Basic |
traduire du code d'un langage à un autre n'est jamais quelque chose de conseillé. En général, la manière d'écrire peut varier assez fortement suivant ce que le langage te propose. Donc à la limite, si tu veux porter ton programme, reprends depuis le début. Tu sais ce qu'il fait, donc tu peux le refaire.
le problème pour ton nombre flottant, c'est aussi que l'utilisateur pourra rentrer une valeur qui fera entrer ton programme dan,s une boucle infinie au vu de sa construction actuelle (par exemple une valeur flottante représentant un nombre supérieur à 2^32+2)
ton compilateur ne te met pas ce genre de header par défaut. Il se peut, par contre, que ton IDE t'en mette, mais effectivement, <iostream.h> est un header obsolète depuis déjà un bon nombre d'années. On utilise <iostream> depuis longtemps, maintenant
Marsh Posté le 21-12-2005 à 10:25:51
Bon j'ai fait cet algo à l'arrache sans compiler, il est largement optimisable, mais c'est une mailleure base non?
int verif_premier (unsigned int nb)
{
int diviser;
int trouve = 0;
for (diviser = 2; diviser <= sqrt(nb,2), trouve == 0; diviser++)
{
if (nb%diviser == 0) //reste de la division = 0
{
trouve = 1;
}
}
return (trouve == 0)
}
Retourne 1 si il est premier, 0 sinon...
Marsh Posté le 21-12-2005 à 10:33:30
alors, sans prendre en compte la notion d'optimisation :
* si tu retournes une valeur genre 0 ou 1 -qui a clairement vocation d'être un booléen-, alors pourquoi utiliser un int ?
* le ++ devrait être préfixé sans même parler d'optimisation
* tu aimes faire des tours de boucle inutile ? au lieu de faire trouve = 1, retourne false directement
Marsh Posté le 21-12-2005 à 10:35:29
Si on prend pas en compte la notion d'optiomisation, alors tes remarques n'ont pas lieu d'être. Le préfixage de ++ n'a aucune importance, et pour le reste, j'ai l'habitude de coder en C, et j'ai fait cet algo à l'arrache viteuf, comme précisé d'ailleurs. (en passant, en C les booléesn sont codés comme des int, alors à la rigueur c'est même mieux ^^, et je ne fais pas de tour de boucle en plus qu'avec ta méthode. Deux ou trois cafés de trop?)
Marsh Posté le 21-12-2005 à 10:40:34
durkheim a écrit : Si on prend pas en compte la notion d'optiomisation, alors tes remarques n'ont pas lieu d'être. Le préfixage de ++ n'a aucune importance, et pour le reste, j'ai l'habitude de coder en C, et j'ai fait cet algo à l'arrache viteuf, comme précisé d'ailleurs. (en passant, en C les booléesn sont codés comme des int, alors à la rigueur c'est même mieux ^^, et je ne fais pas de tour de boucle en plus qu'avec ta méthode. Deux ou trois cafés de trop?) |
on fait pas de C ici, merci de sortir
et mes remarques que tu as l'air de considérer comme des optimisations sont simplement des remarques de bon sens. (Qui plus est, optimiser sans tenir compte du contexte d'utilisation, c'est assez moyen)
désolé pour ma remarque sur les tours en trop, effectivement, tu n'en fais pas, c'est juste la condition du for qui n'est pas vraiment naturelle
Marsh Posté le 21-12-2005 à 10:43:43
Ok, ok, remarques acceptées. Voila une nouvelle mouture, C++ compliant:
bool verif_premier (unsigned int nb)
{
int diviser;
int trouve = 0;
for (diviser = 2; diviser <= sqrt(nb,2), trouve == 0; diviser++)
{
if (nb%diviser == 0) //reste de la division = 0
{
trouve = 1;
}
}
return (trouve == 0);
}
Bon, comme tu vas encore trouver à y redire, je te propose de poster une fonction similaire en améliorant celle ci, et je ferai de même. Au lieu de 4 posts inutiles, on aura ptêt un prog pour le posteur.
Marsh Posté le 21-12-2005 à 10:59:13
bah, le posteur n'a pas l'air particulièrement intéressé par l'idée d'avoir une solution toute faite, non ? apparamment, il fait ca pour prendre en main le langage
sinon, l'algo en lui-même, comme tu l'as prouvé dès ta première intervention, n'est pas d'une difficulté insurmontable si on veut juste quelque chose de "fonctionnel", donc bon ...
Marsh Posté le 21-12-2005 à 13:18:32
tant qu'on y est a parler d'optimisation c'est ridicule de faire un sqrt() a chaque itération !!!!!! et çà mange certainement plus de cycles que le résultat temporraire inutile
Ma petite version:
Code :
|
Après evidemment on peut optimiser, en effet les seuls diviseurs a tester sont les autres nombres premiers, du coup ton optim de n'utiliser que les impairs a partir de 3 marche pas mal.
Marsh Posté le 21-12-2005 à 13:22:02
le int main() ligne 49 est horrible, fait une boucle dans ton main qui lit l'entrée et appelle la méthode de test, méthode qui renvoie un bool et qui n'affiche rien... c'est ds la boucle du main que tu vas faire l'affichage selon le résultat de la fonction
pour ton souci ds la boucle, as tu tracé au moins ? en mode debug tu devrais vite trouver le porblème
(tu compiles avec koi ?)
Marsh Posté le 21-12-2005 à 14:15:23
Malkav a écrit : le int main() ligne 49 est horrible |
c'est pas que c'est horrible, c'est surtout que ca déclare une fonction, la ligne est donc parfaitement inutile
ensuite, non, on ne s'occupe pas d'optimiser, justement
si la fonction avait réellement besoin d'être optimisée, ca sous-entendrait qu'elle serait un point critique de l'application, donc qu'elle serait appelée souvent. Auquel cas on pourrait préférer stocker les différents nombres premiers qu'on a pu rencontrer afin de les réutiliser pour les calculs suivants, par exemple ... donc ce n'est pas de ca qu'on s'occupe ici
Marsh Posté le 21-12-2005 à 15:16:58
Code :
|
Marsh Posté le 21-12-2005 à 18:36:09
Bon merci de vous interesser à mon prog, aussi pitoyable soit-il!
Je vais effectivement retenir vos conseils (ne teste jamais deux nombres flottants avec == ou !=...) et je vais me mettre sérieusement au C++ avec 1 bon bouquin (et les cours de l'IUT qu'on m'a passé)
Je n'ai utilisé que "Dev-C++ 4" (en anglais) -un vieux truc quoi!
Je cherchais à faire ce prog : pour me faire au C++ déjà; mais aussi parce-que ce programme m'intéressait! (je veux dire que je voulais avoir un prog qui me permette de trouver des nombres premiers ou les facteurs premiers d'un nombre). C vrai qu'on peut en trouver sur le net, mais je voulais le faire moi-même.
Je trouve assez inutile de tester la division avec les nombres pairs ( càd 1 sur 2!!), car c'est une opération totalement inutile quand on sait s'il est lui-m pair ou non!!!
//maintenant si c pas encore à ma portée de faire une boucle à incrémentation de 2... c 1 autre probl.
Cette optimisation (j'appelle même pas ça 1 optimisation...) est importante si le nombre entré est très grand. (d'autant plus que c'est la seule existante -mis à part faire une boucle la plus concise possible...)
De nombreux chercheurs planchent là dessus et l'algo le + puissant est basé sur ça / ils ont trouvé des trucs ms c plus de la prog (HS) et c trop compliqué!)
Enfin la boucle peut s'arrêter lorsque le diviseur == racine carrée du nombre entré.
???1? comment on fait les racines en C++ ???
???2? Je sais qu'on peut utiliser goto mais je sais pas comment on definit un label!
???3? Quelle est la syntaxe exacte de la boucle for ? (je vois pas ce qui empêche d'incrémenter 2...)
--Merci--
Marsh Posté le 22-12-2005 à 10:10:48
1 : std::sqrt pour la racine en C++, j'imagine (je n'ai pas vérifié)
2 : l'utilisation de goto est une mauvaise habitude que tu as pu avoir avec ta calculatrice, normalement, tu ne devrais en avoir besoin que dans de très rares cas. Sinon, la déclaration d'un label se fait de la manière suivante :
nom_label:
3 : for( intialisation ; condition ; incrémentation) instruction à répéter
donc oui, rien ne t'empêche d'incrémenter de 2 en 2, simplement, le fait de faire ca induit que tu es en train de chercher à optimiser et la remarque plus haut portait plutôt sur ce fait ... On ne cherche pas à optimiser un algo bancal
(Edit : AMHA, les chercheurs ne vont pas s'amuser à entrer un à un les nombres qu'ils soupçonnent être premiers, donc l'approche de ton programme est déjà contestable si c'est là sa vocation)
Marsh Posté le 22-12-2005 à 15:15:52
shockwave, quand on parle d'optimisation c'est pas juste en stockant un résultat de calcul, là c meme pas de l'optimisation c'est du bon sens, et une bonne habitude à prendre. on n'est pas obligé de faire expres de pondre du code lent qd meme.
jet-acide : tu as tout a fait raison, il est inutile de tester avec les nb pairs...
pour la racine carrée ben j'ai mis un exemple, lit le, sinon la méthode c'est
Code :
|
dans math.h
Pour sortir d'une boucle pas de goto mais un break, mais pas la peine si tu peux retourner direct le résultat
sinon çà donne par exemple un truc du genre :
Code :
|
Marsh Posté le 22-12-2005 à 15:44:21
moi je vote, le C# c'est mieu.
et au moins, une abération du style :
int truc()
{
return false;
}
au moins ça compile pas en C#... quand je vois ça dans un programme C/C++, j'ai envie de noyer son auteur
Marsh Posté le 22-12-2005 à 15:58:01
Arjuna a écrit : au moins ça compile pas en C#... quand je vois ça dans un programme C/C++, j'ai envie de noyer son auteur |
Euh, non, return false en C, ça n'existe pas. En C++ à la rigueur...
Marsh Posté le 22-12-2005 à 16:05:01
Ouais, m'enfin le C me permettra quand même de faire un return 'e' alors que ma fonction est censée retourner un Int...
Marsh Posté le 22-12-2005 à 16:10:22
Arjuna a écrit : Ouais, m'enfin le C me permettra quand même de faire un return 'e' alors que ma fonction est censée retourner un Int... |
En C, 'e' est un int...
Marsh Posté le 22-12-2005 à 16:27:15
Le C n'est pas typé. C'est qu'une surcharge bien pourrie de l'ASM en fait.
Marsh Posté le 22-12-2005 à 16:34:14
En tout cas, en C# ça marche pas trop mal...
Code :
|
1234567890123456817 => 44 secondes pour trouver que c'est un nombre premier sur un Pentium M 1.5 GHz
Marsh Posté le 22-12-2005 à 16:52:45
C'est bien bête : "decimal" ne marche pas avec la fonction double Math.Sqrt(double a)
Parceque "1234567890123456817", c'est le nombre maximum de chiffres d'un entier 64 bits (j'aurais pu utiliser non signé, m'enfin ça n'aurait pas changé grand chose).
decimal aurait dû permettre d'utiliser des nombres avec au moins le double de chiffres
en tout cas, "1234567890123456817" dans un double (ou un float, ça revient au même) c'est marrant : y'a trop de chiffres et du coup ça dépasse sa précision. ainsi, 1234567890123456817%2 = 0
Marsh Posté le 22-12-2005 à 18:20:06
je ne dirais pas mieux, loin de là
certes, c'est pratique, mais c'est loin d'être adapté à tous les traitements
Edit : Et ... bordel, on est dans la cat C++ pour un mec qui apprend le C++, donc pas de C# ici
Marsh Posté le 22-12-2005 à 18:38:27
Malkav j'avais lu mais j'avais pas compris sqrt...
merci pour ton code.
Shockwave : le but des recherches (pas le mi1) est :
-Tu renrte une cléf publique (cryptographie) qui est : nombre=(nbre_premier1_128bits*nbre_premier2_128bits)
-Ton prog miraculeux te trouve ces 2 multiplicateurs dont l'un est la cléf de décryptage
-Tu décrypte le message sensé être "inviolable" (genre RSA).
Un algo en C/C++ ne peut pas trouver ça en moins de quelques années... (Avec les + gros cluster -non quantiques- du monde) !
Mais les nbres premiers m'ont tjr interessés.
Marsh Posté le 22-12-2005 à 19:03:58
oui, donc tu n'entres pas les nombres premiers à la main ... tu fais un générateur de nombres premiers sur 128 bits, CQFD, tu es mal parti dans ce que tu veux faire, même si ca a pour but de te faire la main sur le langage
(et sinon, ne t'inquiète pas, j'ai fait un peu de crypto pendant mes cours )
Marsh Posté le 24-12-2005 à 16:08:38
Malkav a écrit : là c meme pas de l'optimisation c'est du bon sens |
C'est extrèmement discutable, ça rend le code moins lisible en n'apportant peu ou prou rien en terme de vitesse de calcul.
Malkav a écrit : une bonne habitude à prendre. on n'est pas obligé de faire expres de pondre du code lent qd meme |
Non, utiliser des constructions rapides pourquoi pas, mais ce genre d'optimisations à la con, pas avant d'avoir fait tourner un profiler sur le code pour vérifier que ça fume vraiment les perfs, et (surtout) pas avant d'être sûr que l'algo actuel est le meilleur disponible et que les performances sont insuffisantes
Marsh Posté le 20-12-2005 à 17:23:03
Bon j'ai fait un petit programme qui est sensé déterminer si un nombre est premier ou pas...
Le problème est à l'intérieur de la boucle for...
Quand un nombre n'est ni divisible par 2, ni par 3, il se met en boucle ininterrompue et je trouve pas pourquoi!
(j'ai pas encore mis de quoi quitter mais ça n'a pas d'importance je le ferai + tard...)
A l'occaz une petite simplification ne se refuse pas... Mon script doit être bourré de fautes car C mon 1er prog en C++ et je n'ai jamais eu de formation
Bon d'accord il est construit d'une drôle de façon, mais avec l'habitude ça ira mieux!
Alors qu'est-ce qui pose problème?