Kiểm soát luồng PHP là gì?
Trong khoa học máy tính, luồng điều khiển (hoặc luồng điều khiển) là thứ tự mà các câu lệnh, lệnh hoặc lệnh gọi hàm riêng lẻ của một chương trình mệnh lệnh được thực hiện hoặc đánh giá. Sự nhấn mạnh vào luồng điều khiển rõ ràng giúp phân biệt ngôn ngữ lập trình mệnh lệnh với ngôn ngữ lập trình khai báo Show
Trong một ngôn ngữ lập trình mệnh lệnh, một câu lệnh luồng điều khiển là một câu lệnh dẫn đến sự lựa chọn được thực hiện theo hai hoặc nhiều đường dẫn để đi theo. Đối với các ngôn ngữ chức năng không nghiêm ngặt, các hàm và cấu trúc ngôn ngữ tồn tại để đạt được kết quả tương tự, nhưng chúng thường không được gọi là các câu lệnh luồng điều khiển Đến lượt mình, một tập hợp các câu lệnh thường được cấu trúc dưới dạng một khối, khối này ngoài việc nhóm, còn xác định phạm vi từ vựng Ngắt và tín hiệu là các cơ chế cấp thấp có thể thay đổi luồng điều khiển theo cách tương tự như chương trình con, nhưng thường xảy ra như một phản ứng đối với một số kích thích hoặc sự kiện bên ngoài (có thể xảy ra không đồng bộ), thay vì thực thi nội tuyến. Ở cấp độ ngôn ngữ máy hoặc hợp ngữ, hướng dẫn luồng điều khiển thường hoạt động bằng cách thay đổi bộ đếm chương trình. Đối với một số đơn vị xử lý trung tâm (CPU), các hướng dẫn luồng điều khiển duy nhất có sẵn là các hướng dẫn rẽ nhánh có điều kiện hoặc không điều kiện, còn được gọi là các bước nhảy Các loại câu lệnh luồng điều khiển được hỗ trợ bởi các ngôn ngữ khác nhau sẽ khác nhau, nhưng có thể được phân loại theo tác dụng của chúng
Nguyên thủy [ chỉnh sửa ]Nhãn là một tên hoặc số rõ ràng được gán cho một vị trí cố định trong mã nguồn và có thể được tham chiếu bởi các câu lệnh luồng điều khiển xuất hiện ở nơi khác trong mã nguồn. Nhãn đánh dấu một vị trí trong mã nguồn và không có tác dụng nào khác Số dòng là một thay thế cho nhãn có tên được sử dụng trong một số ngôn ngữ (chẳng hạn như BASIC). Chúng là các số nguyên được đặt ở đầu mỗi dòng văn bản trong mã nguồn. Các ngôn ngữ sử dụng những thứ này thường áp đặt ràng buộc rằng số dòng phải tăng giá trị trong mỗi dòng tiếp theo, nhưng có thể không yêu cầu chúng phải liên tiếp. Ví dụ, trong CƠ BẢN Trong các ngôn ngữ khác như C và Ada, nhãn là một mã định danh, thường xuất hiện ở đầu dòng và ngay sau đó là dấu hai chấm. Ví dụ, trong C Success: printf("The operation was successful.\n"); Ngôn ngữ ALGOL 60 cho phép cả số nguyên và số nhận dạng dưới dạng nhãn (cả hai đều được liên kết bằng dấu hai chấm với câu lệnh sau), nhưng rất ít nếu có bất kỳ biến thể ALGOL nào khác cho phép số nguyên. Trình biên dịch Fortran ban đầu chỉ cho phép các số nguyên làm nhãn. Bắt đầu với Fortran-90, nhãn chữ và số cũng đã được cho phép Câu lệnh goto (sự kết hợp của các từ tiếng Anh go và to, và được phát âm tương ứng) là hình thức cơ bản nhất của việc chuyển giao quyền kiểm soát vô điều kiện Mặc dù từ khóa có thể ở dạng chữ hoa hoặc chữ thường tùy thuộc vào ngôn ngữ, nó thường được viết là goto label Tác dụng của câu lệnh goto là làm cho câu lệnh tiếp theo được thực thi là câu lệnh xuất hiện tại (hoặc ngay sau) nhãn được chỉ định Các câu lệnh Goto đã bị nhiều nhà khoa học máy tính coi là có hại, đặc biệt là Dijkstra Chương trình con[sửa]Thuật ngữ cho các chương trình con khác nhau; Vào những năm 1950, bộ nhớ máy tính rất nhỏ so với tiêu chuẩn hiện tại nên các chương trình con được sử dụng chủ yếu[cần dẫn nguồn] để giảm kích thước chương trình. Một đoạn mã được viết một lần và sau đó được sử dụng nhiều lần từ nhiều nơi khác nhau trong một chương trình Ngày nay, chương trình con thường được sử dụng nhiều hơn để giúp chương trình có cấu trúc hơn, chẳng hạn như. g. , bằng cách cô lập một số thuật toán hoặc ẩn một số phương thức truy cập dữ liệu. Nếu nhiều lập trình viên đang làm việc trên một chương trình, chương trình con là một loại mô đun có thể giúp phân chia công việc Trình tự[sửa]Trong lập trình có cấu trúc, thứ tự sắp xếp thứ tự của các lệnh nối tiếp nhau được coi là một trong những cấu trúc điều khiển cơ bản, được dùng làm khối xây dựng cho chương trình bên cạnh phép lặp, đệ quy và lựa chọn. Luồng điều khiển có cấu trúc tối thiểu[sửa | sửa mã nguồn]Vào tháng 5 năm 1966, Böhm và Jacopini đã xuất bản một bài báo[1] trên tạp chí Communications of the ACM, trong đó chỉ ra rằng bất kỳ chương trình nào có gotos đều có thể được chuyển thành dạng không có goto chỉ bao gồm lựa chọn (IF THEN ELSE) và các vòng lặp (điều kiện WHILE DO xxx) . Các tác giả sau này đã chỉ ra rằng sự lựa chọn có thể được thay thế bằng các vòng lặp (và nhiều biến Boolean hơn) Việc có thể thực hiện được chủ nghĩa tối giản như vậy không có nghĩa là nó nhất thiết phải được mong muốn; Điều mà bài báo của Böhm và Jacopini chỉ ra là tất cả các chương trình đều có thể được truy cập miễn phí. Nghiên cứu khác cho thấy rằng các cấu trúc điều khiển với một mục nhập và một lối ra dễ hiểu hơn nhiều so với bất kỳ dạng nào khác,[cần dẫn nguồn] chủ yếu là do chúng có thể được sử dụng ở bất kỳ đâu như một câu lệnh mà không làm gián đoạn luồng điều khiển. Nói cách khác, chúng có thể tổng hợp được. (Những phát triển sau này, chẳng hạn như các ngôn ngữ lập trình không nghiêm ngặt – và gần đây hơn là các giao dịch phần mềm có thể kết hợp – đã tiếp tục chiến lược này, làm cho các thành phần của chương trình thậm chí có thể kết hợp một cách tự do hơn. ) Một số học giả đã áp dụng cách tiếp cận thuần túy đối với kết quả Böhm–Jacopini và lập luận rằng ngay cả các hướng dẫn như if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;2 và if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;3 từ giữa các vòng lặp cũng là một cách thực hành tồi vì chúng không cần thiết trong chứng minh Böhm–Jacopini, và do đó họ ủng hộ rằng tất cả các vòng lặp nên có . Cách tiếp cận thuần túy này được thể hiện trong ngôn ngữ Pascal (được thiết kế vào năm 1968–1969), cho đến giữa những năm 1990 là công cụ ưa thích để dạy lập trình nhập môn trong giới học thuật. [2] Việc áp dụng trực tiếp định lý Böhm–Jacopini có thể dẫn đến các biến cục bộ bổ sung được đưa vào biểu đồ có cấu trúc và cũng có thể dẫn đến một số mã trùng lặp. [3] Pascal bị ảnh hưởng bởi cả hai vấn đề này và theo các nghiên cứu thực nghiệm được trích dẫn bởi Eric S. Roberts, các sinh viên lập trình đã gặp khó khăn trong việc xây dựng các giải pháp chính xác trong Pascal cho một số vấn đề đơn giản, bao gồm viết một hàm để tìm kiếm một phần tử trong một mảng. Một nghiên cứu năm 1980 của Henry Shapiro do Roberts trích dẫn đã phát hiện ra rằng chỉ sử dụng các cấu trúc điều khiển do Pascal cung cấp, chỉ 20% đối tượng đưa ra lời giải đúng, trong khi không đối tượng nào viết sai mã cho vấn đề này nếu được phép viết trả về từ . [2] Cấu trúc điều khiển trong thực tế[sửa | sửa mã nguồn]Hầu hết các ngôn ngữ lập trình có cấu trúc điều khiển đều có từ khóa khởi tạo cho biết loại cấu trúc điều khiển có liên quan. [cần làm rõ] Các ngôn ngữ sau đó phân chia xem các cấu trúc điều khiển có từ khóa cuối cùng hay không
Câu lệnh if-then-(else)[sửa]Biểu thức điều kiện và cấu trúc điều kiện là các tính năng của ngôn ngữ lập trình thực hiện các phép tính hoặc hành động khác nhau tùy thuộc vào việc điều kiện boolean do lập trình viên chỉ định đánh giá là đúng hay sai
if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;3 if a > 0 then Put_Line("yes"); else Put_Line("no"); end if; goto label0 if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;0 if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;0 if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;1 Các biến thể ít phổ biến hơn bao gồm
Báo cáo trường hợp và chuyển đổi [ chỉnh sửa ]Các câu lệnh chuyển đổi (hoặc các câu lệnh tình huống hoặc các nhánh nhiều chiều) so sánh một giá trị đã cho với các hằng số đã chỉ định và thực hiện hành động theo hằng số đầu tiên phù hợp. Thường có một điều khoản cho một hành động mặc định ("khác", "nếu không") sẽ được thực hiện nếu không có trận đấu nào thành công. Câu lệnh chuyển đổi có thể cho phép tối ưu hóa trình biên dịch, chẳng hạn như bảng tra cứu. Trong các ngôn ngữ động, các trường hợp có thể không bị giới hạn ở các biểu thức không đổi và có thể mở rộng sang khớp mẫu, như trong ví dụ về tập lệnh trình bao ở bên phải, trong đó if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;61 triển khai trường hợp mặc định dưới dạng toàn cầu khớp với bất kỳ chuỗi nào. Case logic cũng có thể được triển khai ở dạng chức năng, như trong câu lệnh if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;62 của SQLpascal. Ađa. C. kịch bản vỏ. nói ngọng if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;6 if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;0 goto label0 goto label1 goto label2 Vòng lặp là một dãy các câu lệnh được xác định một lần nhưng có thể được thực hiện nhiều lần liên tiếp. Mã "bên trong" vòng lặp (phần thân của vòng lặp, được hiển thị bên dưới là xxx) được tuân theo một số lần nhất định hoặc một lần cho mỗi tập hợp các phần tử hoặc cho đến khi một số điều kiện được đáp ứng hoặc vô thời hạn Trong các ngôn ngữ lập trình chức năng, chẳng hạn như Haskell và Scheme, cả quy trình đệ quy và lặp đều được thể hiện bằng các thủ tục đệ quy đuôi thay vì các cấu trúc lặp theo cú pháp. Các vòng lặp được kiểm soát [ chỉnh sửa ]Hầu hết các ngôn ngữ lập trình đều có cấu trúc để lặp lại một vòng lặp với số lần nhất định. Trong hầu hết các trường hợp, việc đếm có thể đi xuống thay vì lên trên và có thể sử dụng kích thước bước khác 1 goto label3 Trong các ví dụ này, nếu N < 1 thì phần thân của vòng lặp có thể thực thi một lần (với I có giá trị 1) hoặc không thực hiện, tùy thuộc vào ngôn ngữ lập trình Trong nhiều ngôn ngữ lập trình, chỉ các số nguyên mới có thể được sử dụng một cách đáng tin cậy trong vòng lặp kiểm soát số lượng. Các số dấu phẩy động được biểu diễn không chính xác do các ràng buộc về phần cứng, do đó, một vòng lặp chẳng hạn như goto label4 có thể được lặp lại 9 hoặc 10 lần, tùy thuộc vào lỗi làm tròn và/hoặc phần cứng và/hoặc phiên bản trình biên dịch. Hơn nữa, nếu sự gia tăng của X xảy ra do phép cộng lặp lại, thì các lỗi làm tròn tích lũy có thể có nghĩa là giá trị của X trong mỗi lần lặp lại có thể khác khá nhiều so với trình tự dự kiến 0. 1, 0. 2, 0. 3,. , 1. 0 Các vòng điều khiển theo điều kiện[sửa | sửa mã nguồn]Hầu hết các ngôn ngữ lập trình đều có cấu trúc để lặp lại một vòng lặp cho đến khi một số điều kiện thay đổi. Một số biến thể kiểm tra điều kiện khi bắt đầu vòng lặp; . Nếu bài kiểm tra bắt đầu, cơ thể có thể bị bỏ qua hoàn toàn; goto label5 Ngắt kiểm soát là một phương pháp phát hiện thay đổi giá trị được sử dụng trong các vòng lặp thông thường để kích hoạt quá trình xử lý cho các nhóm giá trị. Các giá trị được giám sát trong vòng lặp và một thay đổi sẽ chuyển hướng luồng chương trình sang việc xử lý sự kiện nhóm được liên kết với chúng goto label6 Vòng lặp kiểm soát bộ sưu tập[sửa | sửa mã nguồn]Một số ngôn ngữ lập trình (e. g. , Ada, D, C++11, Smalltalk, PHP, Perl, Object Pascal, Java, C#, MATLAB, Visual Basic, Ruby, Python, JavaScript, Fortran 95 trở lên) có các cấu trúc đặc biệt cho phép lặp ngầm qua tất cả các phần tử của goto label7____18____19 Scala có các biểu thức for, khái quát hóa các vòng lặp do bộ sưu tập kiểm soát và cũng hỗ trợ các mục đích sử dụng khác, chẳng hạn như lập trình không đồng bộ. Haskell có biểu thức do và khả năng hiểu, cùng nhau cung cấp chức năng tương tự như biểu thức for trong Scala Lặp lại chung [ chỉnh sửa ]Các cấu trúc lặp chung như câu lệnh if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;63 của C và dạng goto label00 của Common Lisp có thể được sử dụng để diễn đạt bất kỳ loại vòng lặp nào ở trên và các loại khác, chẳng hạn như lặp song song trên một số tập hợp. Trong trường hợp có thể sử dụng cấu trúc vòng lặp cụ thể hơn, nó thường được ưu tiên hơn cấu trúc lặp chung, vì nó thường làm cho mục đích của biểu thức rõ ràng hơn Vòng lặp vô hạn[sửa]Các vòng lặp vô hạn được sử dụng để đảm bảo một đoạn chương trình lặp lại mãi mãi hoặc cho đến khi một điều kiện đặc biệt phát sinh, chẳng hạn như lỗi. Chẳng hạn, một chương trình hướng sự kiện (chẳng hạn như máy chủ) sẽ lặp lại mãi mãi, xử lý các sự kiện khi chúng xảy ra, chỉ dừng khi quá trình kết thúc bởi một người vận hành Các vòng lặp vô hạn có thể được thực hiện bằng cách sử dụng các cấu trúc luồng điều khiển khác. Thông thường nhất, trong lập trình phi cấu trúc, đây là bước nhảy ngược lại (goto), trong khi trong lập trình có cấu trúc, đây là một vòng lặp không xác định (vòng lặp while) được đặt thành không bao giờ kết thúc, bằng cách bỏ qua điều kiện hoặc đặt nó thành true một cách rõ ràng, như if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;65. Một số ngôn ngữ có cấu trúc đặc biệt cho các vòng lặp vô hạn, thường bằng cách loại bỏ điều kiện khỏi vòng lặp vô hạn. Các ví dụ bao gồm Ada ( if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;66),[4] Fortran ( if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;67), Go ( if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;68) và Ruby ( if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;69) Thông thường, một vòng lặp vô hạn vô tình được tạo ra do lỗi lập trình trong vòng lặp được kiểm soát bởi điều kiện, trong đó điều kiện của vòng lặp sử dụng các biến không bao giờ thay đổi trong vòng lặp Tiếp tục với lần lặp lại tiếp theo[sửa]Đôi khi trong thân vòng lặp có mong muốn bỏ qua phần còn lại của thân vòng lặp và tiếp tục với lần lặp tiếp theo của vòng lặp. Một số ngôn ngữ cung cấp câu lệnh, chẳng hạn như if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;00 (hầu hết các ngôn ngữ), if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;01,[5] hoặc if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;02 (Perl và Ruby), sẽ thực hiện việc này. Hiệu quả là kết thúc sớm thân vòng lặp trong cùng và sau đó tiếp tục như bình thường với lần lặp tiếp theo. Nếu lần lặp là lần cuối cùng trong vòng lặp, hiệu quả là kết thúc sớm toàn bộ vòng lặp Làm lại bước lặp hiện tại[sửa]Một số ngôn ngữ, như Perl[6] và Ruby,[7] có câu lệnh if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;03 khởi động lại bước lặp hiện tại từ đầu Khởi động lại vòng lặp[sửa]Ruby có một câu lệnh if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;04 khởi động lại toàn bộ vòng lặp từ lần lặp đầu tiên. [số 8] Thoát khỏi vòng lặp sớm[sửa]Khi sử dụng vòng lặp kiểm soát số lượng để tìm kiếm trong một bảng, có thể nên dừng tìm kiếm ngay khi tìm thấy mục được yêu cầu. Một số ngôn ngữ lập trình cung cấp một câu lệnh chẳng hạn như if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;2 (hầu hết các ngôn ngữ), if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;06 (Visual Basic) hoặc if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;07 (Perl), có tác dụng chấm dứt vòng lặp hiện tại ngay lập tức và chuyển điều khiển sang câu lệnh ngay sau vòng lặp đó. Một thuật ngữ khác cho các vòng thoát sớm là vòng lặp rưỡi Ví dụ sau đây được thực hiện trong Ada, hỗ trợ cả thoát khỏi vòng lặp sớm và vòng lặp có kiểm tra ở giữa. Cả hai tính năng đều rất giống nhau và so sánh cả hai đoạn mã sẽ cho thấy sự khác biệt. thoát sớm phải được kết hợp với câu lệnh if trong khi điều kiện ở giữa là cấu trúc độc lập if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;30 Python hỗ trợ thực thi mã có điều kiện tùy thuộc vào việc vòng lặp có được thoát sớm (với câu lệnh if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;2) hay không bằng cách sử dụng mệnh đề khác với vòng lặp. Ví dụ, if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;31 Mệnh đề if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;09 trong ví dụ trên được liên kết với câu lệnh if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;63 chứ không phải câu lệnh goto label03 bên trong. Cả hai vòng lặp if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;63 và goto label03 của Python đều hỗ trợ một mệnh đề khác như vậy, mệnh đề này chỉ được thực thi nếu không xảy ra thoát sớm vòng lặp Một số ngôn ngữ hỗ trợ thoát khỏi các vòng lặp lồng nhau; . Một ví dụ sử dụng phổ biến là tìm kiếm một bảng đa chiều. Điều này có thể được thực hiện thông qua ngắt đa mức (ngắt ngoài N mức), như trong bash[9] và PHP,[10] hoặc thông qua ngắt có nhãn (ngắt và tiếp tục ở nhãn đã cho), như trong Java và Perl. [11] Các lựa chọn thay thế cho phá vỡ nhiều cấp độ bao gồm phá vỡ đơn lẻ, cùng với một biến trạng thái được thử nghiệm để phá vỡ một cấp độ khác; . C không bao gồm ngắt đa cấp và cách thay thế thông thường là sử dụng goto để thực hiện ngắt có nhãn. [12] Python không có ngắt hoặc tiếp tục đa cấp – điều này đã được đề xuất trong PEP 3136 và bị từ chối trên cơ sở rằng độ phức tạp được thêm vào không đáng để sử dụng hợp pháp hiếm hoi. [13] Khái niệm phá vỡ đa cấp được một số người quan tâm trong khoa học máy tính lý thuyết, bởi vì nó tạo ra cái mà ngày nay được gọi là hệ thống phân cấp Kosaraju. [14] Năm 1973 S. Rao Kosaraju đã tinh chỉnh định lý chương trình có cấu trúc bằng cách chứng minh rằng có thể tránh thêm các biến bổ sung trong lập trình có cấu trúc, miễn là cho phép ngắt vòng lặp ở nhiều cấp độ, độ sâu tùy ý. [15] Hơn nữa, Kosaraju đã chứng minh rằng tồn tại một hệ thống phân cấp nghiêm ngặt của các chương trình. với mọi số nguyên n, tồn tại một chương trình chứa ngắt đa cấp có độ sâu n không thể viết lại thành chương trình có ngắt đa cấp có độ sâu nhỏ hơn n mà không đưa vào các biến bổ sung. [14] Người ta cũng có thể thoát khỏi một chương trình con đang thực thi các câu lệnh lặp, thoát ra khỏi cả vòng lặp lồng nhau và chương trình con. Có các cấu trúc kiểm soát được đề xuất khác cho nhiều lần ngắt, nhưng thay vào đó, chúng thường được triển khai dưới dạng ngoại lệ Trong cuốn sách giáo khoa năm 2004 của mình, David Watt sử dụng khái niệm trình tự sắp xếp của Tennent để giải thích sự giống nhau giữa ngắt đa cấp và câu lệnh trả về. Watt lưu ý rằng một lớp trình sắp xếp thứ tự được gọi là trình tự thoát, được định nghĩa là "trình sắp xếp thứ tự kết thúc việc thực thi lệnh hoặc thủ tục kèm theo văn bản", bao gồm cả ngắt khỏi vòng lặp (bao gồm cả ngắt đa cấp) và câu lệnh trả về. Tuy nhiên, như thường được triển khai, trình tự trả về cũng có thể mang giá trị (trả về), trong khi trình sắp xếp ngắt như được triển khai trong các ngôn ngữ hiện đại thường không thể. [16] Các biến thể và bất biến của vòng lặp[sửa | sửa mã nguồn]Các biến thể vòng lặp và bất biến vòng lặp được sử dụng để thể hiện tính đúng đắn của các vòng lặp. [17] Về mặt thực tế, một biến thể của vòng lặp là một biểu thức số nguyên có giá trị ban đầu không âm. Giá trị của biến thể phải giảm trong mỗi lần lặp lại vòng lặp nhưng không bao giờ được âm trong quá trình thực hiện đúng vòng lặp. Các biến thể của vòng lặp được sử dụng để đảm bảo rằng các vòng lặp sẽ kết thúc Bất biến vòng lặp là một khẳng định phải đúng trước lần lặp đầu tiên và vẫn đúng sau mỗi lần lặp. Điều này ngụ ý rằng khi một vòng lặp kết thúc chính xác, cả điều kiện thoát và bất biến vòng lặp đều được thỏa mãn. Bất biến vòng lặp được sử dụng để theo dõi các thuộc tính cụ thể của vòng lặp trong các lần lặp liên tiếp Một số ngôn ngữ lập trình, chẳng hạn như Eiffel có hỗ trợ riêng cho các biến thể và bất biến của vòng lặp. Trong các trường hợp khác, hỗ trợ là một tiện ích bổ sung, chẳng hạn như đặc tả của Ngôn ngữ mô hình hóa Java cho các câu lệnh vòng lặp trong Java Ngôn ngữ con vòng lặp [ chỉnh sửa ]Một số phương ngữ Lisp cung cấp một ngôn ngữ con mở rộng để mô tả Vòng lặp. Một ví dụ ban đầu có thể được tìm thấy trong Lisp chuyển đổi của Interlisp. Common Lisp[18] cung cấp macro Vòng lặp triển khai ngôn ngữ con như vậy Bảng tham chiếu chéo hệ thống vòng lặp[sửa]
Luồng điều khiển phi cục bộ có cấu trúc[sửa | sửa mã nguồn]Nhiều ngôn ngữ lập trình, đặc biệt là những ngôn ngữ thiên về phong cách lập trình năng động hơn, cung cấp các cấu trúc cho luồng điều khiển phi cục bộ. Những điều này làm cho luồng thực thi nhảy ra khỏi ngữ cảnh nhất định và tiếp tục tại một số điểm được khai báo trước. Điều kiện, ngoại lệ và phần tiếp theo là ba loại phổ biến của cấu trúc điều khiển không cục bộ; Điều kiện[sửa]PL/I có khoảng 22 điều kiện tiêu chuẩn (e. g. , ZERODIVIDE SUBSCRIPTRANGE ENDFILE) có thể được nâng lên và có thể bị chặn bởi. Hành động điều kiện BẬT; Giống như nếu không có cấu trúc, chỉ có thể chỉ định một câu lệnh, vì vậy trong nhiều trường hợp, GOTO là cần thiết để quyết định nơi luồng điều khiển sẽ tiếp tục Thật không may, một số triển khai có chi phí đáng kể cả về không gian và thời gian (đặc biệt là SUBSCRIPTRANGE), vì vậy nhiều lập trình viên đã cố gắng tránh sử dụng các điều kiện Các ví dụ cú pháp phổ biến if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;32 Ngoại lệ[sửa]Các ngôn ngữ hiện đại có cấu trúc cấu trúc chuyên biệt để xử lý ngoại lệ không phụ thuộc vào việc sử dụng ngắt hoặc trả về goto label12 hoặc (đa cấp). Ví dụ, trong C++ người ta có thể viết if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;33 Bất kỳ số lượng và sự đa dạng của mệnh đề goto label13 nào cũng có thể được sử dụng ở trên. Nếu không có goto label13 khớp với một goto label15 cụ thể, điều khiển sẽ lặp lại thông qua các lệnh gọi chương trình con và/hoặc các khối lồng nhau cho đến khi tìm thấy một goto label13 phù hợp hoặc cho đến khi kết thúc chương trình chính, tại thời điểm đó chương trình bị buộc dừng với một lỗi phù hợp Do ảnh hưởng của C++, goto label13 là từ khóa dành riêng để khai báo một trình xử lý ngoại lệ khớp mẫu trong các ngôn ngữ khác phổ biến hiện nay, như Java hoặc C#. Một số ngôn ngữ khác như Ada sử dụng từ khóa goto label18 để giới thiệu một trình xử lý ngoại lệ và sau đó thậm chí có thể sử dụng một từ khóa khác ( if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;17 trong Ada) để khớp mẫu. Một vài ngôn ngữ như AppleScript kết hợp trình giữ chỗ trong cú pháp xử lý ngoại lệ để tự động trích xuất một số thông tin khi ngoại lệ xảy ra. Cách tiếp cận này được minh họa bên dưới bằng cấu trúc goto label20 từ AppleScript if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;34 Sách giáo khoa năm 2004 của David Watt cũng phân tích việc xử lý ngoại lệ trong khuôn khổ trình sắp xếp thứ tự (được giới thiệu trong bài viết này trong phần thoát khỏi vòng lặp sớm). Watt lưu ý rằng một tình huống bất thường, thường được minh họa bằng lỗi tràn số học hoặc lỗi đầu vào/đầu ra như không tìm thấy tệp, là một loại lỗi "được phát hiện trong một số đơn vị chương trình cấp thấp, nhưng [đối với đó] một trình xử lý nằm ở vị trí tự nhiên hơn . Ví dụ: một chương trình có thể chứa một số lệnh gọi để đọc tệp, nhưng hành động thực hiện khi không tìm thấy tệp phụ thuộc vào ý nghĩa (mục đích) của tệp được đề cập đối với chương trình và do đó không thể xử lý thường trình cho tình huống bất thường này. . Watts lưu ý thêm rằng việc giới thiệu kiểm tra cờ trạng thái trong trình gọi, vì lập trình có cấu trúc một lối ra hoặc thậm chí (nhiều lối ra) trả về trình tự sẽ đòi hỏi, dẫn đến tình huống "mã ứng dụng có xu hướng bị lộn xộn do kiểm tra cờ trạng thái" và . Trên thực tế, các tình huống bất thường được biểu thị bằng cờ trạng thái theo mặc định sẽ bị bỏ qua. " Watt lưu ý rằng trái ngược với kiểm tra cờ trạng thái, các ngoại lệ có hành vi mặc định ngược lại, khiến chương trình kết thúc trừ khi lập trình viên xử lý ngoại lệ một cách rõ ràng theo một cách nào đó, có thể bằng cách thêm mã rõ ràng để bỏ qua nó. Dựa trên những lập luận này, Watt kết luận rằng trình tự nhảy hoặc trình tự thoát không phù hợp như một trình sắp xếp ngoại lệ chuyên dụng với ngữ nghĩa đã thảo luận ở trên. [21] Trong Object Pascal, D, Java, C# và Python, mệnh đề goto label21 có thể được thêm vào cấu trúc goto label22. Cho dù điều khiển rời khỏi goto label22 như thế nào thì mã bên trong mệnh đề goto label21 vẫn được đảm bảo thực thi. Điều này hữu ích khi viết mã phải từ bỏ một tài nguyên đắt tiền (chẳng hạn như tệp đã mở hoặc kết nối cơ sở dữ liệu) khi xử lý xong if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;35 Vì mẫu này khá phổ biến nên C# có một cú pháp đặc biệt if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;36 Khi rời khỏi khối goto label25, trình biên dịch đảm bảo rằng đối tượng goto label26 được giải phóng, liên kết hiệu quả biến với luồng tệp trong khi trừu tượng hóa khỏi các tác dụng phụ của việc khởi tạo và giải phóng tệp. Câu lệnh goto label27 của Python và đối số khối của Ruby đối với goto label28 được sử dụng để tạo hiệu ứng tương tự Tất cả các ngôn ngữ được đề cập ở trên xác định các ngoại lệ tiêu chuẩn và các trường hợp mà chúng được đưa ra. Người dùng có thể đưa ra các ngoại lệ của riêng họ; Tiếp tục [ chỉnh sửa ]C#5. 0 đã giới thiệu từ khóa async để hỗ trợ I/O không đồng bộ theo "kiểu trực tiếp" Máy phát điện[sửa]Trình tạo, còn được gọi là semicoroutines, cho phép tạm thời chuyển quyền kiểm soát sang phương thức người tiêu dùng, thường sử dụng từ khóa goto label30 (mô tả năng suất). Giống như từ khóa async, điều này hỗ trợ lập trình theo "kiểu trực tiếp" Coroutines [ chỉnh sửa ]Coroutines là các chức năng có thể trao quyền kiểm soát cho nhau - một dạng đa nhiệm hợp tác không có luồng Các coroutine có thể được triển khai như một thư viện nếu ngôn ngữ lập trình cung cấp phần tiếp theo hoặc trình tạo - vì vậy sự khác biệt giữa coroutine và trình tạo trong thực tế là một chi tiết kỹ thuật Tham chiếu chéo luồng điều khiển không cục bộ[sửa | sửa mã nguồn]Các cấu trúc điều khiển được đề xuất[sửa | sửa mã nguồn]Trong một bài báo giả mạo Datamation[28] năm 1973, R. Lawrence Clark gợi ý rằng câu lệnh GOTO có thể được thay thế bằng câu lệnh COMEFROM và cung cấp một số ví dụ thú vị. COMEFROM được triển khai bằng một ngôn ngữ lập trình bí truyền có tên INTERCAL Bài báo năm 1974 của Donald Knuth "Lập trình có cấu trúc với các câu lệnh đi tới",[29] xác định hai tình huống không được bao phủ bởi các cấu trúc điều khiển được liệt kê ở trên và đưa ra ví dụ về các cấu trúc điều khiển có thể xử lý các tình huống này. Mặc dù tiện ích, nhưng các cấu trúc này vẫn chưa tìm được đường vào các ngôn ngữ lập trình chính thống Vòng lặp với bài kiểm tra ở giữa[sửa | sửa mã nguồn]Điều sau đây được đề xuất bởi Dahl vào năm 1972. [30] if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;37 Nếu xxx1 bị bỏ qua, chúng ta sẽ nhận được một vòng lặp với phép thử ở trên cùng (vòng lặp while truyền thống). Nếu bỏ qua xxx2, chúng ta sẽ nhận được một vòng lặp có dấu kiểm ở dưới cùng, tương đương với vòng lặp do while trong nhiều ngôn ngữ. Nếu while bị bỏ qua, chúng ta sẽ có một vòng lặp vô hạn. Việc xây dựng ở đây có thể được coi như một vòng lặp do với kiểm tra trong khi ở giữa. Do đó cấu trúc đơn lẻ này có thể thay thế một số cấu trúc trong hầu hết các ngôn ngữ lập trình Các ngôn ngữ thiếu cấu trúc này thường mô phỏng nó bằng cách sử dụng thành ngữ vòng lặp vô tận tương đương if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;38 Một biến thể có thể là cho phép nhiều hơn một trong khi thử nghiệm; Trong Ada, cấu trúc vòng lặp ở trên (vòng lặp-trong khi-lặp lại) có thể được biểu diễn bằng cách sử dụng một vòng lặp vô hạn tiêu chuẩn (vòng lặp - vòng lặp kết thúc) có mệnh đề exit when ở giữa (đừng nhầm với câu lệnh exitwhen trong phần sau if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;39 Đặt tên cho một vòng lặp (như Read_Data trong ví dụ này) là tùy chọn nhưng cho phép rời khỏi vòng lặp bên ngoài của một số vòng lặp lồng nhau Nhiều lần thoát/thoát khỏi vòng lặp lồng nhau[sửa]Điều này đã được đề xuất bởi Zahn vào năm 1974. [31] Một phiên bản sửa đổi được trình bày ở đây if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;0 exitkhi được sử dụng để chỉ định các sự kiện có thể xảy ra trong xxx, sự xuất hiện của chúng được biểu thị bằng cách sử dụng tên của sự kiện làm câu lệnh. Khi một số sự kiện xảy ra, hành động có liên quan được thực hiện và sau đó kiểm soát sẽ chuyển ngay sau endexit. Cấu trúc này cung cấp một sự tách biệt rất rõ ràng giữa việc xác định rằng một số tình huống áp dụng và hành động được thực hiện cho tình huống đó exitwhen về mặt khái niệm tương tự như xử lý ngoại lệ và các ngoại lệ hoặc cấu trúc tương tự được sử dụng cho mục đích này trong nhiều ngôn ngữ Ví dụ đơn giản sau liên quan đến việc tìm kiếm một bảng hai chiều cho một mục cụ thể if a > 0 then Put_Line("yes"); else Put_Line("no"); end if;1 Bảo mật[sửa]Một cách để tấn công một phần mềm là chuyển hướng luồng thực thi của một chương trình. Một loạt các kỹ thuật kiểm soát tính toàn vẹn của luồng, bao gồm ngăn xếp canaries, bảo vệ tràn bộ đệm, ngăn xếp bóng tối và xác minh con trỏ vtable, được sử dụng để chống lại các cuộc tấn công này. [32][33][34] Điều khiển luồng trong lập trình là gì?Luồng điều khiển là thứ tự mà máy tính thực thi các câu lệnh trong tập lệnh . Mã được chạy theo thứ tự từ dòng đầu tiên trong tệp đến dòng cuối cùng, trừ khi máy tính chạy qua các cấu trúc (cực kỳ thường xuyên) làm thay đổi luồng điều khiển, chẳng hạn như điều kiện và vòng lặp.
3 loại luồng điều khiển là gì?Luồng điều khiển thông qua bất kỳ chức năng nhất định nào được triển khai với ba loại cấu trúc điều khiển cơ bản. . tuần tự. chế độ mặc định. . Lựa chọn. được sử dụng cho các quyết định, phân nhánh -- lựa chọn giữa 2 hoặc nhiều đường dẫn thay thế. . sự lặp lại. được sử dụng để lặp, tôi. e. lặp lại một đoạn mã nhiều lần liên tiếp Một ví dụ về kiểm soát dòng chảy là gì?Ví dụ về kỹ thuật Kiểm soát luồng là. Giao thức Dừng&Chờ và Giao thức Cửa sổ trượt . Ví dụ về các kỹ thuật kiểm soát lỗi là. ARQ Dừng&Chờ và ARQ Cửa sổ trượt.
3 loại cấu trúc điều khiển trong PHP là gì?Cấu trúc điều khiển PHP . Câu điều kiện. Câu lệnh có điều kiện cho phép bạn phân nhánh đường dẫn thực thi trong tập lệnh dựa trên việc một hoặc nhiều điều kiện, đánh giá là đúng hay sai. . Tuyên bố khác Câu lệnh Else If vòng điều khiển. . Đối với vòng lặp Vòng lặp mới này đã được giới thiệu trong phiên bản PHP 4 |