Dùng vòng lặp while để chương trình không nhận số 0 và số âm

Mọi người cho mình hỏi với!
Mình tính diện tích hình chữ nhật, dùng vòng lặp while để chương trình không nhận số 0 và số âm
Thì xảy ra 1 vấn đề
Đoạn vòng while mình để thế này

while(chieu_dai<0||chieu_rong<0)

thì chương trình chạy bình thường, nhưng đổi sang

while(chieu_dai<=0||chieu_rong<=0)

thì kết quả máy tính mặc định bằng 0

Code mình viết:

#include<iostream>
using namespace std;
int main()
{
	float chieu_dai, chieu_rong, S;
	while(chieu_dai<=0||chieu_rong<=0)
	{
		cout<<"Nhap chieu dai: ";
		cin>>chieu_dai;
		cout<<"Nhap chieu rong: ";
		cin>>chieu_rong;
		if(chieu_dai<=0||chieu_rong<=0)
		{
			cout<<"So lieu sai!\n\n";
		}
		S=chieu_dai*chieu_rong;
	}
		cout<<"Dien tich la: "<<S;
	system("pause");
	return 0;
}

Ồ, lần đầu while chưa đọc gì thì sao bạn biết được chieu_dai với chieu_rong là bao nhiêu được?

6 Likes

Đôi khi, chúng ta không nên viết code bừa mà phải đọc kĩ xem code nó làm cái gì.

Đối với trình độ của bạn hiện tại thì mình chỉ nói đơn giản là trong C, C++, khi khai báo biến mới thì nó sẽ nhận giá trị ngẫu nhiên, còn nó có thực sự ngẫu nhiên hay không thì mình sẽ không nói tới. Trong trường hợp này, vì chieu_daichieu_rong lớn hơn 0 nên hiển nhiên đoạn code phía dưới vòng lặp while sẽ không chạy. Nếu bạn test vài chục, vài trăm, vài nghìn lần thì biết đâu nó chạy.
Còn kết quả mặc định của máy tính là 0 do:

P/s: Một số compiler cho giá trị mặc định là 0.

5 Likes
  • Bạn nên dùng do while nhé. Nó sẽ chạy ít nhất 1 lần.
  • Ở 1 số compiler nó sẽ mặc định bằng 0 nếu bạn không khai báo, vì vậy 0 nhân gì cũng bằng 0. Bạn nên cho nó bằng 1 ở đầu vòng lặp.
1 Like

Vậy là chương trình chạy được là do có giá trị được sinh ra ngẫu nhiên trong C/C++. Cảm ơn bạn chỗ này nhiều. Cái này là chỉ trong C/C++ hay các ngôn ngữ khác nó cũng tạo ngẫu nhiên như vậy ạ.
Bạn có giải thích cả vế sau luôn được không? :grin: :grin:

Và mình có sửa lại

cout<<"Nhap chieu dai: "; cin>>chieu_dai;
cout<<"Nhap chieu rong: "; cin>>chieu_rong;
while(chieu_dai<=0||chieu_rong<=0)

Như vậy có đúng bản chất là nó đã có điều kiện để so sánh trước khi vòng lặp xảy ra không?

Ý tưởng của bạn là cho user nhập chiều dài và chiều rộng, và nếu user nhập sai thì bắt nhập lại. Có nghĩa là nó phải nhận input từ người dùng trước đã, bạn hãy dùng do while .

do{
        cout<<"Nhap chieu dai: ";
		cin>>chieu_dai;
		cout<<"Nhap chieu rong: ";
		cin>>chieu_rong;
		if(chieu_dai<=0||chieu_rong<=0)
		{
			cout<<"So lieu sai!\n\n";
		}
		S=chieu_dai*chieu_rong;
}while(chieu_dai<=0||chieu_rong<=0)
4 Likes

Nếu theo DRY thì ta nên dùng while(true) :smiley:

2 Likes

Mình xin phép sửa lại chỗ này 1 chút là các giá trị đó không phải là ngẫu nhiên mà là giá trị mà chương trình khác trước đó đã để lại.
Mỗi khi tạo ra 1 biến trong chương trình 1 thì biến đó đc gán 1 địa chỉ. Khi sử dụng xong và kết thúc chương trình 1 thì giá trị của biến lưu trên địa chỉ đó vẫn còn và 1 chương trình khác khi tạo ra 1 biến khác lại cấp vào ô nhớ đó nên biến mới trong chương trình mới sẽ sử dụng giá trị cũ của chương trình cũ. Các giá trị đó gọi là giá trị rác.

