Các cấu trúc điều khiển trong ngôn ngữ lập trình


[Updated1-10/03/17]Một trong những yếu tố quan trọng và không thể thiếu của một chương trình là “việc điều khiển”, cụ thể là các cấu trúc điều khiển, cũng là thành tố kết hợp đồng thời giữa dữ liệu và tác vụ. Có thể hiểu, điều khiển trong lập trình là lựa chọn những câu lệnh nào sẽ thực hiện tiếp theo câu lệnh vừa thực thi. Cấu trúc điều khiển (Câu lệnh điều khiển) cho phép một lập trình viên xác định thứ tự thực thi các lệnh trong mỗi chương trình, thể hiện qua việc:

+ Bỏ qua một vài câu lệnh để thực thi các câu lệnh khác.
+ Lặp lại một hoặc khối lệnh trong khi điều kiện còn đúng.

Cấu trúc điều khiển (Control Structure) là một trong các đặc trưng cơ bản của phương pháp lập trình cấu trúc. Trong đó, người ta sử dụng 3 cấu trúc điều khiển để tạo nên logic của chương trình. Mọi vấn đề về logic đều được giải quyết bằng cách phối hợp 3 cấu trúc: Cấu trúc tuần tự (Sequence structures), Cấu trúc chọn (Selection structures) và cấu trúc lặp (Iterative structures).

Trong đề tài này, ta phân biệt hai loại điều khiển: Loại thứ nhất là điều khiển thứ tự thực thi của các tác vụ trong một kết hợp, gọi là điều khiển trình tự (sequence control). Loại thứ hai là điều khiển việc truy xuất dữ liệu ở mỗi tác vụ và việc truyền dữ liệu giữa các tác vụ trong một kết hợp, gọi là điều khiển dữ liệu (data control).

 

NỘI DUNG BÀI VIẾT

Giới thiệu

I Điều khiển trình tự

  • Cấu trúc điều khiển trình tự trong biểu thức
  1. Điều khiển trong biểu thức (Control within expressions)
  • Các cấu trúc điều khiển trình tự giữa các phát biểu
  1. Các câu lệnh lựa chọn (Selection Statements)
  2. Các câu lệnh lặp (Iterative Statements)
  3. Rẽ nhánh không điều kiện (Unconditional Branching)
  • Cấu trúc điều khiển trình tự giữa các chương trình con
  1. Cấu trúc gọi đệ quy (Recursive Call)

II Điều khiển dữ liệu

Tóm tắt

Tài liệu tham khảo

========================

Giới thiệu

Dữ liệu và tác vụ là hai yếu tố cơ bản của chương trình. Mỗi sự kết hợp của chúng gắn liền với cấu trúc điều khiển. Cấu trúc điều khiển là tập hợp các qui tắc xác định thứ tự thực hiện chương trình.

–  Xét về cấu trúc, có 3 loại điều khiển:

+ Điều khiển trong các biểu thức.
+ Điều khiển giữa các phát biểu: cấu trúc điều kiện/ cấu trúc lặp.
+ Điều khiển trong chương trình con: gọi trả về hay đệ qui.

– Xét về thiết kế ngôn ngữ, có 2 loại điều khiển:

+ Điều khiển ngầm: được thiết kế trong ngôn ngữ lập trình.
(Ví dụ: quy tắc ưu tiên các toán tử)

+ Điều khiển tường minh: được xác định bởi lập trình viên.
(Ví dụ: phát biểu GOTO, CONTINUE, BEAK,…)

Các vấn đề logic được giải quyết bằng cách phối hợp 3 cấu trúc:

– Cấu trúc tuần tự (Sequence structures).
Cấu trúc chọn (Selection structures).
Cấu trúc lặp (Iterative structures).

cautrucdieukhien1

(True: T / False: F)

Lệnh (statement): một biểu thức kết thúc bởi 1 dấu chấm phẩy gọi là 1 lệnh.

vd: int a, b, c;   a=10;

Khối lệnh (block): một hay nhiều lệnh được bao quanh bởi cặp dấu { } gọi là một khối lệnh. Về mặt cú pháp, khối lệnh tương đương 1 câu lệnh đơn.

