Aliran kawalan

Dalam sains komputer, **aliran kawalan** (juga **struktur kawalan**) ialah susunan pernyataan individu, arahan atau panggilan fungsi bagi atur cara imperatif yang dilaksanakan atau dinilai. Penekanan pada aliran kawalan eksplisit membezakan bahasa *[[pengaturcaraan imperatif]]* daripada bahasa *[[Pengaturcaraan penyata|pengaturcaraan deklaratif]]*.

Dalam bahasa pengaturcaraan imperatif, *pernyataan aliran kawalan* ialah pernyataan yang menghasilkan pilihan dibuat terhadap dua atau lebih laluan untuk diikuti. Bagi bahasa fungsian yang tidak ketat, fungsi dan binaan bahasa wujud untuk mencapai hasil yang sama, tetapi ia biasanya tidak dipanggil sebagaii penyataan aliran kawalan.

Satu set pernyataan pula secara amnya distrukturkan sebagai blok, yang selain daripada pengelompokan, juga mentakrifkan skop leksikal.

Gangguan dan isyarat ialah mekanisme peringkat rendah yang boleh mengubah aliran kawalan dengan cara yang serupa dengan subrutin, tetapi biasanya berlaku sebagai tindak balas kepada beberapa rangsangan atau peristiwa luaran (yang boleh berlaku secara tidak segerak), dan bukannya pelaksanaan aliran kawalan *pada talian*.

Pada peringkat bahasa mesin atau bahasa himpunan, arahan aliran kawalan biasanya berfungsi dengan mengubah pembilang program. Bagi sesetengah unit pemprosesan pusat (CPU), satu-satunya arahan aliran kawalan yang tersedia ialah arahan cabang bersyarat atau tidak bersyarat, juga dipanggil "lompatan".

## Kategori

Jenis penyataan aliran kawalan yang disokong oleh bahasa yang berbeza berbeza-beza, tetapi boleh dikategorikan mengikut kesannya:

* Sambungan pada pernyataan yang berbeza (cabang tanpa syarat atau lompatan)
* Melaksanakan set pernyataan hanya jika beberapa syarat dipenuhi (pilihan - iaitu cabang bersyarat)
* Melaksanakan set pernyataan sifar atau lebih kali, sehingga beberapa syarat dipenuhi (gelung - sama seperti cawangan bersyarat)
* Melaksanakan set pernyataan berlainan, selepas itu aliran kawalan biasanya kembali (subrutin, korutin dan sambungan)
* Menghentikan program, lalu menghalang sebarang pelaksanaan selanjutnya (berhenti tanpa syarat)

## Primitif

### Label
Label ialah nama atau nombor eksplisit yang diberikan kepada kedudukan tetap dalam kod sumber, dan boleh dirujuk oleh pernyataan aliran kawalan yang muncul di tempat lain dalam kod sumber. Label menandakan kedudukan dalam kod sumber dan tidak mempunyai kesan lain.

Nombor baris ialah alternatif kepada label bernama yang digunakan dalam beberapa bahasa (seperti BASIC). Ia adalah nombor bulat yang diletakkan pada permulaan setiap baris teks dalam kod sumber. Bahasa yang menggunakan ini selalunya mengenakan kekangan bahawa nombor baris mesti meningkat dalam nilai dalam setiap baris berikut, tetapi mungkin tidak memerlukannya berturut-turut. Sebagai contoh, dalam BASIC:
```qbasic
10 LET X = 3
20 PRINT X
```
Dalam bahasa lain seperti C dan Ada, label bertindak sebagai pengecam, biasanya muncul pada permulaan baris dan serta-merta diikuti dengan titik bertindih. Sebagai contoh, dalam C:
```c
Success: printf("The operation was successful.\n");
```
Bahasa ALGOL 60 membenarkan kedua-dua nombor bulat dan pengecam sebagai label (kedua-duanya dipautkan oleh titik bertindih kepada pernyataan berikut), tetapi sedikit jika ada varian ALGOL lain membenarkan nombor bulat. Penyusun Fortran awal hanya membenarkan nombor bulat sebagai label. Bermula dengan Fortran-90, label alfanumerik juga telah dibenarkan.

## Jenis struktur kawalan
Kebanyakan bahasa pengaturcaraan dengan struktur kawalan mempunyai kata kunci awal yang menunjukkan jenis struktur kawalan yang terlibat. Bahasa-bahasa ini kemudian dibahagikan sama ada struktur kawalannya mempunyai kata kunci akhir atau tidak.

