Các câu lệnh điều khiển gồm có : • câu lệnh rẽ nhánh : if...else ; switch • câu lệnh nhảy không điều kiện • câu lệnh vòng lặp • câu lệnh hỗ trợ như break, continue... Nếu trong khối lệnh
Trang 1Ch−¬ng V CÁC CÂU LỆNH ĐIỀU KHIỂN
Thông thường trong một chương trình, các câu lệnh được thực hiện tuần tự từ trên xuống Tuy nhiên có nhiều khi ta lại muốn thay đổi trật tự trên nhờ sử dụng các câu lệnh điều khiển chương trình Các câu lệnh điều khiển có thể làm cho các câu lệnh được thực hiện nhiều lần hoặc không lần nào cả
Các câu lệnh điều khiển gồm có :
• câu lệnh rẽ nhánh : if else ; switch
• câu lệnh nhảy không điều kiện
• câu lệnh vòng lặp
• câu lệnh hỗ trợ như break, continue
I Câu lệnh if else :
I.1 Các dạng của câu lệnh if :
Dạng 1 : if (biểu thức) /* không có dấu chấm phẩy ở đây*/
lệnh_1;
Dạng 2 : if (biểu thức)
lệnh_1;
else lệnh_2;
biểu thức
khối lệnh 1 T
F
Trang 2Dạng 1 : nếu biểu thức có giá trị khác 0 (TRUE) thì thực hiện khối lệnh 1, nếu bằng 0 (FALSE) thì tiếp tục thực hiện lệnh tiếp theo sau lệnh if
Dạng 2 : nếu biểu thức có giá trị khác 0 (TRUE) thì thực hiện khối lệnh 1, nếu bằng 0 (FALSE) thì thực hiện khối lệnh 2
Biểu thức không nhất thiết phải là biểu thức so sánh mà có thể là biểu thức số học
Ví dụ : tìm số lớn nhất và nhỏ nhất trong 2 số nhập từ bàn phím
#include <stdio.h>
#include <conio.h>
main()
{
float x,y,min,max;
printf(“Nhap so thuc thu nhat:”);scanf(“%f”,&x);
printf(“Nhap so thuc thu hai :”);scanf(“%f”,&y);
if ( x<y )
{ min = x;
max = y;
}
else
{ min = y;
max = x;
}
printf(“\n Gia tri lon nhat = %f, Gia tri nho nhat = %f”,max, min);
getch();
return 0;
}
Ta có thể thay thế lệnh trên bằng lệnh :
min=(x<y)? x:y;
max=(x>y)? x:y;
I.2 Sự lồng nhau giữa các câu lệnh if:
Các câu lệnh if có thể lồng nhau : trong khối lệnh của câu lệnh if này có thể có câu lệnh if khác Để tránh nhầm lẫn ta nên sử dụng dấu đóng mở khối lệnh
khối lệnh 1 T
F
Trang 3Nếu số từ khóa if bằng số từ khóa else thì ta có tương ứng từng cặp if-else
Nếu số từ khóa if nhiều hơn số từ khóa else thì else được gắn với if liền trước nó
Ví dụ :
if (n>0)
if (a>b)
z=a;
else z=b;
Như vậy else sẽ gắn liền với if thứ hai
Để chương trình trong sáng, ta cần tuân thủ :
• Ta nên sử dụng cặp dấu {} để chắc chắn không nhầm lẫn
• Các câu lệnh, khối lệnh nằm trong một câu lệnh if nằm dịch về bên phải
• Các câu lệnh, khối lệnh cùng cấp thì viết thẳng cột
• Điểm đầu và điểm cuối của khối lệnh phải nằm thẳng cột
Ví dụ :
if (n>0)
if(a>b)
z=a;
tương đương với :
if ((n>0)&&(a>b))
z=a;
I.3 else if:
if (biểu thức 1)
khối lệnh 1;
else if (biểu thức 2)
khối lệnh 2;
else if ( biểu thức n)
khối lệnh n;
else khối lệnh n+1;
Đối với câu lệnh này :
• Chỉ có 1 trong n+1 khối lệnh được thực hiện
• Nếu biểu thức i là biểu thức đầu tiên khác 0 (TRUE) thì khối lệnh i được thực hiện
• Nếu cả n biểu thức đều bằng 0 (FALSE) thì khối lệnh n+1 được thực hiện
Ví dụ : giải phương trình bậc 2
#include <stdio.h>
#include <conio.h>
#include <math.h>
main()
{
Trang 4float a,b,c,delta;
printf(“\nNhap vao 3 he so:”);
scanf(“%f%f%f”,&a,&b,&c);
if (a==0)
if (b==0)
if (c==0)
printf(“\nPhuong trinh dung voi moi x”);
else printf(“\nPhuong trinh vo nghiem!”);
else printf(“\nPhuong trinh co 1 nghiem x: %f”,(-c) / b);
else
{
delta=b*b-4*a*c;
if (delta<0.0)
printf(“\nPhuong trinh vo nghiem”);
else if (delta==0.0)
printf(“\nPhuong trinh co mot nghiem kep : x = %f”,-b/(2*a));
else { printf(“\nPhuong trinh co hai nghiem phan biet :”);
printf(“\nx1 = %f”, (-b+sqrt(delta))/(2*a));
printf(“\nx2 = %f”, (-b-sqrt(delta))/(2*a));
}
}
getch();
return 0;
}
II Câu lệnh switch:
Lệnh if chỉ cho phép ta chọn một trong hai phương án tùy theo biểu thức điều kiện Tuy nhiên đôi khi ta cần phải lựa chọn 1 trong nhiều phương án khác nhau Để thuận tiện ta sẽ dùng câu lệnh switch:
switch (biểu thức)
{
case hằng1 : [ khối lệnh 1 ; ]
case hằng2 : [ khối lệnh 2 ; ]
case hằngn : [ khối lệnh n ; ]
[default : khối lệnh n+1 ; ]
}
Trong đó :
biểu thức: là biểu thức nguyên bất kì
Các hằng i phải có giá trị khác nhau
Các khối lệnh i và thành phần default là không bắt buộc
• Sự hoạt động của câu lệnh switch :
Trang 5Máy sẽ so sánh biểu thức với các hằng i theo thứ tự từ trên xuống Khi biểu thức có giá trị bằng hằng i thì khối lệnh i được thực hiện Nếu trong khối lệnh đó không có lệnh nhảy thì sẽ thực hiện tiếp tục các khối lệnh bên dưới mà không cần so sánh tiếp Nếu trong khối lệnh đó có lệnh break thì sẽ thoát ra khỏi câu lệnh switch Khi biểu thức có giá trị khác với tất cả hằng i thì sẽ thực hiện khối lệnh n+1 (nếu có)
Khi biểu thức bằng với hằng i, để sau khi thực hiện xong khối lệnh i chương trình sẽ thoát ra ngoài câu lệnh switch sớm hơn ta có thể dùng lệnh break Ta cũng có thể sử dụng lệnh goto để nhảy ra khỏi câu lệnh switch (ta không nên dùng lệnh goto)
Ví dụ :
#include <stdio.h>
#include <conio.h>
main()
{
char ch;
printf(“\n Nhap 1 ki tu:”);
scanf(“%c”,&ch);
switch (ch)
{
case ‘A’ : printf(“\nChu A”);
break;
case ‘B’ : printf(“\nChu B”);
break;
case ‘C’ : printf(“\nChu C”);
break;
default : printf(“\nKhong phai cac chu A,B,C”);
}
getch();
return 0;
}
• Nhiều giá trị case trong một trường hợp :
Máy sẽ tiếp tục làm việc khi chưa gặp lệnh thoát, vì vậy ta có thể sắp xếp để có nhiều giá trị case trong một trường hợp
Ví dụ :
#include <stdio.h>
#include <conio.h>
main()
{
int n;
printf(“Nhap diem:”);
scanf(“%d”,&n);
Trang 6switch (n)
{ case 0:
case 1:
case 2:
case 3:
case 4: printf(“loại kém”);break;
case 5:
case 6: printf(“loại trung bình”);break;
case 7:
case 8: printf(“loại giỏi”);break;
default: printf(“loại giỏi”);
} getch();
return 0;
}
Trong C++ ta có thể viết như sau :
#include <stdio.h>
#include <conio.h>
main()
{
int n;
printf(“Nhap diem:”);
scanf(“%d”,&n);
switch (n)
{ case 0,1,2,3,4: printf(“loại kém”);break;
case 5,6: printf(“loại trung bình”);break;
case 7,8: printf(“loại giỏi”);break;
default: printf(“loại giỏi”);
} getch();
return 0;
}
Ta nên sử dụng default cho dù không bao giờ xảy ra trường hợp đó: ta dùng default để kiểm tra xem có thể có lỗi hay không bằng cách đặt một thông báo lỗi ở đó, từ đó ta dễ gỡ rối III Câu lệnh for:
Để thực hiện các công việc lặp đi lặp lại hay làm việc với các phần tử mảng, nếu ta viết từng lệnh một thì sẽ không hiệu quả
• Dạng :
for([ các biểu thức khởi tạo ] ; [ biểu thức điều kiện ] ; [ biểu thức thay đổi điều kiện ])
Trang 7công việc ; /* đây là thân của chu trình */
• Sự hoạt động của câu lệnh for :
1 Thực hiện biểu thức khởi tạo
2 Kiểm tra biểu thức điều kiện
- nếu biểu thức điều kiện đúng thì thực hiện công việc bên trong chu trình for
- nếu biểu thức điều kiện sai thì thoát ra khỏi lệnh for
3 Tính biểu thức 3, quay trở lại bước 2
Ví dụ : Để đưa ra màn hình các số từ 1 đến 10, mỗi số trên một dòng :
#include <stdio.h>
#include <conio.h>
main()
{
int i;
for(i=1;i<=10;i++)
printf(“\n%d”,i);
getch();
return 0;
}
Ví dụ :
#include <stdio.h>
#include <conio.h>
main()
{
Biểu thức khởi tạo
Biểu thức điều kiện
Thực hiện công việc
Thay đổi điều kiện
T
F
Trang 8int i,n,sohang,tong=0;
printf(“\nNhap n:”);
scanf(“%d”,&n);
printf(“\nNhap vao %d so nguyen :”,n);
for(i=1;i<=n;i++)
{ printf(“\nSo thu %d : ”,i);
scanf(“%d”,&sohang);
tong+=sohang;
} printf(“\nTong = %d”,tong);
getch();
return 0;
}
Các biểu thức trong ngoặc vuông có thể có, có thể không nhưng các dấu chấm phẩy, ngoặc đơn bắt buộc phải có mặt Các biểu thức cùng loại được ngăn cách nhau bởi dấy phẩy
Với C++ ta có thể khai báo biến tạm thời ở một khối lệnh {} Trong vòng lặp for có thể khai báo biến trong biểu thức đầu tiên của biểu thức khởi tạo
Khi biểu thức 2 vắng mặt thì nó xem như luôn đúng Biểu thức 2 có thể gồm nhiều biểu thức nhưng tính đúng sai của nó là tính đúng sai của biểu thức cuối cùng
Để ra khỏi vòng lặp ta dùng các lệnh break, goto hoặc return trong thân chu trình
Ví dụ : vòng lặp for sau đây không có biểu thức thay đổi điều kiện:
for(count=0;count<10;)
printf(“\n%d”,count++);
Thậm chí ta có thể viết vòng lặp for không có cả ba biểu thức trên Ta cũng có thể tạo vòng lặp for không có câu lệnh nào trong vòng lặp, mọi công việc đã được thực hiện trong câu lệnh for Khi đó câu lệnh rỗng sẽ là dấu chấm phẩy đứng một mình trên một dòng Tuy nhiên
ta không nên làm như vậy
• Các vòng for lồng nhau :
Phía trong các thân của vòng for có thể có những vòng for khác
Ví dụ :
for(i=1;i<10;i++)
{ for(j=1;j<10;j++)
printf(“%3d”,i+j);
printf(”\n”);
}
Khi gặp lệnh break trong vòng lặp for thì máy sẽ ra khỏi vòng lặp for sâu nhất chứa lệnh này
Trang 9IV Câu lệnh while:
• Dạng :
while (biểu thức)
công việc; /* thân chu trình*/
Dấu ngoặc bao quanh biểu thức là bắt buộc
• Sự hoạt động của câu lệnh while :
1 Kiểm tra biểu thức
- Nếu biểu thức đúng thì chuyển sang bước 2
- Nếu biểu thức sai thì thoát khỏi vòng lặp
2 Thực hiện công việc
3 Quay lại bước 1
Ví dụ : Để đưa ra màn hình các số từ 1 đến 10, mỗi số trên một dòng :
#include <stdio.h>
#include <conio.h>
main()
{
int i=1;
while ( i<=10)
{ printf(“\n%d”,i);
i++;
}
getch();
return 0;
}
Ở đây ta nhớ phải tăng giá trị của biến i vì nếu không thì vòng lặp sẽ được thực hiện mãi mãi vì lúc nào điều kiện cũng được thỏa mãn
biểu thức
công việc
T
F
Trang 10Ví dụ :
#include <stdio.h>
#include <conio.h>
main()
{
int n,tong=0,i=1;
while ( i<=10)
{ printf(“\nNhap so thu %d : ”,i);
scanf(“%d”,&n);
tong+=n;
i++;
}
printf(“\nTong la : %d”,tong);
getch();
return 0;
}
Ví dụ :
#include <stdio.h>
#include <conio.h>
main()
{
int n,i=1;
long luythua=1;
printf(“\nNhap n:”);
scanf(“%d”,&n);
while ( i<=10)
{ luythua*=n;
i++;
}
printf(“\n%d luy thua 10 = : %ld”,n,luythua);
getch();
return 0;
}
Ví dụ : kiểm tra số nguyên n có phải là số nguyên tố không
int k=2;
while (n%k && k*k<=n) k++;
if(k*k>n) printf(“\nDay la so nguyen to”);
Ví dụ : Tính ex≈1+x/1!+x2/2!+ +xn/n!
#include <stdio.h>
#include <conio.h>
#include <math.h>
Trang 11#define EPS 1e-9
void main()
{
float x, tong=0, sh=1, n=0;
printf(“Nhap gia tri x=”);
scanf(“%f”,&x);
while (sh>EPS)
{ tong+=sh;
n++;
sh*=x/n;
}
printf(“\ntong=%.10f”,tong);
printf(“\nepx(x)=%.10f”, exp(x));
getch();
return 0;
}
Cũng tương tự như for, vòng lặp while cũng có thể lồng vào nhau
Ta có thể viết :
while(1)
côngviệc;
Tất nhiên, trong côngviệc phải có lệnh để thoát ra khỏi vòng lặp vô hạn này
while(string[i]) /* trong khi string[i]!=0 : chưa tới cuối xâu */
{
}
V Câu lệnh do while:
• Dạng :
do
công việc ; /* thân chu trình */
while (biểu thức);
biểu thức công việc
F
T
Trang 12• Sự hoạt động của câu lệnh do while :
1 Thực hiện công việc
2 Kiểm tra biểu thức :
- Nếu đúng thì quay trở lại bước 1
- Nếu sai thì thoát khỏi vòng lặp
Đối với vòng lặp for và while, đầu tiên phải kiểm tra biểu thức điều kiện vì vậy có thể không thực hiện công việc trong chu trình lần nào cả Đối với vòng lặp do while thì biểu thức điều kiện được kiểm tra sau nên công việc trong chu trình được thực hiện ít nhất một lần
Ví dụ : Để đưa ra màn hình các số từ 1 đến 10, mỗi số trên một dòng :
#include <stdio.h>
#include <conio.h>
main()
{
int i=1;
do
{ printf(“\n%d”,i);
i++;
}
while ( i<=10);
getch();
return 0;
}
Ví dụ :
#include <stdio.h>
#include <conio.h>
main()
{
int n;
do
{ printf(“\nNhap mot so duong : ”);
scanf(“%d”,&n);
printf(“\nBan da nhap so : %d ”,n);
}
while ( n<=0) ;
printf(“\nDung so duong roi ! ”);
getch();
return 0;
}
Trang 13VI Các lệnh rẽ nhánh không điều kiện : break, continue, goto :
VI.1 Lệnh break, continue:
Lệnh break có tác dụng kết thúc toán tử điều khiển đang thực hiện Lệnh break được sử dụng trong các vòng lặp, khi gặp lệnh này máy sẽ thoát ra khỏi vòng lặp Trường hợp các vòng lặp lồng nhau thì khi gặp lệnh break, máy sẽ thoát ra khỏi vòng lặp trong cùng nhất
Trái với lệnh break, continue dùng để bắt đầu một vòng mới của chu trình mà không thực hiện phần còn lại của chu trình Khi gặp lệnh continue bên trong thân chu trình của vòng lặp for, máy sẽ chuyển tới bước thực hiện biểu thức thay đổi điều kiện Khi gặp lệnh continue bên trong thân chu trình của vòng lặp while, do while , máy sẽ chuyển tới bước kiểm tra biểu thức điều kiện
Ví dụ : Dùng lệnh break để thoát ra khỏi vòng lặp sớm
#include <stdio.h>
#include <conio.h>
main()
{
int i;
for(i=1;i<10;i++)
{ printf(“\n%d”,i);
if (i==3) break;
}
getch();
return 0;
}
Biến i chạy từ 1 đến 9 nhưng khi i bằng 3 thì gặp lệnh break nên chương trình chỉ hiển thị ra màn hình 3 số 1,2,3
Ví dụ : Dùng lệnh continue
#include <stdio.h>
#include <conio.h>
main()
{
int i;
for(i=1;i<10;i++)
{ printf(“\n%d”,i);
if (i!=3) continue;
printf(“ Day la so 3”);
}
getch();
return 0;
}
Chương trình sẽ hiển thị các số từ 1 đến 9, mỗi số trên một dòng Khi i khác 3 thì máy sẽ chuyển tới kiểm tra tiếp, khi i bằng 3 thì sẽ hiển thị thêm dòng chữ “Day la so 3”
Trang 14Ví dụ : Tính 10!!=2*4*6*8*10
#include <stdio.h>
#include <conio.h>
main()
{
int p=1, i=1;
while (1)
{ i++;
if(i>10) break;
if(i%2) continue;
p*=i;
}
getch();
return 0;
}
VI.2 Lệnh goto:
Nhãn được đặt tên như tên biến và có dấu “:” phía sau Nhãn có thể được gán cho bất
kì câu lệnh nào trong chương trình
Lệnh goto có dạng:
goto nhãn;
Ví dụ :
ketthuc : printf(“Het”); // ketthuc là nhãn của lệnh printf
goto ketthuc;
Khi gặp lệnh này máy sẽ thực hiện các lệnh sau nhãn
Ví dụ :
nhan :
{
}
if (biểu thức) goto nhan;
Chú ý :
• Câu lệnh goto và nhãn phải nằm trong cùng một hàm, không thể nhảy từ hàm này sang hàm khác
• Không cho phép sử dụng goto để nhảy từ ngoài vào trong khối lệnh, thường là nhảy từ trong khối lệnh ra ngoài
Ta nên hạn chế sử dụng lệnh này đến mức tối đa, chỉ dùng trong những trường hợp thật cần thiết bằng cách sử dụng các lệnh điều khiển khác vì việc điều khiển dễ bị rối
Trang 15Ví dụ : Kiểm tra xem mảng n phần tử có đối xứng không ?
Cách 1 :
dx=1;
for(i=0,j=n-1;i<j;i++,j )
{ if (mang[i]==mang[j])
continue;
dx=0;
break;
}
Cách 2 :
i=0;j=n-1;
while ((i<j)&&(mang[i]==mang[j]))
{ i++;j ;
}
if (i<j) dx1=0;
else dx1=1;
VII Bài tập :
1 Tính tổng của 100 số nguyên dương đầu tiên
2 Tính n!, tổ hợp n chập k ( Cnk)
3 Đưa ra màn hình :
4 Nhập vào một số thực từ bàn phím, kiểm tra xem số đó có thuộc (-1,1) hay không ? Tính giá trị hàm số :
≥ +
<
−
=
0
0
* 2
* 3 )
2
x x
x
x x x
x f
5 Nhập tuổi của một người Hiển thị ra màn hình :
Nếu tuổi < 18 : trẻ vị thành niên
Nếu 18 <= tuổi <= 60 : người lớn
Nếu 60 < tuổi : người già
6 Giải hệ pt : ax+by=c
dx+ey=f
7 Giải pt bậc 1, 2, 3, 4
8 Giải pt trùng phương : ax4 + bx2 + c = 0
9 Tính diện tích hình thang biết độ dài các cạnh
10 Nhập R[i], i=1÷5 Tính điện trở tương đương của mạch cầu