if(a<b)
{
  temp=a;
  a=b;
  b=temp;
}

===================================

Điều khiển trong biểu thức
(Control within expressions)

cautrucdieukhien2

Cho biểu thức như sau: (A + B) * (C – A), được biểu diễn bằng dạng cây như hình. Cơ chế điều khiển trong biểu thức là sự chồng chất hàm (funcyional composition): xác định tác vụ hay phép toán là chính, các đối số hay các toán hạng (operand) của nó được xác định. Các toán hạng này có thể là các hằng, các kết quả của các phép tham khảo dữ liệu (biến, đối tượng dữ liệu được tham khảo đến bởi biến chỉ điểm,…), hoặc các kết quả của các phép toán khác trong biểu thức. Cơ chế chồng chất hàm có thể được biểu diễn bằng một cấu trúc cây, trong đó nút gốc của cây biểu diễn phép toán chính của biểu thức, các nút giữa gốc và lá biểu diễn các phép toán trung gian của biểu thức, còn các lá biểu diễn các hằng hoặc các phép tham khảo dữ liệu.

Dạng biểu diễn cây cho biểu thức đã cho theo cơ chế chồng chất hàm vẫn còn liên quan đến thứ tự thực hiện của các toán tử.

Thứ tự ưu tiên của các toán tử

Trong toán học, khi tính giá trị của biểu thức, luôn có sự ưu tiên của các toán tử như: Nhân chia trước, cộng trừ sau, ưu tiên từ trái sang phải… Trong ngôn ngữ lập trình, các toán tử đều có những độ ưu tiên, do đó cần chú ý để không gây sai sót khi thực thi chương trình.

Ta có biểu thức sau: 1 + 2 * 3 – 4; Kết quả sẽ bằng bao nhiêu?

Câu trả lời là kết quả của biểu thức phụ thuộc vào thứ tự thực hiện các toán tử. Được mô tả ngay sau đây với 3 ngôn ngữ lập trình:

cautrucdieukhien3

Các toán tử cùng độ ưu tiên

Cho biểu thức: a – b + c – d

Phép toán cộng (+) và trừ (-) có cùng độ ưu tiên. Ta cần có một quy luật để xác định thứ tự thực hiện. Các ngôn ngữ lập trình quy định thứ tự thực hiện như sau:

+ Từ trái sang phải.
+ Trừ Fortran (từ phải sang trái).

Ada bắt buộc phải có dấu ngoặc khi thực hiện biểu thức đa toán tử ( ( a – b ) + c ) – d. Nếu có dấu ngoặc thì thứ tự ưu tiên của các toán tử bị mất đi và thực hiện theo dấu ngoặc.

Thứ tự các toán hạng

– Biểu thức quan hệ: là một toán tử quan hệ và hai toán hạng có nhiều kiểu khác nhau. Trị của biểu thức quan hệ là Đúng hoặc Sai. Ví dụ toán tử quan hệ:

cautrucdieukhien4

– Biểu thức logic: là một toán tử logic và hai toán hạng có kiểu logic. Trị của biểu thức logic là Đúng hoặc Sai. Ví dụ toán tử logic:

cautrucdieukhien5

– Tổng kết thứ tự ưu tiên để đánh giá, thực hiện biểu thức là:

+ Tính toán các hàm chức năng.
+ Tính toán trong dấu ngoặc đơn.
+ Tính lũy thừa/ số mũ (^, **).
+ Tính phép nhân, chia, từ trái sang phải.
+ Tính phép cộng, trừ, từ trái sang phải.
+ Thực hiện các toán tử quan hệ (= != /= < <= > >=), từ trái sang phải.
+ Đánh giá toán tử logic NOT, trái sang phải.
+ Đánh giá toán tử logic AND, trái sang phải.
+ Đánh giá toán tử logic XOR, trái sang phải.
+ Đánh giá toán tử logic OR, trái sang phải.

cautrucdieukhien6

Hiệu ứng lề

Hiệu ứng lề là một phép toán làm thay đổi giá trị của đối tượng dữ liệu được tham khảo đến các phép toán khác trong biểu thức.

Hàm hiệu ứng lề là hàm thay đổi biến không cục bộ hoặc có truyền quy chiếu.

