Lập trình C: Bài 5 – Cấu trúc vòng lặp
Thông báo, Bài viết đã được cập nhật chi tiết, đầy đủ và dễ hiểu hơn tại Lập trình C : Bài 6 – Vòng lặp for trong C và Lập trình C: Bài 7 – Vòng lặp while, do…while trong C
Nội dung
A.Lệnh rẽ nhánh không điều kiện
1.Lệnh break:
Thông thường lệnh break dùng để thoát khỏi vòng lặp không xác định điều kiện dừng hoặc bạn muốn dừng vòng lặp theo điều kiện do bạn chỉ định Việc dùng lệnh break để thoát khỏi vòng lặp thường sử dụng phối hợp với lệnh if. Lệnh break dùng trong for, while, do…while, switch. Lệnh break thoát khỏi vòng lặp chứa nó.
Trong bài trước chúng ta đã sử dụng lệnh break trong switch để nhảy bỏ các câu lệnh kế tiếp còn lại.
2.Lệnh goto
Lệnh goto dùng để chuyển tới một câu lệnh nào đó đứng sau nhãn đã chỉ định. Nhãn là tên hợp lệnh đứng trước lệnh mà ta cần nhảy tới. Lệnh goto kết hợp với lệnh if cũng có thể tạo ra một vòng lặp.
Cú pháp lệnh goto: goto nhan;
Cú pháp nhãn: nhan : lệnh;
#include <stdio.h> int main(){ int a, kt; tieptuc : printf("Nhap a = "); scanf("%d", &a); switch(a) { case 1: printf("Mot"); break; case 2: printf("Hai"); break; case 3: printf("Ba"); break; case 4: printf("Bon"); break; case 5: printf("Nam"); break; default: printf("Khong phai so tu 1 den 5"); } printf("\nBan muon tiep tuc? 1 de tiep tuc, 0 de dung: "); scanf("%d", &kt); if(kt) goto tieptuc; return 0; }
Tuy nhiên khi sử dụng lệnh goto bạn cần chú ý các điểm sau:
-Nếu lệnh goto và nhãn nằm trong 1 hàm thì lệnh goto chỉ được phép nhảy trong hàm đó và không được phép nhảy sang hàm khác.
-Không được dùng lệnh goto nhảy từ ngoài vào trong một khối nhưng được phép nhảy từ trong khối ra ngoài.
3.Lệnh continue
Được dùng trong vòng lặp for, while, do…while. Khi lệnh continue thi hành quyền điều khiển sẽ trao qua cho biểu thức điều kiện của vòng lặp gần nhất. Nghĩa là lộn ngược lên đầu vòng lặp, tất cả những lệnh đi sau trong vòng lặp chứa continue sẽ bị bỏ qua không thi hành.
Bây giờ chúng ta sẽ đi tìm hiểu các lệnh vòng lặp để từ đó thấy rõ hơn được vai trò của các lệnh rẽ nhánh không điều kiện
[qads]
B.Các lệnh vòng lặp
1.Lệnh for
Vòng lặp xác định thực hiện lặp lại một số lần xác định của một (hoặc một chuỗi) hành động.

