D'abord, srand() ne s'appelle qu'une seule fois, en début du main() par exemple, et on ne voit pas les résultats de tes exécutions.
Ensuite, si tu exécutes ton programme plusieurs fois durant la même seconde, le srand() recevra toujours la même valeur (puisque la valeur renvoyée par time() ne change que toutes les secondes) et donc le rand() génèrera la même valeur.
Enfin,
- Edité par edgarjacobs 8 novembre 2023 à 18:14:59
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Effectivement, srand() ne devrait être exécuté qu'une fois par le programme ou en tout cas n'a pas vocation à être intégré dans une boucle ou une fonction appelée par une boucle pour les raisons expliquées.
Le problème demeure que si le programme doit être exécuté (l'exécutable du programme lancé) plusieurs fois dans un intervalle de temps rapide inférieur à 1 seconde, l'instruction srand(time(NULL)); sera initialisée avec la même graine produite par time(NULL) pour toutes les exécutions faites dans la même seconde, et le résultat de srand() sera identique pendant cette seconde.
Si on a vraiment besoin de faire cela, on pourrait utiliser une autre graine dont on aurait l'assurance qu'elle soit différente à chaque exécution même si le programme est exécuté plusieurs fois dans la même seconde.
Cela peut être un timer avec une plus grande résolution que la seconde, ou le process ID du programme ou n'importe quoi d'unique au programme lancé que l'on puisse exprimer ou transformer sous la forme d'un unsigned int attendu par srand().
Le désavantage de ne pas utiliser time(NULL) pour générer la graine est que l'on doit utiliser des fonctions non standard du C, particulières au système utilisé, mais on peut tout à fait utiliser autre chose.
Exemple donné sur un post récent sur un autre forum :
qui fonctionne sous Linux avec getpid() (qui renvoie un pid_t, qui se trouve être implémenté comme un alias sur unsigned int sous Linux).
L'opération bitwise XOR proposée par le contributeur de ce forum n'est pas vraiment nécessaire si, se toutes façons, la graine n'est initialisée qu'une fois pour un processus donné, et on pourrait se contenter de srand(getpid()).
@Dlks: j'avais déjà lu cette discussion, et j'avais testé sous windows
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h> // pour _getpid()
#define XOR ^ // pour faciliter la lecture aux débutants
int main(void) {
srand(time(NULL) XOR _getpid());
printf("%d\n", rand());
return(0);
}
lancé avec le .bat
@echo off
:next
rand
goto next
et, évidemment, ça fonctionnne. Mais je ne mettrais pas que le _getpid(), ne pourrait-il pas se répéter ? (aucune expérience à ce sujet) (mais ce n'est sans doute qu'une question théorique).
- Edité par edgarjacobs 10 novembre 2023 à 18:57:40
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
(...) ça fonctionnne. Mais je ne mettrais pas que le _getpid(), ne pourrait-il pas se répéter ? (aucune expérience à ce sujet).
Le problème que l'on cherche à résoudre est que si l'exécutable est lancé à intervalles très rapprochés inférieurs à 1 seconde, srand(time(NULL)) est initialisé avec la même graine et rand() produit le même résultat.
Le fait de conserver time(NULL) dans la détermination de la graine ne nous aide donc pas.
En revanche, comme dans un système d'exploitation l'ID du processus doit être unique, par définition, c'est le seul élément réellement utile dans ce code pour résoudre notre problème.
C'est intéressant de savoir que la fonction POSIX getpid() est implémentée sous la forme de _getpid() (qu'on ne peut pas utiliser pour des applications UWP cependant). Bizarrement elle retourne un int (un entier signé...) :
Microsoft fait un tour de passe-passe et n'explique pas sa doc comment un DWORD peut finalement être exprimé comme un int.
Cela nous arrange dans le cas de l'utilisation avec srand() (car la graine doit être un unsigned int selon le standard, à condition que Microsoft ne renvoie pas des entiers négatifs)... mais c'est une absurdité et contradiction parmi d'autres dans ce que nous propose ce système.
J'aurai plutôt eu tendance, sous Windows, à utiliser GetCurrentProcessId() et hacher le DWORD sous la forme de quelque chose tenant dans un unsigned int.
Le fait de conserver time(NULL) dans la détermination de la graine ne nous aide donc pas --> 1
qui retourne un "DWORD" qui, pour Microsoft, est un typedef sur un type unsigned long int --> 2
1) exact, j'ai répondu sans réfléchir
2) la doc ms se prend les pieds me semble-t-il: DWORD Ça parle d'unsigned int, mais aussi d'un typedef unsigned long, ce qui est différent (sauf si sizeof(int)==sizeof(long))*, et je n'arrive pas à trouver le .h où se trouve le typedef
*après vérification, c'est le cas
- Edité par edgarjacobs 10 novembre 2023 à 23:04:10
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Mon programme aléatoire ne fait pas d'aléatoire
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent