2010-07-21 48 views
6

Mã nàyChức năng srand trong C++

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main() 
{ 
    printf ("First number: %d\n", rand() % 100); 
    srand (time(NULL)); 
    printf ("Random number: %d\n", rand() % 100); 
    srand (1); 
    printf ("Again the first number: %d\n", rand() %100); 

    return 0; 
} 

có đầu ra sau đây:

First number: 41 
Random number: 13 
Again the first number: 41 

Ngoài ra còn có các nguyên tắc sau:

Hai khởi tạo khác nhau với các hạt giống, chỉ thị trình tạo giả ngẫu nhiên để tạo ra cùng một loạt các kết quả cho các cuộc gọi tiếp theo tới rand trong cả hai trường hợp.

Tôi hiểu các từ nhưng tôi không hiểu chính phương thức đó. Tại sao nó lại trả lại 41? Có phải ngẫu nhiên hay phải trả về cùng một kết quả trong mọi trường hợp theo mã này?

+2

Điều này giúp gỡ lỗi dễ dàng hơn. Nếu bạn đang chạy bình thường sử dụng srant (thời gian (NULL)). Nếu có một lỗi trong chương trình của bạn không gọi srand() hoặc gọi srand (1) và bạn sẽ nhận được cùng một chuỗi các số từ các cuộc gọi đến rand(). Lưu ý mỗi cuộc gọi đến rand sẽ tạo ra số tiếp theo trong chuỗi nhưng chuỗi sẽ luôn giống nhau. Lưu ý 2: Bạn chỉ nên gọi srand() một lần trong ứng dụng. –

+0

@Martin York: Rất đẹp. Không bao giờ nghĩ về điều này từ điểm gỡ lỗi. Có ý nghĩa. – Lazer

Trả lời

7

Nếu bạn gọi rand() mà không gọi srand(), hành vi này là như nếu bạn gọi srand() với 1 làm đối số.

Hành vi này được xác định trong tiêu chuẩn C ban đầu. Tôi không có một bản sao đầy đủ của nó tiện dụng, nhưng tiêu chuẩn POSIX Các Tập đoàn mở là điều tốt nhất tiếp theo, khi họ kết hợp các tiêu chuẩn đầy đủ C (với một số phần mở rộng):

http://www.opengroup.org/onlinepubs/000095399/functions/rand.html

Các srand Hàm() sử dụng đối số như là một hạt giống cho một chuỗi các số giả ngẫu nhiên mới được trả về bởi các cuộc gọi tiếp theo tới rand(). Nếu srand() sau đó được gọi với cùng một giá trị hạt giống, thì lặp lại các chuỗi số ngẫu nhiên giả. Nếu rand() được gọi trước khi bất kỳ cuộc gọi đến srand() được thực hiện, cùng một chuỗi được tạo ra như khi srand() là lần đầu tiên được gọi với một giá trị hạt giống 1.

Các thực tế kết quả của một cuộc gọi rand() đối với bất kỳ hạt giống cụ thể nào được xác định thực hiện, ngoại trừ đối với bất kỳ hạt giống nào x, hãy gọi n đến rand() sau khi tạo hạt giống của trình tạo phải trả về cùng một kết quả. Vì vậy, trong khi thực hiện, bạn sẽ luôn nhận được 41 trong cuộc gọi rand() đầu tiên sau khi gọi srand(1) và bạn sẽ luôn nhận được kết quả tương tự (cho dù đó là) cho cuộc gọi thứ hai rand(), các triển khai khác có thể sử dụng một thuật toán khác để tạo ra các kết quả khác nhau.

0

Tôi nghĩ cái này có thể là một vấn đề:

Nếu hạt giống được thiết lập để 1, các máy phát điện được reinitialized với giá trị ban đầu của nó và tạo ra các giá trị tương tự như trước bất kỳ cuộc gọi đến rand hoặc srand.

srand reference

0

Gọi srand với giá trị 1 đặt lại trình khởi động về trạng thái ban đầu khi chương trình bắt đầu.

7

Chuẩn C++ theo tiêu chuẩn C cho randsrand (xem phần 26.8 của C++ 0x):

Chức năng rand có ngữ nghĩa được quy định trong tiêu chuẩn C, ngoại trừ việc thực hiện có thể xác định rằng chức năng thư viện đặc biệt có thể gọi rand.

Các tiêu chuẩn C (7.20.2.2 của C99) khẳng định khá khoát:

Nếu rand được gọi trước khi bất kỳ cuộc gọi đến srand đã được thực hiện, cùng một chuỗi được tạo ra như khi srand là lần đầu tiên được gọi với giá trị hạt giống là 1.

Lần đầu tiên bạn gọi rand, hạt giống là 1. Đây cũng là lần thứ ba bạn gọi đó là lý do tại sao bạn nhận được cùng một giá trị.

Lần thứ hai bạn gọi là rand, hạt giống đã được đặt dựa trên thời gian hiện tại, đó là lý do tại sao bạn nhận được kết quả khác. Thường không phải là một ý tưởng tốt để tái tạo trình tạo số ngẫu nhiên trừ khi bạn thực sự là muốn cùng một trình tự (chẳng hạn như trong thử nghiệm).

0

srand(3) cho phép bạn nhận được kết quả có thể lặp lại từ trình tạo số ngẫu nhiên. Bằng cách này, bạn có thể viết các chương trình phụ thuộc vào các số ngẫu nhiên, nhưng kiểm tra chúng một cách xác định. (Thông thường bằng cách có một tùy chọn dòng lệnh để gọi srand() với đối số được cung cấp, vì vậy nó có thể chạy hàng trăm lần với 1, 2, 3, 4, 5, ... làm đầu vào.)

Vì vậy, đây là hành xử như mong đợi.

0

Có thể vì trong lần gọi ban đầu của bạn để rand trình tạo số ngẫu nhiên chưa được tạo hạt giống nên nó sử dụng giá trị mặc định là 1 để gieo hạt.