int a=5;
int fun1() { a = 17; return  3; }
void fun2() { a = a + fun1(); }
void main()
{
   fun2();
}

Kết quả có được của a là 8 hay 20? Với ngôn ngữ C trả về giá trị của a là 20.

Giải pháp giải quyết hiệu ứng lề:

+ Ngôn ngữ lập trình không cho phép hàm tham chiếu các biến không cục bộ và truyền quy chiếu. Giải pháp này dễ thực hiện nhưng không linh hoạt.

+ Ngôn ngữ lập trình phải quy định thứ tự ưu tiên của các toán hnag5. Hạn chế, làm giảm khả năng tối ưu code của trình biên dịch.

Ví dụ hiệu ứng lề với biểu thức A * FUNC(X) + A được biểu diễn bởi cấu trúc cây như sau:

cautrucdieukhien7

Nếu thực hiện FUNC(X) không ảnh hưởng gì đến giá trị của A thì kết quả của việc tính biểu thức trên không phụ thuộc vào việc tham khảo giá trị của A (A+) trước hay thực hiện phép nhân trước (khi thực hiện phép cộng), cũng như không phụ thuộc vào việc tham khảo giá trị của A (A*) trước hay thực hiện FUNC(X) trước (khi thực hiện phép nhân). Nhưng sẽ hoàn toàn khác nếu việc thực hiện FUNC(X) làm thay đổi giá trị của A, sau khi FUNC(X) được thực hiện xong.

Cú pháp của biểu thức

– Dạng trung tố (infex): ký hiệu phép toán được viết giữa 2 toán hạng.
Ví dụ: (A + B) * (C – A)

– Dạng tiền tố (prefix): ký hiệu phép toán được viết trước các toán hạng.
Ví dụ: * (+ (A B) ) –  (C A))

– Dạng hậu tố (posfix): ký hiệu phép toán được viết sau các toán hạng
Ví dụ: ((A B) +) (C A) -)*

===================================

Các câu lệnh lựa chọn
(Selection Statements)

Trong cuộc sống hằng ngày, hẳn bạn cũng đã từng chọn lựa, đưa ra quyết định nào đó. Lấy ví dụ, nếu bạn có 10.000 vnđ, bạn sẽ mua một hủ yaourt và một cây chupa chups. Thêm một ví dụ, khi tham gia chơi cờ tướng, mỗi quân cờ ta lựa chọn, bắt buộc phải đi nước cờ tương ứng đã quy định (Tốt chỉ đi 1 ô, Mã đi ngang 2 ô,…). Cấu trúc if, switch-case về mặt ý nghĩa tương tự như các ví dụ trên, đối với ngôn ngữ lập trình, việc lựa chọn, xác định là yếu tố quan trọng không thể thiếu trong một chương trình hoàn thiện.

Một câu lệnh lựa chọn cung cấp các lựa chọn giữa hai hay nhiều cách thực thi trong một chương trình. Lệnh lựa chọn (lệnh điều khiển) là một lệnh biểu thị sự lựa chọn của hai hoặc đa nhánh để thực hiện.

Chia làm 2 loại:

+ Chỉ có 2 lựa chọn (lệnh if).
+ Nhiều lựa chọn (lệnh case).

“Các câu lệnh lựa chọn” là cầu trúc được trình bày đầu tiên trong cấu trúc điều khiển trình tự giữa các phát biểu, sau đó chúng ta sẽ tìm hiểu và phân tích “các câu lệnh lặp” và phần cuối cùng là “rẽ nhánh không điều kiện”.

1 Cấu trúc lệnh điều khiển IF … ELSE – (Two-Way Selection Statements)

– Dạng phổ biến:

if control_expression  then clause
else clause

– Các yếu tố trong lệnh 2 lựa chọn:

Dạng và kiểu của biểu thức lựa chọn như thế nào, quan hệ, toán và logic?
+ Các câu lệnh theo sau thenelse?
+ Lệnh lựa chọn có lồng nhau hay không?

cautrucdieukhien8

a) Dạng và kiểu của biểu thức