Cách này ok nè nhưng mình gợi ý 1 chút là sao bạn không khởi tạo luôn giá trị bằng 0 cho chiều dài và rộng khi khai báo ạ.
Mình cũng chưa học được nhiều nhưng mình góp ý theo những gì mình hiểu ạ. Cảm ơn bạn đã đọc.

2 Likes

Bạn hiểu sai, mình đang nói tới vòng lặp while ở bên dưới chứ không nói nguyên cái chương trình. Ngoài ra, mình đã có nói “còn nó có thực sự ngẫu nhiên hay không thì mình sẽ không nói tới”, ngụ ý ở đây là nó không thực sự là giá trị random (tương đối), mình không muốn giải thích vì bạn mới học nên có nghe cũng sẽ không hiểu. Còn @nguyen2812 đã giải thích dùm bạn, đó không phải là giá trị ngẫu nhiên, đó là “giá trị rác” (garbage value). Việc vòng lặp while chạy được có thể được coi như một lỗi race condition - lỗi có xác suất xảy ra, dạng lỗi khó chịu nhất trong khoa học máy tính, lập trình.

Nó còn tùy vào việc ngôn ngữ đó có khả năng “thu gom rác” (Garbage collection) không. Những ngôn ngữ hỗ trợ khả năng này sẽ được gọi là garbage collected language (tạm dịch: Ngôn ngữ có khả năng thu gom rác, nên search tiếng Anh). Theo tiêu chuẩn thông thường thì C và C++ không có khả năng này nhưng nhiều khi mấy ông làm ra compiler lại thích bổ sung vào. C và C++ không phải là garbage collected language theo tiêu chuẩn vì C và C++ được thiết kế để “close to the metal” (có thể tạm hiểu là gần gũi với phần cứng), hay nói cách khác là nó đánh đổi mấy tính năng tiện lợi như Garbage collection để đổi lấy hiệu năng.

2 Likes

Cảm ơn bạn ạ! Ngay lúc đó mình cũng thử kiểu đó luôn rồi ạ.

Vậy trong chương trình đang viết, mình có cách nào clear toàn bộ những giá trị rác đi không? Về bản chất có phải là nó sẽ chiếm luôn 1 ô nhớ mãi mãi nếu mình không bằng cách nào đó xóa nó đi?

Gán giá trị khởi tạo cho biến trước khi dùng là được.

4 Likes

Thực ra thì giá trị rác trong C/C++ nó trở thành 1 phần tất yếu của cuộc sống rồi.

Cái này thì theo mình. Cũng tùy theo bạn nghĩ thế nào là clear các giá trị rác.

  • Nếu bạn chỉ cần tất cả các ô nhớ chứa các giá trị là 0 thì sau khi sử dụng và trước khi kết thúc chương trình thì bạn chỉ cần gán giá trị cho biến đó bằng 0. Thực ra thì cũng không có tác dụng mấy vì vùng nhớ rất rộng mà chương trình khác sử dụng lại ra giá trị rác thôi. Cách tốt nhất là gán giá trị trước khi dùng
  • Nếu muốn ô nhớ trên stack không chứa gì cả kể cả giá trị 0 thì điều này theo mình biết là không thể trong C.
    Đây là 1 bài viết trên Quora mình lượn lờ và nhặt được : Link bài viết

Để giải thích dễ hiểu hơn thì bạn tưởng tượng mỗi ô nhớ là 1 địa chỉ của 1 mảnh đất và dữ liệu sẽ là những thứ có trên mảnh đất đó. Bạn đâu thể làm cho 1 khu đất thành chân không (tức không có gì) khi mà không sử dụng. Bạn chỉ có thể báo cho chính quyền biết bạn muốn nhượng lại cho người khác thôi.
Giải thích khó hiểu quá nhỉ :man_facepalming: :worried: . Bạn cứ học tiếp đến khi học đến cấp phát động rồi quản lí bộ nhớ, vv… là tự hiểu ấy mà còn giờ thì bỏ qua cái này đi.

Theo mình biết thì RAM sử dụng các bóng bán dẫn(transistor) để lưu trữ dữ liệu và các bóng này chỉ hoạt động được khi có điện. Vì thế nếu không xóa được thì rút dây cắm ra là ok. Bí nữa thì đốt hoặc phá theo bất kì cách nào bạn biết :grin:

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