tuần 3 cấu trúc lặp

40
Tuần 3 Cấu trúc lặp

Upload: independent

Post on 01-Dec-2023

0 views

Category:

Documents


0 download

TRANSCRIPT

Tuần 3

Cấu trúc lặp

Nội dung trình bày

• Toán tử một ngôi

• Cấu trúc lặp

• Câu lệnh while

• Biến điều khiển

• Lệnh break và lệnh continue

• Một số loại vòng lặp thường gặp

Toán tử một ngôi

• Toán tử tăng 1 đơn vị ++ i++ : Tăng i thêm 1 đơn vị. Nếu i++ nằm trong một biểu

thức thì tính toán biểu thức trước sau đó mới tăng i.

++i : Tăng i thêm 1 đơn vị. Nếu ++i nằm trong một biểu thức thì tăng i trước rồi sau đó mới tính toán biểu thức.

• Toán tử giảm 1 đơn vị -- i-- : Giảm i đi 1 đơn vị. Nếu i-- nằm trong một biểu thức

thì tính toán biểu thức trước sau đó mới giảm i.

--i : Giảm i đi 1 đơn vị. Nếu --i nằm trong một biểu thức thì giảm i trước rồi sau đó mới tính toán biểu thức.

Toán tử một ngôi

• Ví dụ:

int i = 5;

int a = 2 + i++; // a = 7; i = 6

int b = ++i + 3; // b = 10; i = 7

int c = 2 + i--; // c = 9; i = 6

int d = --i + 3; // d = 8; i = 5

Toán tử một ngôi

• Bài tập: Hãy cho biết giá trị cuối cùng của biến a và b sau khi biểu thức sau được tính toán:

int a = 1, b= 2;

a = a++ + b++;

b = a++ + ++b;

a = ++a + b++;

b = ++a + ++b;

Các cấu trúc đã học

• Cấu trúc tuần tự : Các câu lệnh được thực hiện lần lượt.

• Cấu trúc rẽ nhánh (if/switch) : Các câu lệnh được thực hiện phụ thuộc vào điều kiện (hay biểu thức logic)

Cấu trúc lặp

• Cấu trúc lặp : Các câu lệnh được thực hiện lặp đi lặp lại.

• Khái niệm vòng lặp: Sự lặp lại của một dãy các bước trong chương trình gọi là vòng lặp (loop) – Ví dụ:

• Để hiển thị 100 kí tự ‘*’ ra màn hình ta chỉ cần lặp đi lặp lại 100 lần lệnh in ký tự ‘*’ ra màn hình.

• Để tính lương cho tất cả các công nhân trong một công ty ta chỉ cần lặp đi lặp lại câu lệnh tính lương đối với từng công nhân trong công ty.

• Trong C++ có 3 loại cấu trúc lặp tương ứng với 3 câu lệnh lặp: while, for và do-while

Câu lệnh while

• Cú pháp: while (b/t logic) <câu lệnh>; // hoặc <khối lệnh> …….

• Quá trình thực hiện của while – Kiểm tra b/t logic

• Nếu <b/t logic> đúng thì thực hiện <câu lệnh> hay <khối lệnh>. Sau khi thực hiện xong <câu lệnh> hay <khối lệnh> lại quay lại kiểm tra <b/t logic>…

• Nếu <b/t logic> sai thì không thực hiện <câu lệnh> hay <khối lệnh> mà thực hiện các lệnh nằm bên dưới <câu lệnh> hay <khối lệnh>.

Câu lệnh while

• Ví dụ 1: Lệnh sau in ra vô số câu “Chao ban” trên màn hình và mỗi câu nằm trên một dòng. while (2 < 3)

cout << “Chao ban” << endl;

• Ví dụ 2: Lệnh sau không in được dữ liệu ra màn hình. while (1 < 0)

cout << “Hien thi du lieu” << endl;

Câu lệnh while

• Bài tập 1: Bạn hãy cho biết kết quả của chương trình sau: int i = 2; while (i < 5) cout << i << endl;

• Bài tập 2: Bạn hãy cho biết kết quả của chương trình sau: int i = 2; while (i++ < 5) cout << i << endl;

Câu lệnh while

• Bài tập 3: Bạn hãy cho biết kết quả của chương trình sau: int i = 2; while (++i < 5) cout << i << endl;

• Bài tập 4: Bạn hãy cho biết kết quả của chương trình sau:

int i = 2; while (++i < 5) { cout << i << endl; i--; }