– Cấu trúc if dạng 1.1 cho thấy nếu biểu thức điều kiện có giá trị “true” thì statement được thực hiện, ngược lại không làm gì cả. Tại dạng 1.2 nếu biểu thức có giá trị “true” thì statement 1 được thực hiện, ngược lại statement 2 được thực hiện.

– ALGOL 60: Chỉ dùng biểu thức logic
if(boolean_expression) then statement
else statement

– C (89 trở về trước): Chỉ dùng biểu thức logic.
– C (99) và C++: biểu thức toán và logic (vd: if (a-b) printf(“OK”) else printf (“Yes”))
– Ada, Java và C# chỉ dùng biểu thức logic.

b) Sự lựa chọn lồng nhau

Ví dụ 1b, đoạn chương trình java:

if(sum ==0)
   if(count ==0)  // Lệnh if nào sẽ đi cùng với lệnh else? 
        result=0;
else result =1;

Ngôn ngữ C, C++, C#, Java quy định lệnh if và lệnh else gần nhau nhất sẽ đi cùng nhau.

Ví dụ 2b:
Đoạn chương trình bên dưới viết lệnh else thẳng hàng với if(n>0), nhưng lệnh else ở đây được hiểu đi kèm với if(a>b) vì nó nằm gần với if(a>b) nhất và if(a>b) chưa có else. Do đó để giảm và tránh nhầm lẫn ta sẽ viết thẳng hàng if(a>b) với else hoặc có thể đặt if(a>b) x=a vào trong khối lệnh {}.

...
if(n > 0)
    if(a > b) 
  x=a;
else 
  x=b;

Perl yêu cầu lệnh ghép (if else đầy đủ), dùng 2 ngoặc nhọn {} để phân định.

if(sum == 0){
      if(count == 0){
            result=0;
        }
} else {
  result=1;
 }

khác với

if(sum == 0){
      if(count == 0){
            result=0;
        }
  else {
  result=1;
 }
}

Cấu trúc if lồng nhau càng nhiều, cấp độ phức tạp càng cao, chương trình chạy càng chậm và trong lúc lập trình dễ bị nhầm lẫn.

2 Lệnh lựa chọn đa nhánh – (Multiple-Selection Statements)

Cho phép lựa chọn 1 nhánh trong số nhiều nhánh lệnh để thực hiện.
Các yếu tố trong lệnh lựa chọn đa nhánh:

+ Kiểu và dạng của biểu thức điều khiển?
+ Công việc của từng nhánh lệnh?
+ Có nhánh lệnh nào không thỏa điều kiện? Nếu có nó thực hiện lệnh gì? 

a) Mô hình switch-case

switch (expression){
case constant_expression1 : statement1 ; break;

case constant_expressionn : statement_n; break;
[default: statementn+1]
}

Tương ứng với từng giá trị của expression mà statementi được thực hiện. Trong trường hợp giá trị biểu thức không trùng với giá trị nào thì statementn+1 được thực hiện.

Chú ý:

+ expression trong switch( ) phải có kiểu dữ liệu đếm được như char, int,.. không thể là kiểu thực (double, float).

+ Sau mỗi statement phải có lệnh break, nếu không thì các statement lần lượt được thực thi cho đến khi gặp 1 lệnh break khác.

cautrucdieukhien9

Switch-case trong C, C++, Java:

+ Biểu thức điều khiển phải là kiểu nguyên.
+ Câu lệnh lựa chọn có thể là 1 câu lệnh đơn hoặc khối lệnh.
+ Kết thúc cấu trúc switch-case khi gặp break;
+ Default: được chọn nếu không có giá trị nào thỏa expression.

Ví dụ:cautrucdieukhien10Switch-case trong Ada:

case expression is
when choice list => stmt_sequence;

when choice list => stmt_sequence;
when others       => stmt_sequence;
end case;

Giá trị <choice list> tương ứng với một giá trị duy nhất (ví dụ 5), một phạm vi ( 1 .. 20) hoặc kết hợp các miền giá trị, ngăn cách bởi ký tự ‘|’.

Ví dụ:

cautrucdieukhien11

Switch-case trong C#:

Biểu thức trong switch() có giá trị đếm được, kiểu dữ liệu là một số nguyên , ký tự, chuỗi ký tự hoặc kiểu dữ liệu liệt kê (enum). Ta có thể thay lệnh break thành goto hoặc continue.

