Giả lập đồng hồ (clock) trên console bằng C++

việc tách các phần của hàm in clock ra có tác dụng tối ưu hơn vậy bạn
với lại như vấn đề ở đâu, phần s làm sao để nó chạy đúng nhỉ, đồng bộ với thời gian của hệ thống

Muốn đồng bộ tgian hệ thống thì có thể gettime liên tục. nếu thời gian đã trôi qua cỡ 1s thì vẽ đồng hồ.
Còn tách hàm vậy dễ đọc code hơn, tránh trùng lặp code (1 tính năng dùng lại 2 lần trở lên thì nên tách thành 1 hàm) + mốt nếu bạn thích sửa giao diện thì dễ hơn.

4 Likes

mình k muốn đồng bộ theo kiểu lấy thời gian từ hệ thống liên tục mà chỉ lấy 1 lần, và ct sẽ tự chạy đúng ấy

Mình nghĩ chương trình bạn chậm do thao tác vẽ nhiều.
Nên nó chạy bị chậm lúc tính toán do đó kéo theo bị lệch giời gian.

2 Likes

1 phần độ trễ kim giây là do hàm in, nhưng sau khi chỉnh ms về thấp xuống, thì nó vẫn k thể đúng, khi nhanh khi chậm k ổn định, bỏ hẳn hàm in ra,chỉ để lại số, vẫn thế
mình nghĩ chạy đúng hay k do 1 phần do hàm in 1 phần do vòng lặp và kiểm tra rẽ nhánh

Bạn có thể in sau khi milisecond = 60 (or khi đủ 1 giây)
Tại lúc đó giao diện mới được cập nhật.
Như vậy có thể tăng tốc lên tí xíu.

3 Likes

Đại khai như sau. Nếu bạn muốn làm 1 cái đồng hồ chính xác cỡ 0.1s thì sau 0.09s bạn lấy time hệ thống 1 lần sau đó hiển thị nó lên màn hình.
Để làm sao cứ đúng 0.09s lấy giờ 1 lần thì bạn dùng kĩ thuậ fix FPS. Gỉa code.

t_last = t_now = 0;
while(isRunning) {
  t_last = t_now.
  //Hàm thục thi.
  t_mow = getTine(); //Lấy giờ sau khi chạy xong hàm
  sleep(1000.0f / FPS - t_now + t_last) // Sleep 1 khoảng thời gian động.
}

Khi đó bạn ổn định được chu kỳ lấy thời gian mà không làm tăng chíp.
Còn việc vẽ lại màn hình có thể dùng bộ đêm hoặc gotoxy.

Chúc bạn thành công.

2 Likes

Thanks :slight_smile: :slight_smile:

sử dụng gotoxy để vẽ lại đồng hồ, có tác dụng gì khác là in ra 1 cách bt bằng cách gọi hàm in clock nhi?

đâu có làm vậy được. Lúc nào cũng phải lấy thời gian thực hết, sao tự đếm được. Vì trên máy ko phải chỉ có 1 chương trình chạy, mà cả chục chương trình chạy với nhau, mỗi chương trình sẽ thay phiên nhau xài CPU. Vì vậy chương trình bạn chạy sẽ có lúc nhanh (được phép xài CPU liên tục), lúc chậm (xài CPU cách khoảng, hoặc chờ khá lâu mới được phép xài, vd anti-virus đang chạy thì nó sẽ chiếm CPU nhiều hơn) nên chỉ dựa vào vòng for để đếm thời gian là ko bao giờ chính xác.

1 Like

như trên có mấy bác chỉ lấy thời gian theo chu kì

với việc tách hàm run_time ra thành các hàm con cho từng hành động thì có tối ưu hơn k nhỉ
vì như thế mỗi hàm chỉ có vài hàng, hàm này gọi hàm kia thì có tệ hơn là để trong cùng 1 hàm và đánh đổi bằng " if "