* Tiada kata kunci akhir: ALGOL 60, C, C++, Haskell, Java, Pascal, Perl, PHP, PL/I, Python dan PowerShell. Bahasa sedemikian memerlukan beberapa cara untuk mengumpulkan pernyataan bersama:
** ALGOL 60 dan Pascal: `begin` ... `end`
** C, C++, Java, Perl, PHP dan PowerShell: kurungan kerinting `{` . . . `}`
** PL/I: `DO` . . . `END`
** Python: menggunakan tahap inden
** Haskell: sama ada aras inden atau kurungan kerinting, dan boleh digunakan secara bercampur
** Lua: menggunakan `do` ... `end`
* Kata kunci akhir: Ada, ALGOL 68, Modula-2, Fortran 77, Mythryl, Visual Basic. Bentuk kata kunci akhir berbeza-beza:
** Ada: kata kunci akhir ialah `end` + *ruang* + kata kunci awal cth, `if` ... `end if`, `loop` ... `end loop`
** ALGOL 68, Mythryl: kata kunci awal yang dieja ke belakang cth, `if` ... `fi`, `case` ... `esac`
** Fortran 77: kata kunci akhir ialah `END` + kata kunci awal cth, `IF` . . . `ENDIF`, `DO` . . . `ENDDO`
** Modula-2: kata kunci akhir yang sama `END` untuk semuanya
** Visual Basic: setiap struktur kawalan mempunyai kata kunci sendiri. `If` . . . `End If` ; `For` . . . `Next` ; `Do` . . . `Loop` ; `While` . . . `Wend`

## Gelung
Gelung (*loop*) ialah urutan pernyataan yang dinyatakan sekali tetapi boleh dijalankan beberapa kali berturut-turut. Kod "di dalam" gelung (*badan* gelung, ditunjukkan di bawah sebagai *xxx*) dipatuhi beberapa kali tertentu, atau sekali untuk setiap koleksi item, atau sehingga beberapa syarat dipenuhi, atau selama-lamanya.

Dalam bahasa pengaturcaraan kefungsian seperti Haskell dan Scheme, gelung boleh dinyatakan dengan menggunakan rekursi atau lelaran titik tetap dan bukannya binaan gelung eksplisit. Rekursi ekor ialah kes pengulangan khas yang boleh diubah dengan mudah menjadi lelaran.

### Gelung dikawal kiraan
Kebanyakan bahasa pengaturcaraan mempunyai pembinaan untuk mengulang gelung beberapa kali. Dalam kebanyakan kes, pengiraan boleh pergi ke bawah dan bukannya ke atas dan saiz langkah selain daripada 1 boleh digunakan.

    FOR I = 1 TO N           | **for** I := 1 **to** N **do** **begin**
        xxx                  |     xxx
    NEXT I                   | **end**;
 ------------------------------------------------------------
    DO I = 1,N               | **for** ( I=1; I current-zipcode
          display_tally(current-zipcode, zipcount)
          
          current-zipcode = new-zipcode
          zipcount = 0
       ENDIF
       
       zipcount++
    LOOP

### Gelung dikawal koleksi
Sebilangan bahasa pengaturcaraan (seperti Ada, D, C++11, Smalltalk, PHP, Perl, Object Pascal, Java, C#, MATLAB, Visual Basic, Ruby, Python, JavaScript, Fortran 95 dan lebih baru) mempunyai binaan khas yang membenarkan tersirat menggelung melalui semua elemen tatasusunan, atau semua ahli set atau koleksi.

    someCollection **do**: [:eachElement |xxx].

    **for** Item **in** Collection **do** **begin** xxx **end**;
 
    **foreach** (item; myCollection) { xxx }
 
    **foreach** someArray { xxx }
 
    **foreach** ($someArray as $k => $v) { xxx }
 
    Collection coll; **for** (String s : coll) {}
 
    **foreach** (**string** s **in** myStringCollection) { xxx }
 
    someCollection | ForEach-Object { $_ }

    **forall** ( index = first:last:step... )

Scala mempunyai ekspresi *for* yang menyamaratakan gelung terkawal koleksi, dan juga menyokong kegunaan lain, seperti pengaturcaraan tak segerak. Haskell mempunyai eskpresi dan pemahaman *do*, yang bersama-sama menyediakan fungsi yang serupa dengan ungkapan *for* dalam Scala.

### Gelung tak terhingga
Gelung tak terhingga digunakan untuk memastikan gelung segmen program berlaku selama-lamanya atau sehingga keadaan khas timbul seperti ralat. Sebagai contoh, atur cara dipacu peristiwa (seperti dalampelayan) harus bergelung selama-lamanya, mengendalikan peristiwa semasa ia berlaku, dan hanya berhenti apabila proses ditamatkan oleh pengendali.

Selalunya, gelung tak terhingga tercipta secara tidak sengaja oleh ralat pengaturcaraan dalam gelung dikawal keadaan, di mana keadaan gelung menggunakan pemboleh ubah dengan nilai yang tidak pernah berubah dalam gelung.