Ta có ví dụ sau:

cautrucdieukhien12

b) Mô hình if

Trong nhiều trường hợp, khi sử dụng lệnh switch-case sẽ không phù hợp với đa lựa chọn (ngoại trừ Ruby). Một ví dụ, khi thực hiện việc chọn lựa dựa trên một biểu thức Boolean (đúng hoặc sai) ta sử dụng cấu trúc if else lồng nhau để mô phỏng như một lệnh lựa chọn đa nhánh (case).

Lệnh lựa chọn đa nhánh có thể chuyển thành lệnh chọn 2 nhánh với else-if

if (expr == const_expr_1) stmt_1;
else if (expr == const_expr_2) stmt_2;

else if (expr == const_expr_n) stmt_n;
else stmt_n+1;

Ví dụ trong Python (trong Python else-if được viết thành elif ):

cautrucdieukhien13

===================================

Các câu lệnh lặp
(Iterative Statements)

Mỗi ngày bạn đánh răng ít nhất 2 lần, học một môn học mỗi tuần 2 tiết, rửa chén đến khi sạch, đi bộ (chân trái, chân phải, rồi lại chân trái chân phải,…), có rất rất nhiều hoạt động thường nhật xảy ra lặp đi lặp lại. Trong ngôn ngữ lập trình cũng vậy, đôi lúc chúng ta viết một đoạn code lặp đi lặp lại nhiều lần để thực hiện một yêu cầu nào đó, thật vất vả khi bạn phải viết 100 câu lệnh giống nhau chỉ để làm một công việc. Chính vì vậy, khái niệm lệnh lặp giúp rất nhiều cho lập trình viên để xây dựng các chương trình khác nhau một cách hiệu quả, nhanh chóng.

Ở phần này, chúng ta sẽ chú ý đến ba cấu trúc: for, while, do-while. Ba cấu trúc này đóng góp rất lớn trong quá trình cài đặt phần mềm, loại bỏ nhanh chóng việc giảm hiệu xuất gây ra do sử dụng quá nhiều dòng lệnh có chung tính chất.

– Điều kiện kết thúc sự lặp có thể được xác định thông qua biến đếm hoặc là điều kiện phức tạp được biểu diễn bằng một biểu thức luận lý. Có 2 loại lệnh lặp: Lệnh lặp với bộ đếm và lệnh lặp có điều kiện.

– Các yếu tố trong lệnh lặp

+ Làm thế nào để kiểm soát lặp?
+ Kiểm soát lặp xuất hiện ở đâu trong vòng lặp?

Lệnh lặp với bộ đếm – (Counter-Controlled Loops)

Trong lệnh điều khiển lặp có một biến số, ta gọi đây là biến lặp. Trong đó giá trị của biến đếm từ giá trị bắt đầu (initial) đến giá trị kết thúc (terminal) và giá trị của bước nhảy (stepsize)

– Các yếu tố trong lệnh lặp:

+ Kiểu của biến lặp và phạm vi?
+ Giá trị của biến lặp khi vòng lặp kết thúc?
+ Giá trị của biến lặp có được thay đổi trong thân vòng lặp không? Nếu có thì có ảnh hưởng đến vòng lặp không?

– Cú pháp Fortran 90:

+ do bien_lap = gia_tri_dau, gia_tri_ket_thuc [, buoc_nhay]
+ Trị của bước nhảy là bất kỳ (trừ 0), mặc định là 1
+ gia_tri_dau, gia_tri_ket_thuc có thể là biểu thức
+ Kiểu biến lặp phải là kiểu nguyên.
+ Biến lặp không được thay đổi trong thân vòng lặp.

– Cú pháp Fortran 95:

do bien_lap = gia_tri_dau, gia_tri_ket_thuc [, buoc_nhay]

end do

– Cú pháp lệnh for của Pascal

for bien_lap := bat_dau (to | downto)
ket_thuc do

+ bien_lap có kiểu số nguyên, giá trị không thay đổi trong thân vòng lặp.
+ Sau khi kết thúc vòng lặp, giá trị của bien_lap không xác định.

