Это хорошая идея передать неинициализированную переменную в srand?
Хорошо ли передать неинициализированную переменную в srand
вместо результата time(NULL)
?
Это один #include
, а один вызов функции меньше.
Пример кода:
#include <stdlib.h>
int main(void) {
{
usigned seed; //uninitialized
srand(seed);
}
//other code
return 0;
}
вместо
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(NULL));
//other code
return 0;
}
Ответы
Ответ 1
Нет, это не так.
Чтение неинициализированного значения приводит к поведению undefined. Он может быть нулевым, он может быть полуслучайным, но как таковой он может неоднократно быть одним и тем же значением. Это может также привести к ошибкам компиляции или времени выполнения или любой другой совершенно непредсказуемой вещи.
Затем кто-то другой, компилирующий вашу программу, заметит предупреждение компилятора о неинициализированном значении и попытается его исправить. Он может исправить это правильно или получить достаточно сложную программу, он может просто инициализировать ее до нуля. То, что "маленькие" ошибки превращаются в огромные ошибки.
Просто попробуйте свой фрагмент с заменой srand()
на printf()
:
#include <stdio.h>
int main()
{
{
unsigned seed;
printf("%u\n", seed);
}
return 0;
}
В моей системе она несколько раз дает 0
. Это означает, что существует хотя бы одна система, где ваш код сломан:).
Ответ 2
Нет, доступ к неинициализированной переменной - это поведение undefined. Вы должны предпочесть time(NULL)
. Неинициализированный метод переменной может затруднить поиск ошибок или может привести к выходу компьютера из строя.
В большинстве случаев наблюдаемый эффект будет (при большей реализации) выше кода будет принимать (читать) некоторое оставшееся значение из стека, которое может быть нулевым или чем-то другим, но может быть одинаковым во многих прогонах, побеждающих вашу цель. time
, с другой стороны, обещает.
Ответ 3
Это не очень хорошая идея. Поведение Undefined не гарантирует, что вы не получите одно и то же семя при каждом прогоне, что было бы плохо для случайности. Это не гарантирует, что ваш процессор не остановится и не загорится.
Ответ 4
Другим моментом является то, что неинициализированные переменные могут привести к уязвимости. Таким образом, это не только плохой дизайн и поведение undefined, он также может сделать вашу программу доступной.
Рассмотрим этот код:
#include <stdio.h>
#include <time.h>
void print_uninitialized(void) {
unsigned var;
printf("%u\n", var);
}
void fake_init() {
unsigned var=42;
}
int main(void) {
print_uninitialized();
fake_init();
print_uninitialized();
}
Возможный выход:
0
42
Следующий пример является более реалистичным:
#include <stdio.h>
unsigned uninitialized( void ) {
unsigned var;
return var;
}
unsigned square(unsigned arg){
unsigned result=arg*arg;
return result;
}
int main( void ) {
unsigned to_square;
printf("UNINITIALIZED = %u\n", uninitialized());
while(scanf("%u", &to_square)!=EOF){
printf("%u * %u = %u\n", to_square, to_square, square(to_square));
printf("UNITNITIALIZED = %u\n", uninitialized());
}
}
Неинициализированная переменная может быть изменена пользователем.
Input:
2
Вывод:
UNINITIALIZED = 0
2 * 2 = 4
UNITNITIALIZED = 4
Ответ 5
В первом случае возможны две возможности:
- семя - это случайная величина (менее возможно)
- семя постоянно в каждом прогоне (возможно)
time (NULL) возвращает время, равное 99.99% при каждом запуске кода.
Ничто не является идеальным случайным, но использование времени (NULL) дает вам "более случайный" номер, если вы будете использовать первый подход.
Вы должны проверить использование функции
http://www.cplusplus.com/reference/cstdlib/srand/