void run_time(){
		milisecond++;
		if (milisecond == 60){
			milisecond = 0;
			cout << "\a";
			second++;
			if (second >= 60){
				second = 0;
				minute++;
				if (minute == 60){
					minute = 0;
					hour++;
					if (hour == 24){
						hour = 0;
						day++;
						if (day == 1 + day_month(month)){
							day = 1;
							month++;
							if (month == 13){
								month = 1;
								year++;
								if (year == 2081){   // clock only run to 2080
									cout << "Out of battery" << endl;
									system("pause");
									exit(0);
								}
							}
						}
					}
				}
			}
		}
	}

trong hàm run_time()vòng do...while(1) thì lấy

time_t currentTimestamp = time(NULL); //số giây tính từ UNIX epoch (1/1/1970)
if (currentTimestamp > prevTimestamp) //prevTimestamp lưu như 1 biến của clock_console. Khi khởi tạo thì gán luôn prevTimestamp = time(NULL)
{
    prevTimestamp = currentTimestamp; //update prevTimestamp
    clock_12h(); //chỉ vẽ lại khi có thay đổi ở số giây
}

để tránh đốt CPU thì trong vòng do ... while(1); thêm vô Sleep(16);

do
{
    time_t currentTimestamp = time(NULL); //số giây tính từ UNIX epoch (1/1/1970)
    if (currentTimestamp > prevTimestamp) //prevTimestamp lưu như 1 biến của clock_console. Khi khởi tạo thì gán luôn prevTimestamp = time(NULL)
    {
        prevTimestamp = currentTimestamp; //update prevTimestamp
        clock_12h(); //chỉ vẽ lại khi có thay đổi ở số giây
        calender_number();
    }
    Sleep(16); //include <windows.h>
}
while (1);
2 Likes

nghĩa là cứ lấy rồi cập nhật, lấy rồi cập nhật, chứ k thể tự thân nó vận động à? chỉ lấy lần đầu, còn lại tự chạy

ko. Nó tự chạy thì ko đúng. 1 giây có thể nó chạy được 1000 vòng lặp, đếm đủ 1000ms = 1 giây, nhưng khi bạn bật Chrome lên, bật scan virus, bật defrag disk, v.v… thì 1 giây nó chỉ còn chạy được 10 vòng lặp, đếm 10ms, ko đúng 1 giây.

máy tính có 1 bộ phận đếm giờ riêng thì phải, time(NULL) là lấy thời gian này ra. Đó chính là thời gian thực. Thật ra nếu bạn có kết nối internet thì bộ phận này cũng có thể phải lấy thời gian từ internet xuống cho đồng bộ, chứ nó chạy cũng ko đúng 100%, ví dụ 1 ngày lệch 1 giây chẳng hạn.

trừ phi máy tính của bạn chỉ dùng để đếm giờ (ko bao giờ có chuyện này, bạn bật task manager lên thì xem có bao nhiêu tiến trình đang chạy hiện tại, toàn trên 20 process) thì 1 vòng do…while có thể đếm đúng , nhưng cũng có sai số, vd 1 giây chạy được 999-1001 vòng lặp, ko bao giờ đúng 1000 mãi mãi được.

3 Likes

hình như thời gian của hệ thống nó chạy trên bios, được nuôi bởi 1 con pin cmos riêng, nên nó k bị ảnh hưởng với mt
ý mình là giờ có cách nào ngoài cách gettime liên tục ấy :3
chứ k thì đồng hồ này vứt đi :smile: đồng hồ mà sai h thì chỉ có vứt rồi

cái này là bạn đo bằng hàm có sẵn hay là xem ở tài liệu nào vậy

phán đại thôi. Có thể là 1200 vòng, 10 ngàn vòng, 60 ngàn vòng v.v… ko biết được. CPU nhanh thì số vòng càng nhiều, CPU cùi bắp thì số vòng càng ít.

2 Likes

chắc thử lên stackoverflow xem có tây nào có cách k :3 cứu vãn lấy e đồng hồ fake

muốn chính xác thì phải truy time(NULL) liên tục thôi, ko có cách nào khác đâu =)

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?