Génération nombre aléatoire [Résolu/Fermé]

Signaler
Messages postés
214
Date d'inscription
vendredi 24 août 2012
Statut
Membre
Dernière intervention
9 septembre 2014
-
Messages postés
214
Date d'inscription
vendredi 24 août 2012
Statut
Membre
Dernière intervention
9 septembre 2014
-
Bonsoir,
Je suis débutant en C, et j'aimerais générer un nombre aléatoire.
Voici la fonction qui est censée le faire:

int random(int nombre)
{
int valider = 1;

srand(time(NULL));

/*Cette fonction est censée générer un multiple de 30 entre 0 et 600*/

while(valider)
{
nombre = rand() % 600;

for(int compteur = 0; compteur < 600; compteur += 30)
{
if (nombre == compteur)
{
valider += 1;
}
}
}

return nombre;
}

Mon problème est que, à chaque fois que j'appelle cette fonction, mon programme plante.
Est-ce à cause du
srand(time(NULL))
que j'ai mis au début et qu'il ne faut utiliser qu'une seule fois?

Merci d'avance de votre réponse

2 réponses

Messages postés
609
Date d'inscription
vendredi 31 juillet 2009
Statut
Membre
Dernière intervention
24 juin 2016
38
Bonjour,
Avant toute choses, je ne pense pas que le sujet soit résolu pour la simple raison que les solutions proposer ne fournisse pas des nombres suffisamment pseudo-aléatoire
qui est le terme correct en informatique ( je pense ).
Le code proposer plus haut est serte fonctionnel mais, incorrect, si on fait appel à la même fonction une deuxième fois en remarque vite qu'il n'y a pas vraiment du pseudo-aléatoire mais juste une répétition des nombres déjà généré à moins que ça soit ce que vous cherchiez ?.
Pour corrigé cela, il faut écrire une votre fonction random de la manière suivante:
/**
* Fonction générateur 
* de nombre pseudo aléatoire
* en définissant une borne
**/
int f_Rand( const int arg ){
 
 static int _seed = 0;
 if( !_seed ){
  _seed = 1;
  srand( time( NULL ) );
 }
 return ( rand() % arg);
}

/**
* Fonction générateur 
* de nombre pseudo aléatoire
* par défaut
**/
int f_Rand( void ){
 
 const int arg = 100;
 static int seed = 0;
 if( seed ){
  seed = 1;
  srand( time( NULL ) );
 }
 return ( rand() % arg );
}


Ainsi donc si l'on modifie légèrement le code précédent en apportant également d'autres correctifs au passage on obtient le code suivant
/***
*  Fonction initialisation
* des nombres pseudo 
* aléatoire
***/
void f_InitRand( void ){
 
 static int seed = 0;
 if( !seed ){
  seed = 1;
  srand( time ( NULL ) );
 }
}

/***
*  Fonction légerement 
* modifier
***/
int f_Random( const int arg ){
 
 int i = 1;
 int j = 0;
 int r = 0;

    f_InitRand();

    /***
 * Cette fonction est censée 
 * générer un multiple de 30 
 * entre 0 et 600
 ***/

    while( i ){
     
        r = ( rand() % arg );
        
        for( ( j = 0 ); ( j < arg );  ( j+= 30 ) ){
         
            printf("%d -> %d\n", r, j );
            if ( r == j ){
                i = 0;
            }
        }
    }
    
    return ( r );
}

/***
* Fonction principale
***/
int main( void ){
       
    int ret = f_Random( 600 );
       printf(" Retour_1\t = %d\n", ret );

       printf("\n ===============( Cas 2 )===============\n");
       
       ret = 0;
       ret = f_Random( 600 );
       printf(" Retour_2\t = %d\n", ret );
       
       return ( 0 );
}

Et là même après une autre appel de la fonction on obtient des nombres suffisamment pseudo-aléatoires.
à bientôt

Toute connaissance est une réponse à une question.
3
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 60596 internautes nous ont dit merci ce mois-ci

Messages postés
214
Date d'inscription
vendredi 24 août 2012
Statut
Membre
Dernière intervention
9 septembre 2014
29
Merci!
En fait vous n'avez initialisé qu'une seule fois le
srand(time(NULL))
, et c'est ce changement qui permet de générer des pseudo aléatoires, je me trompe?
(Et je cherchais justement à garder la valeur d'une variable même quand on sort d'une fonction, je n'avais pas pensé au
static
, merci!)
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 695
Ou alors, tout simplement mettre srand(time(NULL)); dans le main().