+ bat_dau, ket_thuc có thể là biểu thức, nhưng các tham số có thể thay đổi trong vòng lặp và không ảnh hường đến vòng lặp.

Ta có ví dụ phát biểu for:

for I:=E1 to E2 do S

Phát biểu lặp này ta có thể thay thế bằng phát biểu GOTO và phát biểu điều kiện như sau:

I:=E1;
L0:       if I > E2 then goto L1
             S:I:=I+1;
            goto L0
L1: …

– Cú pháp lệnh for của Ada:

                 for bien_lap in  [reverse] day_roi_rac loop
                 …
                 end loop

+ day_roi_rac: miền con số nguyên, 1…10, hoặc kiểu liệt kê monday…Friday
+ Phạm vi của biến có bao gồm vòng lặp.
+ Giá trị của biến lặp không xác định khi vòng lặp kết thúc.

– Cú pháp lệnh for trong C:

for ([expr_1] ; [expr_2]; [expr_3])
statement

+ Mọi thứ có thể thay đổi trong thân vòng lặp.
+ Biểu thức expr_1 được định lượng 1 lần trước khi tực hiện vòng lặp ( biểu thức khởi tạo).

+ Sau mỗi lần lặp, expr_2 (biểu thức điều kiện) và expr_3 (biểu thức điều khiển lặp) được định lượng.
+ Xóa các biểu thức expr_1, expr_2, expr_3 trong vòng for sẽ cho vòng lặp vô tận.
+ C++ cho phép khai báo kiểu trong expr_1

for (int count=0;count<len; count++)   {…}

Lệnh lặp có điều kiện – (Logically Controlled Loops)

– Chỉ được thực hiện khi điều kiện đúng
– Các yếu tố trong lệnh lặp có điều kiện:

+ Kiểm tra điều kiện trước hay sau.
+ Là trường hợp đặc biệt của lệnh lặp với bộ đếm?

– Cú pháp

while (ctrl_expr)   
     loop body 

do{
   loop body
}while (ctrl_expr);

– Pascal phân chia rõ ràng kiểm tra điều kiện trước và sau: while-do và repeat-until
– C và C++ dùng cả “while-do” – (lặp nếu điều kiện còn đúng) và “do-while” – ( lặp đến khi điều kiện sai).

– Biểu thức điều kiện của java và C đều có kiểu boolean.

==> Nhận định qua 2 loại lệnh lặp: Các phát biểu lặp vẫn được hiện thực bằng các lệnh nhảy có điều kiện và không điều kiện của ngôn ngữ máy.

===================================

Rẽ nhánh không điều kiện
(Unconditional Branching)

– Lệnh rẽ nhánh không điều kiện được đưa ra vào những năm cuối thập niên 60.
– Cho phép thay đổi thứ tự thực hiện chương trình.
– Cơ chế phổ biến nhất là lệnh: goto
– Một số NNLT không hỗ trợ lệnh goto
– C# cung cấp lệnh goto, có thể dùng trong switch-case.
– Lệnh goto làm chương trình khó đọc và khó bảo trì.

Luồng điều khiển không tuần tự (Nonlocal control flow)

– Cho phép thoát khỏi luồng điều khiển thông thường
– Ứng dụng:

+ Thoát sớm trong các cấu trúc lặp: Continue & break
+ Trả về (return) sớm trong các hàm: Return
+ Bắt các ngoại lệ: Try/catch

Lệnh continue

– Lệnh continue sẽ kết thúc vòng lặp hiện hành và chuyển đến vòng lặp tiếp theo.
– Khi gặp lệnh này, các câu lệnh còn lại trong thân của vòng lặp sẽ được bỏ qua.
Vd:
int count =0;
for (int i=0; i<=len; i++)
{
if (i = 8) continue;
count+= 1;
}

Lệnh break

– Lệnh break sẽ thoát khỏi cấu trúc lặp hoặc switch

int count =0;
for (int i=0; i<=len;i++)
{
  if (i=8) break; 
  count+=1;      
}
switch (expr)
{
  case 0: stmt1; break;
  case 1: stmt2; stmt3; break;
  case 1: stmt2; stmt3; break;
}

Lệnh return

int  F (int x)
{
   x=10;
   x+=10;
   return x;   // x=20
}