Các biểu thức :
- Biểu thức 1: khởi tạo giá trị ban đầu cho biến điều khiển.
- Biểu thức 2: là quan hệ logic thể hiện điều kiện tiếp tục vòng lặp.
- Biểu thức 3: phép gán dùng thay đổi giá trịbiến điều khiển.
Cách hoạt động:
- Bước 1: Xác định giá trị của biểu thức 1
- Bước 2: Xác định giá trị của biểu thức 2 (kiểm tra điều kiện đúng hay sai tức 1 hoặc 0). Tùy vào giá trị của biểu thức 2 mà thực hiện theo 2 hướng:
- + Nếu sai (0) sẽ thoát khỏi vòng lặp
- + Nếu đung (1) sẽ thực hiện khối lệnh trong vòng for đến khi gặp dấu } ở cuối vòng for hoặc lệnh continue thì sẽ tưới bước 3.
- Bước 3: Tính giá trị biểu thức 3, sau đó quay lại bước 2.
Lưu ý:
- Biểu thức 1 bao giờ cũng chỉ được tính toán một lần khi gọi thực hiện for.
- Biểu thức 2, 3 và thân for có thể thực hiện lặp lại nhiều lần.
- Biểu thức 1, 2, 3 phải phân cách bằng dấu chấm phẩy ( ; ), các biểu thức có thể vắng mặt 1,2 hoặc cả 3 nhưng vẫn phải có dấy chấm phẩy này.
- Nếu biểu thức 2 không có, vòng for được xem là luôn luôn đúng. Muốn thoát khỏi vòng lặp for phải dùng một trong lệnh break, goto hoặc return.
- Với mỗi biểu thức có thể viết thành một dãy biểu thức con phân cách nhau bởi dấu phẩy. Khi đó các biểu thức con được xác định từ trái sang phải. Tính đúng sai của dãy biểu thức con trong biểu thức thứ 2 được xác định bởi biểu thức con cuối cùng.
- Trong thân for (khối lệnh) có thể chứa một hoặc nhiều cấu trúc điều khiển khác, vòng lặp khác.
- Khi gặp lệnh break, cấu trúc lặp sâu nhất sẽ thoát ra.
- Trong thân for có thểdùng lệnh goto để thoát khỏi vòng lặp đến vị trí mong muốn.
- Trong thân for có thể sử dụng return để trở về một hàm nào đó.
- Trong thân for có thể sử dụng lệnh continue để chuyển đến đầu vòng lặp (bỏ qua các câu lệnh còn lại trong thân).
Ví dụ về lệnh for.
Trong các ví dụ dưới đây mình sẽ thực hiện trên kiểu mảng (sẽ học ở các bài sau) nên nếu các bạn chưa rõ về mảng thì chỉ cần quan tâm tới cấu trúc lệnh for của chúng ta chứ không cần thiết quan tâm tới kiểu mảng.
VD1: Sử dụng vòng for in các số nguyên từ 1 đến 10
#include <stdio.h> int main(){ int i; for (i = 1; i <= 10; i++) { printf("%-5d", i); } return 0; }
VD2: Sử dụng vòng for in để đảo ngược mảng trong đó các biểu thức của vòng for là một dãy biểu thức con phân cách nhau bởi dấu phẩy.
#include <stdio.h> int main(){ int i, j, n = 4, a[] = {1, 3, 7, 2}; // mang a gom 4 phan tu /* Xuat mang ban dau*/ printf("Mang ban dau: "); for (i = 0; i < n; i++) { printf("%-5d",a[i]); } printf("\n"); /* Dao nguoc mang*/ for (i = 0, j = n - 1; i <= j; i++, j--) { // doi cho 2 phan tu a[i] va a[j] int temp = a[i]; a[i] = a[j]; a[j] = temp; } /* Xuat mang sau khi dao nguoc*/ printf("Mang dao nguoc: "); for (i = 0; i < n; i++) { printf("%-5d",a[i]); } printf("\n"); return 0; }
VD3: Sử dụng vòng for in để đảo ngược mảng trong đó vắng mặt biểu thức 2, ta sử dụng lệnh break để thoát khỏi vòng lặp
#include <stdio.h> int main(){ int i, j, n = 4, a[] = {1, 3, 7, 2}; // mang a gom 4 phan tu /* Xuat mang ban dau*/ printf("Mang ban dau: "); for (i = 0; i < n; i++) { printf("%-5d",a[i]); } printf("\n"); /* Dao nguoc mang*/ for (i = 0, j = n - 1; ; i++, j--) { if (i >= j) break; // doi cho 2 phan tu a[i] va a[j] int temp = a[i]; a[i] = a[j]; a[j] = temp; } /* Xuat mang sau khi dao nguoc*/ printf("Mang dao nguoc: "); for (i = 0; i < n; i++) { printf("%-5d",a[i]); } printf("\n"); return 0; }
VD4: Minh họa lệnh continue trong vòng for.
#include <stdio.h> int main(){ int i, n = 4, a[] = {1, -3, -7, 2}; // mang a gom 4 phan tu printf("Cac so duong trong mang: "); for (i = 0; i < n; i++) { if (a[i] <= 0) continue; printf("%-5d",a[i]); } return 0; }
2. Lệnh while

Ta có thể hiểu đơn giản: Trong khi biểu thức còn đúng thì làm lệnh, khi sai thì thoát
- Biểu thức: có thể là một biểu thức hoặc nhiều biểu thức con. Nếu là nhiều biểu thức con thì cách nhau bởi dấu phẩy (,) và tính đúng sai của biểu thức được quyết định bởi biểu thức con cuối cùng.
- Trong thân while (khối lệnh) có thể chứa một hoặc nhiều cấu trúc điều khiển khác.
- Trong thân while có thể sử dụng lệnh continue đểchuyển đến đầu vòng lặp (bỏqua các câu lệnh còn lại trong thân).
- Nếu biểu thức là một hằng khác không thì nó luôn đúng và vòng lặp diễn ra vô hạn. Muốn thoát khỏi vòng lặp while tùy ý có thể dùng các lệnh break, goto, return như với lệnh for.
VD: Nhập mật khẩu:
#include <stdio.h> #define PASS "nguyenvanquan7826" // dat pass int main(){ char pass[100]; /* Ham strcmp tra ve ket qua la 0 khi 2 chuoi bang nhau */ while(strcmp(pass, PASS) != 0) { printf("Nhap pass: "); gets(pass); } printf("Mat khau dung roi!"); return 0; }
3. Lệnh do while