srand() permet d'initialiser la séquence de nombres pseudo-aléatoires.
Si tu ne l'utilises pas, on prendra la séquence par défaut. De fait, à chaque lancement de programme, tu récupéreras la même liste.

Pour garder la valeur d'une variable, tu as static, global, ou les paramètres.

Sinon, pour récupérer un nombre pseudo-aléatoire multiple de 30, il y a beaucoup plus simple que la boucle while jusqu'à obtenir un modulo 30 à 0... Il suffit de générer un nombre pseudo-aléatoire et le multiplier par 30 ;-).

Cdlt,
Messages postés
609
Date d'inscription
vendredi 31 juillet 2009
Statut
Membre
Dernière intervention
24 juin 2016
38
@MetroidFE La question n'est pas de savoir si le changement où n'italisation de cette fonction définie sont nouveaux comportements, c'est plutôt savoir pourquoi doit-on initialiser à zéro ? et je complète ce que à dit @fiddy même-ci je le répète:

C'est pour obtenir des nombres différents à chaque exécution du programme et garantir une suffisance pseudo-aléatoire des nombres et pour ça il faut utiliser la fonction
 time()
(qui renvoie le nombre de secondes écoulées depuis le 1er janvier 1970).
Mais aussi, il faut savoir que la fonction
rand()
retourne un nombre entier (de type
int
) tiré au hasard et ce nombre est compris entre 0 et RAND_MAX, qui est une valeur définie dans l'en-tête
stdlib.h

Bref, @fiddy la mieux expliquer et en plus y' a plus facile.
à bientôt
Messages postés
214
Date d'inscription
vendredi 24 août 2012
Statut
Membre
Dernière intervention
9 septembre 2014
29
Merci beaucoup à vous deux pour vos explications, cela m'a été bien utile :D
Messages postés
1723
Date d'inscription
samedi 25 février 2012
Statut
Membre
Dernière intervention
29 mars 2018
324
Salut,
Pourquoi ta fonction demande-t-elle un nombre ? Tu réutilises d'ailleurs cette même variable dans ton code, je ne comprends pas.
Messages postés
1723
Date d'inscription
samedi 25 février 2012
Statut
Membre
Dernière intervention
29 mars 2018
324
Un breakpoint sert à stopper l'exécution d'un programme à un endroit précis. C'est l'IDE qui s'occuper de ça, en général cliquer dans la marge (là où ça compte les lignes) en place un. Et faut run en mode debug.
Tu peux en placer plusieurs pour voir où ça coince. Avant chaque bloc de la fonction par exemple.
Messages postés
1723
Date d'inscription
samedi 25 février 2012
Statut
Membre
Dernière intervention
29 mars 2018
324
Ah et aussi déclare "nombre" DANS ta fonction.
Messages postés
1723
Date d'inscription
samedi 25 février 2012
Statut
Membre
Dernière intervention
29 mars 2018
324
Autre erreur : il faut mettre
valider -= 1;
à la place de
valider += 1;
, sinon la boucle ne s'arrête jamais (eh oui, tu tombes sur 2, qui vaut aussi true).
Dernière chose, déclare le compteur à l'extérieur du for.
Voilà mon code, il fonctionne.

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

main(){
int nombreAleatoire = random();
printf("%d",nombreAleatoire);
}

int random()
{
int valider = 1;
int nombre;
int compteur;

srand(time(NULL));

/*Cette fonction est censée générer un multiple de 30 entre 0 et 600*/

while(valider)
{
nombre = rand() % 600;

for(compteur = 0; compteur < 600; compteur += 30)
{
printf("> %d - %d\n", nombre, compteur);
if (nombre == compteur)
{
valider -= 1;
}
}
}

return nombre;
}
Messages postés
214
Date d'inscription
vendredi 24 août 2012
Statut
Membre
Dernière intervention
9 septembre 2014
29
Merci beaucoup, je croyais que l'on pouvait déclarer une variable dans un FOR. Le problème venait bien du
valider += 1;
, mon programme fonctionne parfaitement désormais!
Bonne soirée!
Messages postés
1723
Date d'inscription
samedi 25 février 2012
Statut
Membre
Dernière intervention
29 mars 2018
324
Le coup de la variable dans le for je ne suis pas sûr, ça dépend des langages mais c'est pas très propre de toute façon.

Bonne soirée :)