Génération nombre aléatoire

Résolu/Fermé
MetroidFE Messages postés 210 Date d'inscription vendredi 24 août 2012 Statut Membre Dernière intervention 9 septembre 2014 - 1 août 2014 à 01:15
MetroidFE Messages postés 210 Date d'inscription vendredi 24 août 2012 Statut Membre Dernière intervention 9 septembre 2014 - 1 août 2014 à 15:33
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
A voir également:

2 réponses

sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
Modifié par sambia39 le 1/08/2014 à 12:14
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
MetroidFE Messages postés 210 Date d'inscription vendredi 24 août 2012 Statut Membre Dernière intervention 9 septembre 2014 34
1 août 2014 à 13:03
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!)
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
1 août 2014 à 14:02
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,
0
sambia39 Messages postés 610 Date d'inscription vendredi 31 juillet 2009 Statut Membre Dernière intervention 9 février 2023 49
Modifié par sambia39 le 1/08/2014 à 14:53
@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
0
MetroidFE Messages postés 210 Date d'inscription vendredi 24 août 2012 Statut Membre Dernière intervention 9 septembre 2014 34
1 août 2014 à 15:33
Merci beaucoup à vous deux pour vos explications, cela m'a été bien utile :D
0
Danelectro Messages postés 1723 Date d'inscription samedi 25 février 2012 Statut Membre Dernière intervention 29 mars 2018 369
1 août 2014 à 01:17
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.
-2
MetroidFE Messages postés 210 Date d'inscription vendredi 24 août 2012 Statut Membre Dernière intervention 9 septembre 2014 34
1 août 2014 à 01:19
C'est parceque elle est appelée de la façon suivante:

int nombreAleatoire = random(nombreAleatoire);
Pensez vous que cette variable n'a pas lieu d'être en paramètre?
0
Danelectro Messages postés 1723 Date d'inscription samedi 25 février 2012 Statut Membre Dernière intervention 29 mars 2018 369
1 août 2014 à 01:24
Ah non non, attention ! On passe un paramètre quand on utilise ce paramètre dans la fonction. La tu peux passer tout ce que tu veux en paramètre, la ligne
nombre = rand() % 600;
le remplacera. De plus, si tu n'initialise pas nombreAleatoire, le programme plante forcément car la fonction attend un entier, et pas... rien du tout.
Vire ce paramètre, ça devrait mieux marcher. La fonction va s'exécuter, et le return va mettre le résultat de cette fonction dans nombreAleatoire.
0
MetroidFE Messages postés 210 Date d'inscription vendredi 24 août 2012 Statut Membre Dernière intervention 9 septembre 2014 34
1 août 2014 à 01:31
Je viens de le faire, mon programme continue de planter (je suis absolument sûr que c'est dans cette fonction qu'il plante)
0
Danelectro Messages postés 1723 Date d'inscription samedi 25 février 2012 Statut Membre Dernière intervention 29 mars 2018 369
1 août 2014 à 01:32
Met un breakpoint dans ce cas.
0
Danelectro Messages postés 1723 Date d'inscription samedi 25 février 2012 Statut Membre Dernière intervention 29 mars 2018 369
1 août 2014 à 01:34
Et n'oublie pas de virer le paramètre dans l'entête de la fonction ET lors de son appel.
0