Try/catch

 
try{ 
  //Đoạn mã có khả năng gây ra ngoại lệ
}
catch(Exception e1){
  //Nếu các lệnh trong khối “try” tạo ra ngoại lệ có loại e1
}
…
catch(Exception eN){
…
}
Finally{
// khối lệnh luôn được thực hiện cho dù có xảy ra ngoại lệ hay không
}

-Ví dụ:

try {
 X= F(x,y);
}
 catch (ArithmeticException) {
 System.out.println (“An arithmetic error occurred!”);
 System.exit (0);
}

+ Nếu F(x,y) không có lỗi, tiến trình vẫn tiếp tục.
+ Nếu F(x,y) lỗi, ArithmeticException được chuyển tới JVM

===================================

Cấu trúc gọi đệ quy
(Recursive Call)

Ở phần cấu trúc điều khiển trình tự giữa các chương trình con, chúng ta sẽ xem xét diễn biến sự thực thi của các chương trình con, có 2 vấn đề cơ bản mà ít nhiều chúng ta đã và bắt buộc sử dụng trong quá trình cài đặt chương trình.

+ Cấu trúc gọi trở về đơn giản. (simple call-return structure).
+ Cấu trúc gọi đệ quy (recursive call).

Cấu trúc gọi trở về đơn giản

Là một cấu trúc chương trình gồm chương trình chính và chương trình con, điều khiển trình tự cơ bản giữa các chương trình con. Khi thực thi chương trình, chương trình chính được thực hiện đầu tiên, trong quá trình thực hiện, chương trình chính có thể gọi các chương trình con, mỗi chương trình con lại gọi các chương trình con khác để hoàn thành nhiệm vụ. Giả sử một chương trình con A, gọi chương trình con B, thì A gọi là chương trình gọi (calling program), còn B gọi là chương trình được gọi (called program). Như vậy, trong quá trình thực thi, khi A gọi B, thì A sẽ đợi B hoàn thành nhiệm vụ rồi mới chạy tiếp công việc của mình. Một số hạn chế như: Chương trình con không được đệ quy, cần có các phát biểu gọi tường minh, chương trình con phải hoàn thành ở mỗi lần gọi,…

Cấu trúc gọi đệ quy

Là cấu trúc điều khiển trình tự quan trọng trong lập trình. Nhiều giải thuật diễn đạt bằng đệ quy, vừa đơn giản, giảm chi phí lập trình hơn so với các giải quyết bằng sự lặp. Ở một số ngôn ngữ như LISP hay PROLOG, gọi đệ quy được sử dụng như cấu trúc chính để thực hiện sự lặp. Khác với gọi trở về đơn giản, cấu trúc gọi đệ quy gọi đến nhiều bản hoạt động của cùng một chương trình con có thể cùng tồn tại trong bộ nhớ, trong thời gian thực hiện chương trình. Một chương trình con (hay hàm) được gọi là đệ quy nếu bên trong thân nó có một lời gọi đến chính nó và khi đạt được tại điều kiện dừng, quá trình đệ quy sẽ không diễn ra nữa.

Xét ví dụ:

cautrucdieukhien14

===================================

Điều khiển dữ liệu
(Data control)

Như đã biết, điều khiển trình tự quan tâm đến thứ tự thực thi của các tác vụ, thì điều khiển dữ liệu quan tâm đến vấn đề truy xuất dữ liệu trong mỗi tác vụ và trao đổi dữ liệu giữa các tác vụ với nhau. Có 2 cách để một đối tượng dữ liệu (đtdl) tham gia thực thi một tác vụ:

+ Truyền trực tiếp: đối tượng dữ liệu là kết quả của một tác vụ và truyền trực tiếp cho tác vụ khác. Ví dụ, biểu thức 3 + 4 * 7, kết quả phép nhân 4 và 7 truyền trực tiếp cho phép cộng để cộng với 3.
+ Truy xuất đối tượng dữ liệu thông qua tên: Tên của đtdl được sử dụng như một toán hạng, chỉ định đtdl đó trong tác vụ.

Tên:

+ Tên đơn giản:
Tên biến, tên thông số hình thức, tên chương trình con (ví dụ: a,b).