Biến điều khiển

• Để tránh trường hợp câu lệnh while bị lặp vô hạn, ta nên sử dụng một biến để xác định điều kiện dừng cho vòng lặp (biến này gọi là biến điều khiển) – Biến điều khiển này do chính người lập trình tự định nghĩa

– Giá trị của biến điều khiển sẽ quyết định vòng lặp có được thực hiện tiếp tục hay không

• 3 bước cần thực hiện với biến điều khiển – Khởi tạo giá trị

– Kiểm tra điều kiện

– Cập nhật lại giá trị

Biến điều khiển

• Ví dụ 1: In ra màn hình 100 kí tự ‘*’ – Phân tích khái quát:

• Ta cần lặp đi lặp lại 100 lần lệnh in ký tự ‘*’ ra màn hình

– Phân tích chi tiết: • Sử dụng biến đếm (đây là biến điều khiển) để đếm số lần đã

in ký tự ‘*’ ra màn hình.

• Ban đầu biến đếm = 0 (vì lúc này ta chưa in ký tự nào ra màn hình)

• Ta sẽ so sánh biến đếm với 100, chừng nào biến đếm còn nhỏ hơn 100, ta còn thực hiện các công việc sau:

– In ký tự ‘*’ ra màn hình

– Tăng biến đếm lên 1 đơn vị

Biến điều khiển

• Ví dụ 1 (tiếp)

– Cài đặt: dem = 0; while (dem < 100) {

cout<<‘*’;

dem = dem + 1;

}

Biến điều khiển

• Ví dụ 1 (tiếp): – Giải thích:

dem = 0; // Khởi tạo biến dem

Kiểm tra điều kiện (dem < 100) là đúng, vậy

– In ra kí tự ‘*’

– Tăng biến dem lên 1, như vậy dem = 1

Kiểm tra điều kiện (dem < 100) là đúng, vậy

– In ra kí tự ‘*’

– Tăng biến dem lên 1, như vậy dem = 2

Kiểm tra điều kiện (dem < 100) là đúng, vậy – In ra kí tự ‘*’ – Tăng biến dem lên 1, như vậy dem = 99

Kiểm tra điều kiện (dem < 100) là đúng, vậy – In ra kí tự ‘*’ – Tăng biến dem lên 1, như vậy dem = 100

Kiểm tra điều kiện (dem < 100) là sai, vậy – Ra khỏi vòng lặp

Biến điều khiển

• Ví dụ 1 (tiếp):

– Có cách nào viết chương trình ngắn gọn hơn hay không ?

Biến điều khiển

• Ví dụ 2: Tính lương cho 10 công nhân dựa trên số sản phẩm (mỗi sản phẩm được trả 5 nghìn đồng)

– Phân tích khái quát:

• Ta cần lặp đi lặp lại 10 lần (tương ứng với 10 công nhân) các công việc sau:

– Nhập số sản phẩm làm được

– Tính và in lương của lên màn hình

Biến điều khiển

• Ví dụ 2 (tiếp): – Phân tích chi tiết:

• Sử dụng biến đếm (đây là biến điều khiển) để đếm số công nhân đã được tính lương.

• Ban đầu biến đếm = 0 (vì lúc này ta chưa tính lương của công nhân nào)

• Ta sẽ so sánh biến đếm với 10, chừng nào biến đếm còn nhỏ hơn 10, ta còn thực hiện các công việc sau:

– Nhập số sản phẩm

– Tính lương theo công thức: Lương = Số sản phẩm * 5

– In lương lên màn hình

– Tăng biến đếm lên 1 đơn vị

Biến điều khiển

• Ví dụ 2 (tiếp):

– Sơ đồ minh họa

true

dem_cn < 10 false

Đọc dữ liệu

Tính và hiển thị lương

Tăng giá trị biến dem_cn

while

Biến điều khiển

• Ví dụ 2 (tiếp): – Cài đặt: dem_cn = 0;

while (dem_cn < 10)

{

cout<<“So san pham lam duoc : ";

cin>>SoSP;

Luong = SoSP * 5;

cout<<“Luong cua cong nhan la : "<<Luong<<" nghin dong"<<endl;

dem_cn++;

} // end while

Biến điều khiển

• Bài tập 1: Viết chương trình in ra các số từ -10 đến 10, mỗi số trên 1 dòng.

• Bài tập 2: Viết chương trình in ra các số từ 1 đến 20 và căn bậc 2 của chúng, mỗi cặp giá trị trên 1 dòng.

