Génération nombre aléatoire

Résolu
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

  1. 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
    1. 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
    2. Contributeur
      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
    3. @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
    4. Merci beaucoup à vous deux pour vos explications, cela m'a été bien utile :D
      0
  2. 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
    1. 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
    2. 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
    3. 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
    4. Met un breakpoint dans ce cas.
      0
    5. Et n'oublie pas de virer le paramètre dans l'entête de la fonction ET lors de son appel.
      0