+ Tên phức hợp:
Kết hợp với tác vụ lựa chọn và truy xuất thành phần (ví dụ: a[1], b.c[2]).

Môi trường tham khảo:

Gồm môi trường tham khảo tĩnh (tập hợp các khai báo mà một chương trình có thể tham khảo) và môi trường tham khảo động (tập hợp các kết hợp mà một bản hoạt động của chương trình con có thể tham khảo). Các loại môi trường tham khảo như: Môi trường cục bộ, môi trường không cục bộ, môi trường toàn cục, môi trường định nghĩa trước.

cautrucdieukhien15

cautrucdieukhien16

Tầm vực: Tầm vực của một ràng buộc là phạm vi chương trình (trong văn bản chương trình hoặc trong thời gian thực thi) mà ràng buộc có ý nghĩa hay có hiệu lực. Có hai loại tầm vực là tầm vực tĩnh và tầm vực động.

Cấu trúc khối:
Chương trình gồm nhiều khối lồng nhau, khối bắt đầu bằng khai báo và theo sau là các phát biểu. Khối tạo ra môi trường cục bộ của khối. Quy tắc tầm vực tĩnh như sau:

+ Khai báo đầu khối tạo môi trường tham khảo cục bộ của khối.
+ Khối bị bao thừa hưởng các khai báo của khối bao nó.
+ Mọi khai báo của khối là bị che với các khối bên ngoài.
+ Một khối có thể được đặt tên – tên khối thuộc môi trường cục bộ của khối
bao trực tiếp khối đang xét.

cautrucdieukhien17

===================================

Tóm tắt bài viết

cautrucdieukhien18

Sequence:
Các công việc được thực hiện tuần tự, quá trình sau tiếp nối quá trình trước, thực hiện từ trên xuống.

Selection:
Còn gọi là cấu trúc ifthenelse (nếu …thì …ngược lại). Cho phép lập trình viên diễn đạt được các logic điều kiện trong chương trình. Nếu điều kiện đúng thì thực hiện quá trình (Công việc, các câu lệnh) tương ứng với điều kiện đúng, ngược lại thực hiện quá trình ứng với điều kiện sai.

Một dạng khác nữa, đó chính là cấu trúc switch – case. Dạng này sử dụng khi một điều kiện được kiểm tra có thể dẫn đến 2 hay nhiều quá trình xử lý khác nhau. Trong một chương trình, menu là một ví dụ.

Iterative:

Cho phép thực hiện nhiều lần cùng một quá trình dựa trên điều kiện cho trước. Có 2 dạng cơ bản là for (Cho phép lặp với số lần xác định) và while (Lặp cho tới khi điều kiện kiểm tra không còn đúng nữa).

===================================

TÀI LIỆU THAM KHẢO

– Tài nguyên tham khảo:

[1] Robert W. Sebesta, Concepts of Programming Languages 10th.
[2] David A. Fisher, Control Structures for Programming Languages.
[3] Cao Hoàng Trụ, Giáo trình Ngôn ngữ lập trình các nguyên lý và mô hình, 2010
[4] Nguyễn Văn Hòa, Cấu trúc điều khiển, 2005.

– Danh mục từ khóa tìm kiếm:

  • Implement Control structures.
  • Control structures.
  • Control structures in programming.
  • What will control structures do?
  • Selection Statements/ Iterative Statements

– Đường dẫn tham khảo:

https://en.wikibooks.org/wiki/Ada_Programming/Operators
http://www.mrao.cam.ac.uk/~rachael/compphys/SelfStudyF95.pdf
http://www.cplusplus.com/doc/tutorial/operators/
https://en.wikiversity.org/wiki/Control_structures
http://www.circuitstoday.com/control-structures-in-c-and-cpp
http://www.cs.man.ac.uk/~pjj/cs211/ho/node11.html

– Danh sách thuật ngữ:
Lệnh : Statement – stmt
Biểu thức: expression – expr

– Phụ lục so sánh Parameter và Argument:
Bài viết mình chụp từ 1 bài viết trên internet


Cảm ơn bạn đã theo dõi blog.
Nhiều ngày tốt lành!

Advertisements

Cho mình biết cảm nhận của bạn nhé

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s