Génération nombre aléatoire

Résolu
MetroidFE Messages postés 210 Date d'inscription   Statut Membre Dernière intervention   -  
MetroidFE Messages postés 210 Date d'inscription   Statut Membre Dernière intervention   -
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   Statut Membre Dernière intervention   49
 
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   Statut Membre Dernière intervention   34
 
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   Statut Contributeur Dernière intervention   1 846
 
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   Statut Membre Dernière intervention   49
 
@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   Statut Membre Dernière intervention   34
 
Merci beaucoup à vous deux pour vos explications, cela m'a été bien utile :D
0
Danelectro Messages postés 1737 Date d'inscription   Statut Membre Dernière intervention   371
 
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   Statut Membre Dernière intervention   34
 
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 1737 Date d'inscription   Statut Membre Dernière intervention   371
 
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   Statut Membre Dernière intervention   34
 
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 1737 Date d'inscription   Statut Membre Dernière intervention   371
 
Met un breakpoint dans ce cas.
0
Danelectro Messages postés 1737 Date d'inscription   Statut Membre Dernière intervention   371
 
Et n'oublie pas de virer le paramètre dans l'entête de la fonction ET lors de son appel.
0