Lệnh break

• Ta đã biết lệnh break được sử dụng để thoát ra khỏi lệnh switch

• Ngoài ra lệnh break còn được sử dụng để thoát ra khỏi vòng lặp bất kỳ, ngay cả khi điều kiện dừng của vòng lặp chưa thỏa mãn

• Ví dụ: int i = 0; while (0 == 0) { cout << i << endl; if (i == 5) break; i++; }

Lệnh continue

• Lệnh continue được sử dụng để chuyển điều khiển về kiểm tra lại điều kiện (về đầu vòng lặp) và bỏ qua tất cả các câu lệnh nằm dưới nó trong vòng lặp.

• Ví dụ: int i = 0; while (i < 5) { cout << i << endl; if (i == 3) continue; i++; }

Một số loại vòng lặp thường gặp

• Vòng lặp thực hiện các công việc giống nhau

• Vòng lặp cộng dồn

• Vòng lặp không biết trước số lần lặp

• Vòng lặp nhập dữ liệu tùy biến

• Vòng lặp lồng nhau

Vòng lặp thực hiện các công việc giống nhau

• Tại mỗi lần lặp vòng lặp lại thực hiện những câu lệnh giống hệt nhau. • Ví dụ: Tính điểm trung bình cho n sinh viên dựa trên điểm tin và điểm toán int iDemSV = 0; while (iDemSV++ < n) { float fDiemTin, fDiemToan; cout << "Nhap diem tin va diem toan: "; cin >> fDiemTin >> fDiemToan; cout << "Diem trung binh la: “; cout << (fDiemTin + fDiemToan) / 2 << endl << endl; }

Vòng lặp cộng dồn

• Vòng lặp công dồn là loại vòng lặp mà dữ liệu chung có thể bị thay đổi sau mỗi lần lặp.

• Mở rộng bài toán trên bằng cách đưa ra màn hình điểm trung bình chung của cả n sinh viên.

• Phân tích bài toán – Dữ liệu vào :

• Số lượng sinh viên • Điểm toán và điểm tin mà từng sinh viên nhận được

– Dữ liệu ra : • Điểm trung bình của từng sinh viên • Điểm trung bình chung của tất cả các sinh viên

Vòng lặp cộng dồn

• Thiết kế thuật toán – Nhập số lượng sinh viên

– Khởi tạo giá trị tổng điểm trung bình cho tất cả các sinh viên là 0

– Với mỗi sinh viên • Nhập điểm toán và điểm tin mà sinh viên nhận được

• Tính điểm trung bình của sinh viên

• Hiển thị điểm trung bình của sinh viên

• Thêm vào tổng điểm trung bình số điểm trung bình của sinh viên vừa tính

– Tính điểm trung bình chung của tất cả các sinh viên

– Hiển thị điểm trung bình chung của tất cả các sinh viên

Vòng lặp cộng dồn

• Làm mịn thuật toán – Tổng Điểm Trung Bình = 0 ; – Đếm = 0; – Trong khi (Đếm < Số Sinh Viên)

• Nhập Điểm Toán và Điểm Tin • Tính Điểm Trung Bình

– Điểm Trung Bình = (Điểm Toán + Điểm Tin) / 2

• Hiển thị Điểm Trung Bình • Thêm vào Tổng Điểm Trung Bình

– Tổng Điểm Trung Bình += Điểm Trung Bình ;

– Tính Điểm Trung Bình Chung • Điểm Trung Bình Chung = Tổng Điểm Trung Bình / Số Sinh Viên

– Hiển thị Điểm Trung Bình Chung

Vòng lặp cộng dồn

• Cài đặt:

float fTongDTB = 0; int iDem = 0; while (iDem++ < iSoSV) { cout << “Nhap diem Toan, Tin: “; cin >> fToan >> fTin; float fDTB = (fToan + fTin) / 2; cout << “Diem TB la: “ << fDTB << endl << endl; fTongDTB += fDTB; } float fDTBChung = fTongDTB / iSoSV; cout << “Diem TB chung la: “ << fDTBChung << endl;

Vòng lặp không biết trước số lần lặp

• Vòng lặp không biết trước số lần lặp là loại vòng lặp chỉ dừng lại khi một điều kiện nào đó liên quan đến dữ liệu được thỏa mãn (dữ liệu này không phải là biến điều khiển như đã đề cập ở trên)

Vòng lặp không biết trước số lần lặp

• Ví dụ: Mô phỏng hiện tượng rơi tự do của một vật. Lập một bảng cho biết độ cao của vật sau mỗi giây

• Phân tích : – Input : Độ cao ban đầu của vật

– Output : Bảng độ cao sau mỗi giây

– Trong khi vật rơi, độ cao mà nó đã rơi qua được tính theo công thức : khoảng cách = ½ gt2 (g = 9.80665)

– Như vậy sau một thời gian t, độ cao của vật so với mặt đất là : Độ cao ban đầu - độ cao đã rơi sau thời gian t

Vòng lặp không biết trước số lần lặp

• Thiết kế thuật toán – Nhập dữ liệu độ cao ban đầu

– Lập bảng cho biết độ cao của vật sau mỗi giây

• Làm mịn bước lập bảng – Khởi tạo độ cao hiện tại của vật là độ cao ban đầu

– Khởi tạo thời gian là 0

– Trong khi (độ cao hiện tại > 0) • Hiển thị thời gian và độ cao hiện tại

• Tăng thời gian lên 1 (giây)

• Tính lại độ cao hiện tại

Vòng lặp không biết trước số lần lặp

• Cài đặt: #include <iostream> #include <iomanip> using namespace std; void main() { // Khai bao hang va bien const float g = 9.80655; float do_cao_ban_dau; float thoi_gian; float do_cao_hien_tai; // Nhap du lieu cout<<"Nhap do cao ban dau cua vat : “; cin>>do_cao_ban_dau;

Vòng lặp không biết trước số lần lặp

// Lap bang do cao cout<<setw(10)<<"Thoi gian"<<setw(8)<<"Do cao"<<endl; thoi_gian = 0; do_cao_hien_tai = do_cao_ban_dau; cout.setf(ios::fixed); cout.precision(2); while (do_cao_hien_tai > 0) { cout<<setw(10)<<thoi_gian<<setw(8)<<do_cao_hien_tai<<endl; thoi_gian ++; do_cao_hien_tai = do_cao_ban_dau - 0.5*g*thoi_gian*thoi_gian; } cout<<endl; cout<<"CHAM DAT !!!"; }

Vòng lặp không biết trước số lần lặp

• Kiểm tra chương trình Nhap do cao ban dau cua vat : 100

Thoi gian Do cao

0.00 100.00

1.00 95.10

2.00 80.39

3.00 55.87

4.00 21.55

CHAM DAT !!!

Vòng lặp nhập dữ liệu tùy biến

• Vòng lặp nhập dữ liệu tùy biến là loại vòng lặp mà người sử dụng ra quyết định vòng lặp có được tiếp tục nữa hay không.

Vòng lặp nhập dữ liệu tùy biến

• Ví dụ 1: Tính tổng giá trị các số nguyên dương nhập từ bàn phím. Các giá trị được nhập vào liên tục cho đến khi gặp giá trị -1 là kết thúc nhập.

tong = 0;

cout<<“Nhap so :”; cin>>so;

while (so != -1)

{

tong = tong + so;

cout<<“Nhap so :”; cin>>so;

}

cout<<“Tong la :”<<tong;

Vòng lặp nhập dữ liệu tùy biến

• Ví dụ 2: Tính tổng các số dương nhập từ bàn phím, sau mỗi lần nhập cho phép người dùng lựa chọn nhập tiếp hay không.

tong = 0; nhap_tiep = true; while (nhap_tiep == true) { cout<<“Nhap so :”; cin>>so; tong = tong + so; cout<<“Co tiep tuc khong (c/k) ?”; cin>>tra_loi; nhap_tiep = (tra_loi == ‘c’ || tra_loi == ‘C’); } cout<<“Tong la :”<<tong;

Vòng lặp while lồng nhau

• Vòng lặp while lồng nhau nghĩa là trong vòng lặp while lại chứa một vòng lặp while khác.

• Ta lồng các vòng lặp while với nhau để giải quyết một số lớp bài toán cần phải duyệt nhiều chiều cùng một lúc.

• Ví dụ: Bài toán duyệt ma trận, ta cần phải dùng 2 vòng lặp lồng vào nhau để duyệt.

Vòng lặp while lồng nhau

• Ví dụ: Hiển thị lên màn hình n dấu * trên n dòng

int i = 1; while (i++ <= n) { int j = 1; while (j++ <= n) cout << '*'; cout << endl; }