Ta có thể hiểu đơn giản: Làm lệnh trong khi biểu thức đúng, hễ sai thì thoát.
Từ đây ta có nhận xét: vòng lặp while thì có thể không thực hiện lệnh nào nếu ngay từ ban đầu biểu thức sai, còn lệnh do while thì sẽ thực hiện lệnh ít nhất 1 lần dù biểu thức có sai ngay từ đầu.
VD:
#include <stdio.h> int main(){ do { printf("khoi lenh duoc thuc hien\n"); } while(5 > 8); return 0; }
Bài tập
Bài 1: Viết chương trình nhập vào từ bàn phím 1 dãy các số nguyên. Kiểm tra và in ra tất cả các số nguyên tố có trong dãy.
Bài 2: Viết chương trình thể hiện cuộc hội thoại của 2 người. Khi nào một trong 2 người nói goodbye thì dừng lại.
[rps-include post=”2703″ shortcodes=”false”]
Trong ví dụ của phần 2 if (kt) goto tieptuc; sao mình không thấy biểu thức so sánh mà nó vẫn đúng hả bạn
Biến kt chính là biến điều kiện đó bạn. Mặc định trong C thì 1 số nguyên khác 0 tương đuơng với đúng, số 0 là sai. Do vậy chỉ cần gọi if(kt) là được rồi.
Anh ơi, %d và %-5d khác nhau chỗ nào ạ ? Mình có thể thay thế %-5d thành %-6d hay các số khác đc không ạ ?
Cái đấu trừ biểu thị là căn lề trái, nếu không sẽ căn lề phải. Bạn thay số nào cũng đk.
Anh ơi hình như lệnh strcmp không dùng trong trong ubuntu được phải không ạ ? Em dùng Geany nó báo “strcmp was not declared in this scope”.
anh vẫn dùng mà.
em dùng trong dev C cũng bị lỗi như vậy
à code a bị thiếu khai báo #include nên nó lỗi như vậy
Ở ví dụ phần 2, printf(“\nBan muon tiep tuc? 1 de tiep tuc, 0 de dung: “); giả sử mình không sử dụng 0 hoặc 1 mà sử dụng chữ cái như c hoặc k thì mình viết như thế nào vậy anh?
Đó chỉ là lệnh in thôi. Còn lệnh nhập thì scanf bạn nhập kiểu char là đk.
scanf(“%c”,c);
Ở ví dụ phần 2, printf(“\nBan muon tiep tuc? 1 de tiep tuc, 0 de dung: “); anh cho em hỏi là tại sao chỉ nhập 0 thì nó lại dừng lại !
Vì trong điều kiện vong lặp mà bạn. Bạn xem lại cách hoạt động của vòng lặp đó là ok mà.
làm s để kết thúc 1 lệnh if v a? e làm 2 if trở lên nó cứ bị lồng vào nhau dù đã đóng ngoặc nhọn r
Vậy xem lại code của bạn thôi.
cho e hỏi code trong Turbo C có thể viết được chương trình tạo hình ảnh không? và nếu được thì lệnh Do..while làm nhiệm vụ với khoảng bao nhiêu vòng lặp?
Cái này mình cũng không rõ. Chưa thử bao giờ 😉
if (kt) goto tieptuc;
anh cho em hỏi sao ko phải là if(kt==1) goto tieptuc?
if (kt) là sao ạ @@
Trong ngôn ngữ C thì 0 có nghĩa là sai, 1 có nghĩa là đúng. Do vậy if(kt) hay if(kt == 1) là như nhau nhé.
for (i = 0, j = n-1 ; i <= j; i++, j–) {
anh comment cho cái code này với ạ, em ko hiểu 🙁
Trong vòng for này thì vẫn có 3 biểu thức ngăn cách nhau bởi dấu chấm phẩy. Nhưng mỗi biểu thức lại có nhiều lệnh:
+/ Biểu thức 1 gồm 2 lệnh khởi tạo i = 0 và j = n -1;
+/ Biểu thức 2 gồm 1 biểu thức so sánh i <= j +/ Biểu thức 3 gồm 2 lệnh là tăng i và giảm j.
anh ơi, nhưng nếu như vậy.
i=0, j =3 . i=1, j=2, i=2, j=1 thì nó đã dừng có nghĩa nó chỉ swap 2 lần sao nó lại swap đc 4 lần luôn ạ 🙁
swap 2 lần thì nó đổi được 4 số rồi. mỗi lần 2 số mà.
Ban đầu là: 1, 3, 7, 2
Lần 1: 2 3 7 1
Lần 2: 2 7 3 1
anh giải thích rõ như debug đc ko ạ 🙁 em vẫn ko hiểu tại sao nó swap đc như vậy
anh ơi có phải là i=0, j=3, thì 1 swap cho 2(tương ứng thứ tự 0 1 2 3 trong mảng), rồi i=1, j=2 thì swap tiếp 3 và 7 tương đương ( 1 2 trong mảng)
đúng ko anh @@
Đúng rồi.
%-5d là sao vậy anh
Nghĩa là dùng 5 khoảng trống để biểu diễn số nguyên và căn trái (dấu trừ)
Dùng vòng lặp để nhập vào 1 số, nếu nhập sai thì bắt nhập lại thì làm thế nào vậy, e nhập sai là nó thoát ra luôn.
Vấn đề là nhập sai thì thế nào là sai, phải có điêu kiện chứ. Gợi ý dùng vòng lặp while hoặc do-while
#include
#include
int main()
{
int a = 9, b = 1+(a++);
printf(” a = %d \t b = %d”, a,b);
return 0;
}
Cho em hỏi sao in ra lại cho a = 10 ạ.
Ah vì trong code của bạn có a++. a++ sẽ tương đương với a = a + 1 nên giá trị của a tăng từ 9 lên 10 là đúng rồi.
em chào anh.anh ơi cho em hỏi với ạ.em không hiểu n trong for(i=0;i<n;i++)
nghĩa là như nào thế ạ.anh có thể giải đáp hộ em không ạ.Em cam ơn
n là 1 số để giới hạn biến chạy i. khi i < n thì vòng lặp còn hoạt động, i >= n thì vòng lặp dừng lại.
anh cho e hỏi i thay vì dùng
int temp = a[i];
a[i] = a[j];
a[j] = temp;
em dùng mỗi a[i] = a[j]; thôi kết quả là 2 7 7 2 thay vì 2 7 3 1 tại sao vậy ạ?
Tại vì dùng như thế thì không thể hoán vị được 2 số. Em tưởng tượng có 2 cốc nước: nước chanh và cafe, hoán đổi 2 cốc như thế nào?
/*
——————————–
Failed to execute “F:\Nhat (IT)\Bai 5 Cau truc vong lap\Vidu 5.2.1.exe”:
Error 216: This version of %1 is not compatible with the version of Windows you’
re running. Check your computer’s system information to see whether you need a x
86 (32-bit) or x64 (64-bit) version of the program, and then contact the softwar
e publisher.
Press any key to continue . . . */
Ad cho em hỏi cách khắc phục lỗi này với ạ
Hình như bản dev-c của bạn không tương thích với win. Bạn kiểm tra lại xem nếu win 32 bit thì dùng 32 bit nhé.
Vâng, cảm ơn anh Nguyenvanquan7826, em khắc phục được rồi ạ
// Baitap 5.3 Viet chuong trinh tinh tong nghich dao cua N so nguyen dau tien theo cong thuc T=1+1/2+1/3+…+1/N
#include
int main (){
int i,n;
float s;
s=0;
printf (“Nhap vao so N la: “);
scanf (“%-5d”,&n);
for (i=1;i<=n;i++){
s+=(float)1/i;
}
printf ("Tong cua day so la: %0.2f",s);
return 0;
}
Các anh chị cho em hỏi, e tự viết code và chạy chương trình trên, nhưng em nhập thử n= 2 thi chương trình trả về kết quả là 15.40 không phải là 1.50, em chưa biết lỗi ở điểm nào, mong các anh chị chỉ dùm em. E xin cảm ơn!
Lệnh nhập n sao lại có %-5d?
Cảm ơn anh Quân nhiều nhé, em tính được rồi ạ!
Tính đúng sai của dãy biểu thức con trong biểu thức thứ 2 được xác định bởi biểu thức con cuối cùng.
–Cho mình hỏi, bạn có ví dụ nào cho dòng chú ý trên không ạ???
VD: for (int i = 0, j = 0; i < 3, j < 8 ; i++, j++) thì điều kiện dừng sẽ phụ thuộc vào j < 8 chứ không phải i < 3.
A cho e hỏi là…khi nào thì dùng for ạ
khi bạn cần làm công việc gì đó lặp đi lặp lại nhiều lần, đặc biệt là biết trước số lần lặp.