Sabtu, 17 Oktober 2026
14:00 WIB
TERKINI
Universitas Teknokrat Indonesia Mahasiswa Universitas Teknokrat Raih Empat Gelar Bergengsi di Kompetisi Bahasa Inggris Nasional Pesisir Barat Pesisir Barat Jalin Kemitraan Strategis, Dorong Akses Pendidikan Tinggi Terjangkau Universitas Teknokrat Indonesia Teknokrat dan PMD Pesawaran Bersinergi Wujudkan Desa Digital Berkelanjutan Humaniora Memperkuat Hak Konstitusional Perempuan Adat untuk Kedaulatan Bangsa Pesawaran Lampung Dorong Rantai Pasok Hijau Kakao, Kopi, Lada ke Pasar Global Pesawaran Pengalihan Status Guru PPPK ke Penuh Waktu: DPRD Pesawaran Soroti Isu Penempatan Lampung Timur Gotong Royong Fantastis: Warga Bandar Agung Himpun Rp15 Miliar untuk Jalan Desa Bandar Lampung JNE Lampung Sukses Ubah Komplain Milea Cutting Jadi Kemitraan Strategis Bandar Lampung Jadwal Padat Pemprov Lampung 16 Oktober 2026: Pisah Sambut Kapolda dan Rapat Strategis Bandar Lampung Lampung Waspada: BMKG Deteksi 212 Titik Panas di Sepuluh Kabupaten Universitas Teknokrat Indonesia Mahasiswa Universitas Teknokrat Raih Empat Gelar Bergengsi di Kompetisi Bahasa Inggris Nasional Pesisir Barat Pesisir Barat Jalin Kemitraan Strategis, Dorong Akses Pendidikan Tinggi Terjangkau Universitas Teknokrat Indonesia Teknokrat dan PMD Pesawaran Bersinergi Wujudkan Desa Digital Berkelanjutan Humaniora Memperkuat Hak Konstitusional Perempuan Adat untuk Kedaulatan Bangsa Pesawaran Lampung Dorong Rantai Pasok Hijau Kakao, Kopi, Lada ke Pasar Global Pesawaran Pengalihan Status Guru PPPK ke Penuh Waktu: DPRD Pesawaran Soroti Isu Penempatan Lampung Timur Gotong Royong Fantastis: Warga Bandar Agung Himpun Rp15 Miliar untuk Jalan Desa Bandar Lampung JNE Lampung Sukses Ubah Komplain Milea Cutting Jadi Kemitraan Strategis Bandar Lampung Jadwal Padat Pemprov Lampung 16 Oktober 2026: Pisah Sambut Kapolda dan Rapat Strategis Bandar Lampung Lampung Waspada: BMKG Deteksi 212 Titik Panas di Sepuluh Kabupaten

Control flow

Bagikan:
Bagaimana perangkat lunak berkembang selama implementasinyaTemplat:SHORTDESC:Bagaimana perangkat lunak berkembang selama implementasinya
Artikel ini bukan mengenai Flow control (data).

Dalam perangkat lunak, alur kendali (atau aliran kendali) menjelaskan bagaimana eksekusi berpindah dari satu perintah ke perintah berikutnya. Dalam banyak konteks, seperti kode mesin dan bahasa pemrograman imperatif, kendali berlangsung secara berurutan (menuju perintah yang terletak tepat setelah perintah yang sedang dieksekusi), kecuali ketika sebuah perintah memindahkan kendali ke titik lain — dalam hal ini perintah tersebut diklasifikasikan sebagai perintah alur kendali. Bergantung pada konteksnya, istilah lain dapat digunakan sebagai pengganti perintah. Misalnya, dalam kode mesin, istilah yang lazim digunakan adalah instruksi, sedangkan dalam bahasa imperatif, istilah yang lazim digunakan adalah pernyataan.

Meskipun bahasa imperatif mengodekan alur kendali secara eksplisit, bahasa dengan paradigma pemrograman lain tidak terlalu berfokus pada alur kendali. Bahasa deklaratif menentukan hasil yang diinginkan tanpa menetapkan urutan operasi. Bahasa fungsional menggunakan konstruksi bahasa dan fungsi untuk mengendalikan alur, meskipun biasanya konstruksi tersebut tidak disebut sebagai pernyataan alur kendali.

Dalam unit pemrosesan pusat set instruksi, instruksi alur kendali sering mengubah program counter dan berupa percabangan tanpa syarat (disebut juga lompatan) atau percabangan bersyarat. Pendekatan alternatif adalah predikasi, yang mengaktifkan instruksi secara bersyarat alih-alih melakukan percabangan.

Pemindahan alur kendali asinkron, seperti interupsi atau sinyal, mengubah alur kendali normal menuju sebuah penangan sebelum mengembalikan kendali ke tempat ketika alur tersebut diinterupsi.

Salah satu cara untuk menyerang perangkat lunak adalah dengan mengalihkan alur eksekusi. Berbagai teknik control-flow integrity, termasuk stack canary, perlindungan buffer overflow, shadow stack, dan verifikasi penunjuk vtable, digunakan untuk bertahan terhadap serangan tersebut.[1][2][3]

Struktur

Alur kendali berkaitan erat dengan struktur kode. Alur kendali mengikuti jalur yang ditentukan oleh struktur dan aturan eksekusi suatu bahasa. Konsep umum mengenai struktur ini tidak boleh disamakan dengan pemrograman terstruktur, yang membatasi struktur pada pengurutan, seleksi, dan iterasi berdasarkan organisasi blok.

Urutan

Eksekusi berurutan merupakan struktur yang paling dasar. Meskipun tidak semua kode bersifat berurutan, kode imperatif bersifat demikian.

Label

Sebuah label mengidentifikasi suatu posisi dalam kode sumber. Beberapa pernyataan alur kendali merujuk pada label sehingga kendali dapat melompat ke baris yang diberi label. Selain menandai suatu posisi, label tidak memiliki efek lain.

Beberapa bahasa membatasi label hanya pada angka yang terkadang disebut nomor baris, meskipun istilah tersebut menyiratkan indeks bawaan dari baris tersebut, bukan sebuah label. Meskipun demikian, label numerik seperti ini biasanya diwajibkan meningkat dari atas ke bawah dalam sebuah berkas, meskipun tidak harus berurutan. Misalnya, dalam BASIC:

10LETX=3
20PRINTX
30GOTO10

Dalam banyak bahasa, label merupakan pengenal alfanumerik, biasanya muncul di awal baris dan langsung diikuti titik dua. Misalnya, kode C berikut mendefinisikan label Success pada baris 3 yang mengidentifikasi titik tujuan lompatan pada pernyataan pertama yang mengikutinya (baris 4).

voidf(boolok){
if(ok){
gotosuccess;
}
return;
success:
printf("OK");
}

Blok

Sebagian besar bahasa menyediakan cara untuk mengorganisasikan urutan kode sebagai sebuah blok. Ketika digunakan bersama pernyataan kendali, awal sebuah blok menyediakan tujuan lompatan. Misalnya, pada kode C berikut (yang menggunakan kurung kurawal untuk membatasi sebuah blok), kendali melompat dari baris 1 ke baris 4 jika done bernilai false.

if(done){
printf("All done");
}else{
printf("Still workin' on it");
}

Kendali

Banyak perintah kendali telah dirancang untuk bahasa pemrograman. Bagian ini menjelaskan konstruksi yang penting dan diorganisasikan berdasarkan fungsinya.

Fungsi

Sebuah fungsi menyediakan alur kendali karena ketika dipanggil, eksekusi melompat ke awal kode fungsi tersebut dan ketika fungsi selesai, kendali kembali ke titik pemanggilannya. Dalam kode C berikut, kendali melompat dari baris 6 ke baris 2 untuk memanggil fungsi foo(). Kemudian, setelah tubuh fungsi selesai (mencetak "Hi"), kendali kembali ke setelah pemanggilan, yaitu baris 7.

voidfoo(){
printf("Hi");
}

voidbar(){
foo();
printf("Done");
}

Percabangan

Perintah percabangan memindahkan titik eksekusi dari titik dalam kode yang memuat perintah tersebut ke titik yang ditentukan oleh perintah.

Lompatan

Perintah lompatan secara tidak bersyarat melakukan percabangan kendali ke titik lain dalam kode, dan merupakan bentuk paling dasar untuk mengendalikan alur kode.

Dalam bahasa tingkat tinggi, hal ini sering disediakan sebagai pernyataan goto. Meskipun kata kunci tersebut dapat ditulis dengan huruf besar atau kecil atau terdiri dari satu atau dua kata, bergantung pada bahasanya, bentuknya seperti: goto label. Ketika kendali mencapai pernyataan goto, kendali kemudian melompat ke pernyataan setelah label yang ditunjukkan. Pernyataan goto telah dianggap berbahaya oleh banyak ilmuwan komputer, termasuk Dijkstra.

Percabangan bersyarat

Pernyataan bersyarat memindahkan kendali berdasarkan nilai suatu ekspresi Boolean. Variasi yang umum meliputi:

if-goto
Melompat ke sebuah label berdasarkan suatu kondisi; pernyataan pemrograman tingkat tinggi yang sangat menyerupai instruksi kode mesin yang sejenis
if-then
Alih-alih terbatas pada lompatan, sebuah pernyataan atau blok dieksekusi jika ekspresi bernilai benar. Dalam bahasa yang tidak memiliki kata kunci then, konstruksi ini dapat disebut pernyataan if.
if-then-else
Seperti if-then, tetapi dengan tindakan kedua yang dilakukan jika kondisi bernilai salah. Dalam bahasa yang tidak memiliki kata kunci then, konstruksi ini dapat disebut pernyataan if-else.
Bersarang
Pernyataan bersyarat sering ditempatkan di dalam pernyataan bersyarat lainnya.
if aritmetika
Fortran awal memiliki if aritmetika (disebut juga if tiga arah) yang menguji apakah suatu nilai numerik negatif, nol, atau positif. Pernyataan ini dinyatakan usang dalam Fortran-90 dan dihapus sejak Fortran 2018.
Operator
Beberapa bahasa memiliki bentuk operator, seperti operator kondisional ternary.
When dan unless
Perl melengkapi if bergaya C dengan when dan unless.
Pesan
Smalltalk menggunakan pesan ifTrue dan ifFalse untuk mengimplementasikan kondisi, bukan konstruksi bahasa.

Kode Pascal berikut menunjukkan if-then-else sederhana. Sintaksnya mirip dengan Ada:

ifa>0then
writeln("yes")
else
writeln("no");

Dalam C:

if(a>0){
puts("yes");
}else{
puts("no");
}

Dalam bash:

if[$a-gt0];then
echo"yes"
else
echo"no"
fi

Dalam Python:

if a > 0: 
    print("yes")
else:
    print("no")

Dalam Lisp:

(princ
(if(pluspa)
"yes"
"no"))

Percabangan multiarah

Percabangan multiarah memindahkan kendali berdasarkan pencocokan nilai. Biasanya tersedia tindakan bawaan jika tidak ditemukan kecocokan. Sebuah pernyataan switch dapat memungkinkan pengoptimalan oleh kompiler, seperti tabel pencarian. Dalam bahasa dinamis, kasus mungkin tidak terbatas pada ekspresi konstan dan dapat diperluas ke pencocokan pola, seperti pada contoh shell script di sebelah kanan, yang menggunakan *) untuk mengimplementasikan kasus bawaan sebagai glob yang cocok dengan string apa pun. Logika case juga dapat diimplementasikan dalam bentuk fungsional, seperti pernyataan decode dalam SQL.

Kode Pascal berikut menunjukkan pernyataan switch yang relatif sederhana. Pascal menggunakan kata kunci case alih-alih switch.

casesomeCharof
'a':actionOnA;
'x':actionOnX;
'y','z':actionOnYandZ;
elseactionOnNoMatch;
end;

Dalam Ada:

case someChar is
  when 'a' => actionOnA;
  when 'x' => actionOnX;
  when 'y' | 'z' => actionOnYandZ;
  when others => actionOnNoMatch;
end;

Dalam C:

switch(someChar){
case'a':
actionOnA;
break;
case'x':
actionOnX;
break;
case'y':
case'z':
actionOnYandZ;
break;
default:
actionOnNoMatch;
}

Dalam Bash:

case$someCharin
a)actionOnA;;
x)actionOnX;;
[yz])actionOnYandZ;;
*)actionOnNoMatch;;
esac

Dalam Lisp:

(casesome-char
((#\a)action-on-a)
((#\x)action-on-x)
((#\y#\z)action-on-y-and-z)
(elseaction-on-no-match))

Dalam Fortran:

select case(someChar)
case('a')
actionOnA
case('x')
actionOnX
case('y','z')
actionOnYandZ
case default
actionOnNoMatch
end select

Perulangan

250px-Programmingloops.svg.png?utm_source=id.wikipedia.org&utm_campaign=parser&utm_content=thumbnail
Jenis dasar perulangan program
Artikel utama: Loop (statement)

Dalam suatu perulangan, urutan pernyataan—yang sering disebut sebagai tubuh perulangan—dieksekusi kembali (setidaknya sebagian) setelah percabangan bersyarat atau lompatan ke langkah sebelumnya dalam urutan tersebut. Jumlah eksekusi suatu perulangan biasanya bergantung pada keadaan saat runtime, misalnya: tubuh dieksekusi sekali untuk setiap item dalam suatu koleksi (iterasi pasti), hingga suatu kondisi terpenuhi (iterasi tak pasti). Namun, beberapa perulangan dapat berulang tanpa batas. Sebuah perulangan dapat ditulis sebagai perulangan tak terbatas, tetapi keluarnya dari perulangan dikendalikan oleh pengujian di dalam tubuh perulangan yang memindahkan kendali ke luar perulangan. Keluar lebih awal dari suatu perulangan dapat didukung melalui pernyataan break.[4][5]

Perulangan yang berada di dalam tubuh perulangan lain disebut perulangan bersarang.[6][7][8]

Dalam bahasa pemrograman fungsional, seperti Haskell dan Scheme, proses rekursif maupun iteratif diekspresikan dengan prosedur rekursif ekor alih-alih konstruksi perulangan yang bersifat sintaksis.

Numerik

Artikel utama: For loop

Perulangan yang relatif sederhana tetapi berguna melakukan iterasi pada rentang nilai numerik. Bentuk sederhana dimulai dari suatu nilai bilangan bulat, berakhir pada nilai bilangan bulat yang lebih besar, dan melakukan iterasi untuk setiap nilai bilangan bulat di antaranya. Sering kali, kenaikan dapat berupa bilangan bulat apa pun (bahkan negatif, untuk melakukan perulangan dari nilai yang lebih besar ke nilai yang lebih kecil).

Contoh dalam BASIC:

FORI=1TON
xxx
NEXTI

Contoh dalam Pascal:

forI:=1toNdobegin
xxx
end;

Contoh dalam Fortran:

DO I=1,N
xxx
END DO

Dalam banyak bahasa pemrograman, hanya bilangan bulat yang dapat digunakan atau dapat digunakan secara andal. Karena bilangan titik mengambang direpresentasikan secara tidak tepat akibat keterbatasan perangkat keras, perulangan berikut dapat melakukan iterasi sebanyak 9 atau 10 kali, bergantung pada berbagai faktor seperti galat pembulatan, perangkat keras, dan kompiler. Selain itu, jika kenaikan X dilakukan melalui penjumlahan berulang, galat pembulatan yang terakumulasi dapat menyebabkan nilai X pada setiap iterasi berbeda cukup jauh dari urutan yang biasanya diharapkan, yaitu 0.1, 0.2, 0.3, ..., 1.0.

for X := 0.1 step 0.1 to 1.0 do

Dikendalikan kondisi

Artikel utama: While loop dan Do while loop

Beberapa konstruksi perulangan melakukan iterasi hingga suatu kondisi bernilai benar. Beberapa variasi menguji kondisi pada awal perulangan; yang lain mengujinya pada akhir. Jika pengujian dilakukan di awal, tubuh perulangan dapat dilewati sepenuhnya. Jika dilakukan di akhir, tubuh perulangan selalu dieksekusi setidaknya sekali.

Contoh dalam Visual Basic:

DOWHILE(test)
xxx
LOOP

Contoh dalam Pascal:

repeat
xxx
untiltest;

Contoh pra-pengujian dalam keluarga C:

while(test){
xxx
}

Contoh pascapengujian dalam keluarga C:

do
xxx
while(test);

Meskipun menggunakan kata kunci for, perulangan C bergaya tiga bagian merupakan konstruksi berbasis kondisi, bukan berbasis numerik. Bagian kedua, yaitu kondisi, dievaluasi sebelum setiap perulangan, sehingga merupakan pra-pengujian. Bagian pertama merupakan tempat untuk menginisialisasi keadaan, sedangkan bagian ketiga digunakan untuk melakukan kenaikan pada iterasi berikutnya, tetapi kedua aspek tersebut dapat dilakukan di tempat lain. Kode C berikut mengimplementasikan logika perulangan numerik yang melakukan iterasi untuk i dari 0 hingga n-1.

for(inti=0;i<n;++i){
xxx
}

Enumerasi

Artikel utama: Foreach

Beberapa konstruksi perulangan melakukan enumerasi item dalam suatu koleksi; melakukan iterasi untuk setiap item.

Contoh dalam Smalltalk:

someCollection do: [:eachElement |xxx].

Contoh dalam Pascal:

forIteminCollectiondobeginxxxend;

Contoh dalam Raku:

foreach (item; myCollection) { xxx }

Contoh dalam TCL:

foreachsomeArray{xxx}

Contoh dalam PHP:

foreach ($someArray as $k => $v) { xxx }

Contoh dalam Java:

Collection<String>coll;
for(Strings:coll){}

Contoh dalam C#:

foreach(stringsinmyStringCollection){xxx}

Contoh dalam PowerShell, dengan 'foreach' sebagai alias dari 'ForEach-Object':

someCollection | foreach { $_ }

Contoh dalam Fortran:

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

Scala memiliki ekspresi for, yang menggeneralisasi perulangan yang dikendalikan oleh koleksi dan juga mendukung penggunaan lain, seperti pemrograman asinkron. Haskell memiliki ekspresi do dan komprehensi, yang secara bersama-sama menyediakan fungsi yang serupa dengan ekspresi for dalam Scala.

Tak terbatas

Page 'Infinite loop' not found

Masalah loop-and-a-half

Struktur perulangan umum terkadang menghasilkan kode yang terduplikasi, baik berupa pernyataan yang diulang maupun kondisi yang diulang. Hal ini muncul karena berbagai alasan dan terdapat berbagai solusi yang diusulkan untuk menghilangkan atau meminimalkan duplikasi kode.[9] Selain solusi tradisional yang tidak terstruktur berupa pernyataan goto,[10] solusi terstruktur yang umum mencakup menempatkan kondisi (pernyataan if) di dalam perulangan (yang mungkin menduplikasi kondisi tetapi tidak pernyataan) atau membungkus logika yang berulang dalam suatu fungsi (sehingga terjadi duplikasi pemanggilan fungsi, tetapi bukan duplikasi pernyataan).[9]

Kasus umum terjadi ketika awal perulangan selalu dieksekusi, tetapi bagian akhir dapat dilewati pada iterasi terakhir.[10] Hal ini disebut oleh Dijkstra sebagai perulangan yang dilakukan "n setengah kali",[11] dan sekarang disebut masalah loop-and-a-half.[5] Kasus umum mencakup membaca data pada bagian pertama, memeriksa akhir data, lalu memproses data pada bagian kedua; atau melakukan pemrosesan, memeriksa akhir, lalu menyiapkan iterasi berikutnya.[10][5] Dalam kasus tersebut, bagian pertama perulangan dieksekusi sebanyak ⁠ n {\displaystyle n} {\displaystyle n}⁠ kali, tetapi bagian kedua hanya dieksekusi sebanyak ⁠ n − 1 {\displaystyle n-1} {\displaystyle n-1}⁠ kali.

Masalah ini telah dikenali setidaknya sejak 1967 oleh Knuth, dengan Wirth menyarankan penyelesaiannya melalui penghentian perulangan lebih awal.[12] Sejak 1990-an, solusi yang paling umum diajarkan menggunakan pernyataan break, seperti:

loop
    statements
    if condition break
    statements
repeat

Hal yang perlu diperhatikan dari solusi ini adalah bahwa kondisi tersebut merupakan kebalikan dari kondisi while biasa: menulis ulang while condition ... repeat dengan keluar di tengah mengharuskan kondisi dibalik: loop ... if not condition exit ... repeat. Struktur kendali perulangan dengan pengujian di tengah secara eksplisit mendukung kasus loop-and-a-half, tanpa membalik kondisi.[12]

Tidak terstruktur

Sebuah konstruksi perulangan menyediakan kriteria penyelesaian terstruktur yang menghasilkan iterasi berikutnya atau melanjutkan eksekusi setelah pernyataan perulangan. Namun, berbagai konstruksi alur kendali tidak terstruktur didukung oleh banyak bahasa.

Iterasi berikutnya lebih awal
Beberapa bahasa menyediakan konstruksi yang memindahkan kendali ke awal tubuh perulangan untuk iterasi berikutnya; misalnya, continue (yang paling umum), skip,[13] cycle (Fortran), atau next (Perl dan Ruby).
Mengulangi iterasi
Beberapa bahasa, seperti Perl[14] dan Ruby,[15] memiliki pernyataan redo yang melompat ke awal tubuh untuk iterasi yang sama.
Mulai ulang
Ruby memiliki pernyataan retry yang memulai ulang seluruh perulangan dari iterasi pertama.[16]
Keluar lebih awal

Keluar lebih awal memindahkan kendali ke setelah tubuh perulangan.[17][5] Misalnya, ketika mencari suatu daftar, perulangan dapat dihentikan ketika item ditemukan. Beberapa bahasa menyediakan pernyataan seperti break (sebagian besar bahasa), Exit (Visual Basic), atau last (Perl).

Dalam kode Ada berikut, perulangan berhenti ketika X bernilai 0.

loop
    Get(X);
    if X = 0 then
        exit;
    end if;
    DoSomething(X);
end loop;

Gaya yang lebih idiomatis menggunakan exit when:

loop
    Get(X);
    exit when X = 0;
    DoSomething(X);
end loop;

Python mendukung eksekusi kode secara kondisional bergantung pada apakah suatu perulangan dihentikan lebih awal (dengan pernyataan break) atau tidak, dengan menggunakan klausa else pada perulangan. Dalam kode Python berikut, klausa else terkait dengan pernyataan for, bukan pernyataan if di dalamnya. Baik perulangan for maupun while Python mendukung klausa else tersebut, yang hanya dieksekusi jika perulangan tidak dihentikan lebih awal.

for n in set_of_numbers:
    if isprime(n):
        print("Set contains a prime number")
        break
else:
    print("Set did not contain any prime numbers")
Break bertingkat

Beberapa bahasa mendukung penghentian perulangan bersarang; dalam teori sirkuit, ini disebut break bertingkat. Salah satu penggunaan umum adalah pencarian pada tabel multidimensi. Hal ini dapat dilakukan melalui break multitingkat (keluar dari N {\displaystyle N} {\displaystyle N} tingkat), seperti dalam bash[18] dan PHP,[19] atau melalui break berlabel (keluar dan melanjutkan pada label tertentu), seperti dalam Ada, Go, Java, Rust, dan Perl.[20] Alternatif untuk break multitingkat meliputi break tunggal bersama variabel keadaan yang diuji untuk keluar dari tingkat lain; pengecualian yang ditangkap pada tingkat tempat keluarnya dilakukan; menempatkan perulangan bersarang dalam sebuah fungsi dan menggunakan return untuk menghentikan seluruh perulangan bersarang; atau menggunakan label dan pernyataan goto. C maupun C++ saat ini tidak memiliki break multitingkat atau perulangan bernama, dan alternatif yang umum adalah menggunakan goto untuk mengimplementasikan break berlabel.[21] Namun, penambahan fitur ini telah diusulkan,[22] dan ditambahkan ke C29,[23] mengikuti sintaks Java. Python tidak memiliki break atau continue multitingkat — fitur ini diusulkan dalam PEP 3136 dan ditolak karena kompleksitas tambahan dianggap tidak sebanding dengan penggunaan sah yang jarang terjadi.[24]

Gagasan mengenai break bertingkat menarik dalam ilmu komputer teoretis, karena menghasilkan apa yang sekarang disebut hierarki Kosaraju.[25] Pada 1973 S. Rao Kosaraju menyempurnakan teorema program terstruktur dengan membuktikan bahwa variabel tambahan dapat dihindari dalam pemrograman terstruktur selama break bertingkat dengan kedalaman arbitrer diperbolehkan.[26] Selain itu, Kosaraju membuktikan bahwa terdapat hierarki program yang ketat: untuk setiap bilangan bulat n {\displaystyle n} {\displaystyle n}, terdapat program yang mengandung break bertingkat dengan kedalaman n {\displaystyle n} {\displaystyle n} yang tidak dapat ditulis ulang sebagai program dengan break bertingkat berkedalaman kurang dari n tanpa menambahkan variabel.[25]

Dalam buku teksnya tahun 2004, David Watt menggunakan gagasan Tennent tentang sequencer untuk menjelaskan kemiripan antara break bertingkat dan pernyataan return. Watt mencatat bahwa kelas sequencer yang dikenal sebagai escape sequencer, yang didefinisikan sebagai "sequencer yang menghentikan eksekusi perintah atau prosedur yang secara tekstual membungkusnya", mencakup break dari perulangan (termasuk break bertingkat) dan pernyataan return. Namun, sebagaimana umumnya diimplementasikan, sequencer return juga dapat membawa nilai (return), sedangkan sequencer break sebagaimana diimplementasikan dalam bahasa kontemporer biasanya tidak dapat melakukannya.[27]

Pengujian di tengah

Struktur berikut diusulkan oleh Dahl pada 1972:[28]

   loop                           loop
       xxx1                           read(char);
   while test;                    while not atEndOfFile;
       xxx2                           write(char);
   repeat;                        repeat;

Konstruksi ini dapat dipandang sebagai perulangan do dengan pemeriksaan while di tengah, yang memungkinkan logika loop-and-a-half yang jelas. Selain itu, dengan menghilangkan komponen tertentu, satu konstruksi ini dapat menggantikan beberapa konstruksi dalam sebagian besar bahasa pemrograman. Jika xxx1 dihilangkan, kita mendapatkan perulangan dengan pengujian di bagian atas (perulangan while tradisional). Jika xxx2 dihilangkan, kita mendapatkan perulangan dengan pengujian di bagian bawah, setara dengan perulangan do while dalam banyak bahasa. Jika while dihilangkan, kita mendapatkan perulangan tak terbatas. Konstruksi ini juga memungkinkan polaritas kondisi tetap sama meskipun berada di tengah, tidak seperti keluar lebih awal yang mengharuskan polaritas dibalik (menambahkan not),[12] sehingga berfungsi sebagai until alih-alih while.

Struktur ini tidak didukung secara luas; sebagian besar bahasa menggunakan if ... break untuk keluar secara bersyarat lebih awal.

Struktur ini didukung oleh beberapa bahasa, seperti Forth, dengan sintaks BEGIN ... WHILE ... REPEAT,[29] dan bahasa shell script Bourne shell (sh) dan bash, dengan sintaks while ... do ... done atau until ... do ... done, seperti:[30][31]

while
statement-1
statement-2
...
condition
do
statement-a
statement-b
...
done

Sintaks shell tersebut bekerja karena perulangan while (atau until) menerima daftar perintah sebagai kondisi,[32] secara formal:

 while'test-commands; doconsequent-commands; done

Nilai (status keluar) dari daftar test-commands adalah nilai dari perintah terakhir, dan perintah-perintah tersebut dapat dipisahkan oleh baris baru, sehingga menghasilkan bentuk idiomatik di atas.

Konstruksi serupa dimungkinkan dalam C dan C++ dengan operator koma, serta bahasa lain dengan konstruksi serupa, yang memungkinkan daftar pernyataan dimasukkan ke dalam kondisi while:

while(statement_1,statement_2,condition){
statement_a;
statement_b;
}

Meskipun sah, penggunaan ini tidak umum dan terutama digunakan, jika memang digunakan, hanya untuk kasus pendek yang melakukan modifikasi lalu pengujian, seperti:[33]

while(read_string(s),strlen(s)>0){
// ...
}

Varian dan invarian perulangan

Varian perulangan dan invarian perulangan digunakan untuk menyatakan kebenaran perulangan.[34]

Dalam praktiknya, varian perulangan adalah ekspresi bilangan bulat yang memiliki nilai awal non-negatif. Nilai varian harus berkurang pada setiap iterasi perulangan, tetapi tidak boleh menjadi negatif selama eksekusi perulangan yang benar. Varian perulangan digunakan untuk menjamin bahwa perulangan akan berhenti.

Invarian perulangan adalah pernyataan yang harus benar sebelum iterasi pertama dan tetap benar setelah setiap iterasi. Hal ini menyiratkan bahwa ketika suatu perulangan berhenti dengan benar, baik kondisi keluar maupun invarian perulangan terpenuhi. Invarian perulangan digunakan untuk memantau sifat-sifat tertentu dari suatu perulangan selama iterasi berturut-turut.

Beberapa bahasa pemrograman, seperti Eiffel, memiliki dukungan bawaan untuk varian dan invarian perulangan. Dalam bahasa lain, dukungan tersedia sebagai tambahan, seperti spesifikasi Java Modeling Language untuk pernyataan perulangan dalam Java.

Subbahasa perulangan

Beberapa dialek Lisp menyediakan subbahasa yang luas untuk mendeskripsikan perulangan. Contoh awal dapat ditemukan dalam Conversional Lisp dari Interlisp. Common Lisp[35] menyediakan makro Loop yang mengimplementasikan subbahasa semacam itu.

Tabel referensi silang sistem perulangan

Bahasa pemrograman Bersyarat Perulangan Keluar awal Kelanjutan perulangan Ulangi kembali Coba lagi Fasilitas kebenaran
Awal Tengah Akhir Numerik Koleksi Umum Tak terbatas [1] Varian Invarian
Ada Ya Ya Ya Ya arrays Tidak Ya deep nested Tidak
APL Ya Tidak Ya Ya Ya Ya Ya deep nested [3] Ya Tidak Tidak
C Ya Tidak Ya Tidak [2] Tidak Ya Tidak deep nested [3] deep nested [3] Tidak Tidak Tidak Tidak
C++ Ya Tidak Ya Tidak [2] Ya [9] Ya Tidak deep nested [3] deep nested [3] Tidak Tidak Tidak Tidak
C# Ya Tidak Ya Tidak [2] Ya Ya Tidak deep nested [3] deep nested [3] Tidak Tidak Tidak Tidak
COBOL Ya Tidak Ya Ya Tidak Ya Tidak deep nested [15] deep nested [14] Tidak
Common Lisp Ya Ya Ya Ya builtin only [16] Ya Ya deep nested Tidak
D Ya Tidak Ya Ya Ya Ya Ya[14] deep nested deep nested Tidak
Eiffel Ya Tidak Tidak Ya [10] Ya Ya Tidak one level [10] Tidak Tidak Tidak [11] integer only [13] Ya
F# Ya Tidak Tidak Ya Ya Tidak Tidak Tidak [6] Tidak Tidak
FORTRAN 77 Ya Tidak Tidak Ya Tidak Tidak Tidak one level Ya Tidak Tidak
Fortran 90 Ya Tidak Tidak Ya Tidak Tidak Ya deep nested deep nested Tidak Tidak
Fortran 95 dan versi selanjutnya Ya Tidak Tidak Ya arrays Tidak Ya deep nested deep nested Tidak Tidak
Go Ya Tidak Tidak Ya builtin only Ya Ya deep nested deep nested Tidak
Haskell Tidak Tidak Tidak Tidak Ya Tidak Ya Tidak [6] Tidak Tidak
Java Ya Tidak Ya Tidak [2] Ya Ya Tidak deep nested deep nested Tidak non-native [12] non-native [12]
JavaScript Ya Tidak Ya Tidak [2] Ya Ya Tidak deep nested deep nested Tidak Tidak Tidak
Kotlin Ya Tidak Ya Mungkin Ya Tidak Tidak deep nested deep nested Tidak Tidak Tidak Tidak
Natural Ya Ya Ya Ya Tidak Ya Ya Ya Ya Ya Tidak
OCaml Ya Tidak Tidak Ya arrays,lists Tidak Tidak Tidak [6] Tidak Tidak
Odin Tidak [17] Tidak Tidak Tidak [5] builtin only Ya Tidak [17] deep nested deep nested
PHP Ya Tidak Ya Tidak [2] [5] Ya [4] Ya Tidak deep nested deep nested Tidak Tidak Tidak Tidak
Perl Ya Tidak Ya Tidak [2] [5] Ya Ya Tidak deep nested deep nested Ya
Python Ya Tidak Tidak Tidak [5] Ya Tidak Tidak deep nested [6] deep nested [6] Tidak Tidak Tidak Tidak
QB64 Ya Tidak Ya Ya Tidak Ya Ya one level per type of loop one level per type of loop Tidak Tidak Tidak Tidak
Rebol Tidak [7] Ya Ya Ya Ya Tidak [8] Ya one level [6] Tidak Tidak
Ruby Ya Tidak Ya Ya Ya Tidak Ya deep nested [6] deep nested [6] Ya Ya
Rust Ya Tidak Tidak Tidak [5] Ya Tidak Ya deep nested deep nested Tidak Tidak Tidak Tidak
Standard ML Ya Tidak Tidak Tidak arrays,lists Tidak Tidak Tidak [6] Tidak Tidak
Swift Ya Tidak Ya Tidak Ya Ya Tidak deep nested deep nested Tidak Tidak Tidak Tidak
Visual Basic .NET Ya Tidak Ya Ya Ya Tidak Ya one level per type of loop one level per type of loop Tidak Tidak Tidak Tidak
PowerShell Ya Tidak Ya Tidak [2] Ya Ya Tidak Ya Ya Tidak Tidak Tidak Tidak
Zig Ya Tidak Tidak Ya builtin only Tidak Tidak deep nested deep nested Tidak Tidak Tidak Tidak
  1. a while (true) tidak dihitung sebagai perulangan tak terbatas untuk tujuan ini karena bukan merupakan struktur bahasa khusus.
  2. abcdefgh Perulangan C for (init; test; increment) merupakan konstruksi perulangan umum, bukan khusus untuk penghitungan, meskipun sering digunakan untuk tujuan tersebut.
  3. abc Break bertingkat dapat dilakukan dalam APL, C, C++, dan C# melalui penggunaan label dan goto.
  4. a Iterasi terhadap objek ditambahkan dalam PHP 5.
  5. abcdef Perulangan penghitung dapat disimulasikan dengan melakukan iterasi pada daftar atau generator yang meningkat, misalnya range() dalam Python.
  6. abcde Break bertingkat dapat dilakukan melalui penanganan pengecualian.
  7. a Tidak ada konstruksi khusus karena fungsi while dapat digunakan untuk tujuan ini.
  8. a Tidak ada konstruksi khusus, tetapi pengguna dapat mendefinisikan fungsi perulangan umum.
  9. a Standar C++11 memperkenalkan range-based for. Dalam STL, terdapat fungsi templat std::for_each yang dapat melakukan iterasi pada kontainer STL dan memanggil fungsi uner untuk setiap elemen.[36] Fungsionalitas ini juga dapat dibangun sebagai makro pada kontainer tersebut.[37]
  10. a Perulangan numerik dilakukan dengan iterasi pada interval bilangan bulat; keluar lebih awal dilakukan dengan menyertakan kondisi tambahan untuk keluar.
  11. a Eiffel mendukung kata tercadang retry, tetapi kata tersebut digunakan dalam penanganan pengecualian, bukan untuk kendali perulangan.
  12. a Memerlukan Java Modeling Language (JML), yaitu bahasa spesifikasi antarmuka perilaku.
  13. a Mengharuskan varian perulangan berupa bilangan bulat; varian transfinit tidak didukung. Eiffel: Why loop variants are integers
  14. a D mendukung koleksi tak terbatas dan kemampuan untuk melakukan iterasi pada koleksi tersebut. Hal ini tidak memerlukan konstruksi khusus.
  15. a Break bertingkat dapat dicapai menggunakan GO TO dan prosedur.
  16. a Common Lisp mendahului konsep tipe koleksi generik.
  17. ab Perulangan for umum dalam Odin mendukung pintasan sintaks untuk perulangan bersyarat dan perulangan tak terbatas.

Nonlokal

Banyak bahasa pemrograman, terutama yang lebih menyukai gaya pemrograman dinamis, menyediakan konstruksi untuk alur kendali nonlokal yang menyebabkan eksekusi melompat dari titik eksekusi saat ini ke titik yang telah dideklarasikan sebelumnya. Contoh penting di antaranya adalah sebagai berikut.

Penanganan kondisi

Kompiler Fortran paling awal mendukung pernyataan untuk menangani kondisi luar biasa, termasuk IF ACCUMULATOR OVERFLOW, IF QUOTIENT OVERFLOW, dan IF DIVIDE CHECK. Demi independensi terhadap mesin, pernyataan tersebut tidak disertakan dalam FORTRAN IV dan Standar Fortran 66. Namun, sejak Fortran 2003, masalah numerik dapat diuji melalui pemanggilan fungsi dalam modul IEEE_EXCEPTIONS.

PL/I memiliki sekitar 22 kondisi standar (misalnya, ZERODIVIDE, SUBSCRIPTRANGE, ENDFILE) yang dapat dibangkitkan dan dicegat menggunakan: ON condition action; Pemrogram juga dapat mendefinisikan dan menggunakan kondisi bernama mereka sendiri.

Seperti if tidak terstruktur, hanya satu pernyataan yang dapat ditentukan sehingga dalam banyak kasus diperlukan GOTO untuk menentukan tempat alur kendali dilanjutkan.

Sayangnya, beberapa implementasi memiliki overhead yang cukup besar dalam penggunaan ruang maupun waktu (terutama SUBSCRIPTRANGE), sehingga banyak pemrogram berusaha menghindari penggunaan kondisi.

Contoh sintaks yang umum:

ON condition GOTO label

Penanganan pengecualian

Banyak bahasa modern secara bawaan mendukung penanganan pengecualian. Umumnya, alur kendali pengecualian dimulai ketika sebuah objek pengecualian dilemparkan (disebut juga dibangkitkan). Kendali kemudian diteruskan ke penangan pengecualian terdalam pada call stack. Jika penangan menangani pengecualian tersebut, alur kendali kembali normal. Jika tidak, kendali bergerak keluar menuju penangan yang membungkusnya hingga ada yang menangani pengecualian atau program mencapai lingkup terluar dan berhenti. Ketika kendali bergerak menuju penangan yang semakin luar, aspek-aspek yang biasanya terjadi, seperti mengeluarkan elemen dari call stack, ditangani secara otomatis.

Kode C++ berikut menunjukkan penanganan pengecualian terstruktur. Jika sebuah pengecualian muncul dari eksekusi doSomething() dan tipe objek pengecualian cocok dengan salah satu tipe yang ditentukan dalam klausa catch, klausa tersebut dieksekusi. Misalnya, jika pengecualian bertipe SomeException dibangkitkan oleh doSomething(), maka kendali melompat dari baris 2 ke baris 4 dan pesan "Caught SomeException" dicetak, kemudian kendali melompat ke setelah pernyataan try, yaitu baris 8. Jika pengecualian dengan tipe lain dibangkitkan, kendali melompat dari baris 2 ke baris 6. Jika tidak ada pengecualian, kendali melompat dari baris 2 ke baris 8.

try{
doSomething();
}catch(constSomeException&e)
std::println("Caught SomeException: {}",e.what());
}catch(...){
std::println("Unknown error");
}
doNextThing();

Banyak bahasa menggunakan kata kunci C++ (throw, try, dan catch), tetapi beberapa bahasa menggunakan kata kunci lain. Misalnya, Ada menggunakan exception untuk memperkenalkan penangan pengecualian dan when sebagai pengganti catch. AppleScript menyertakan placeholder dalam sintaksnya untuk mengekstrak informasi tentang pengecualian seperti yang ditunjukkan dalam kode AppleScript berikut.

try
    set myNumber to myNumber / 0
on error e number n from f to t partial result pr
    if ( e = "Can't divide by zero" ) then display dialog "You must not do that"
end try

Dalam banyak bahasa (termasuk Object Pascal, D, Java, C#, dan Python), klausa finally di akhir pernyataan try dieksekusi pada akhir pernyataan try, baik pengecualian diteruskan dari bagian lain try maupun tidak. Kode C# berikut memastikan bahwa aliran stream ditutup.

FileStreamstream=null;
try
{
stream=newFileStream("logfile.txt",FileMode.Create);
returnProcessStuff(stream);
}
finally
{
if(stream!=null)
{
stream.Close();
}
}

Karena pola ini umum, C# menyediakan pernyataan using untuk memastikan pembersihan. Dalam kode berikut, bahkan jika ProcessStuff() meneruskan sebuah pengecualian, objek stream dilepaskan. Pernyataan with dalam Python dan argumen blok Ruby pada File.open digunakan untuk tujuan serupa.

using(FileStreamstream=new("logfile.txt",FileMode.Create))
{
returnProcessStuff(stream);
}

Kontinuasi

Page 'Continuation' not found

Generator

Page 'Generator (computer science)' not found

Korutin

Page 'Coroutine' not found

COMEFROM

Page 'COMEFROM' not found

Keluar lebih awal dari perulangan bersarang berbasis peristiwa

Zahn's construct diusulkan pada 1974,[38] dan dibahas dalam Knuth (1974). Versi yang dimodifikasi disajikan di sini.

   exitwhen EventA or EventB or EventC;
       xxx
   exits
       EventA: actionA
       EventB: actionB
       EventC: actionC
   endexit;

exitwhen digunakan untuk menentukan peristiwa yang mungkin terjadi di dalam xxx, yang kemunculannya ditunjukkan dengan menggunakan nama peristiwa sebagai pernyataan. Ketika suatu peristiwa terjadi, tindakan yang relevan dijalankan, kemudian kendali diteruskan tepat setelah endexit. Konstruksi ini memberikan pemisahan yang sangat jelas antara menentukan bahwa suatu situasi berlaku dan tindakan yang harus dilakukan untuk situasi tersebut.

exitwhen secara konseptual mirip dengan penanganan pengecualian, dan pengecualian atau konstruksi serupa digunakan untuk tujuan ini dalam banyak bahasa.

Contoh sederhana berikut melibatkan pencarian item tertentu dalam tabel dua dimensi.

   exitwhen found or missing;
       for I := 1 to N do
           for J := 1 to M do
               if table[I,J] = target then found;
       missing;
   exits
       found:   print ("item is in table");
       missing: print ("item is not in table");
   endexit;

Lihat pula

Referensi

  1. ↑ Payer, Mathias; Kuznetsov, Volodymyr. "On differences between the CFI, CPS, and CPI properties". nebelwelt.net. Diakses tanggal 2016-06-01.
  2. ↑ "Adobe Flash Bug Discovery Leads To New Attack Mitigation Method". Dark Reading. 10 November 2015. Diakses tanggal 2016-06-01.{{cite web}}: Pemeliharaan CS1: Tanggal diterjemahkan otomatis (link)
  3. ↑ Endgame. "Endgame to Present at Black Hat USA 2016". www.prnewswire.com (Rilis pers). Diakses tanggal 2016-06-01.
  4. ↑ Knuth, Donald E. (1974). "Structured Programming with go to Statements". Computing Surveys. 6 (4): 261–301. doi:10.1145/356635.356640. S2CID 207630080.
  5. 1 2 3 4 Roberts, E. [1995] "Loop Exits and Structured Programming: Reopening the Debate Diarsipkan 2014-07-25 di Wayback Machine," ACM SIGCSE Bulletin, (27)1: 268–272.
  6. ↑ "Nested Loops in C with Examples". GeeksforGeeks (dalam bahasa American English). 2019-11-25. Diakses tanggal 2024-03-14.
  7. ↑ "Python Nested Loops". www.w3schools.com (dalam bahasa American English). Diakses tanggal 2024-03-14.
  8. ↑ Dean, Jenna (2019-11-22). "Nested Loops". The Startup (dalam bahasa Inggris). Diakses tanggal 2024-03-14.
  9. 1 2 "Messy Loop Conditions". WikiWikiWeb. 2014-11-03.
  10. 1 2 3 Knuth 1974, hlm. 278, Simple Iterations.
  11. ↑ Edsger W. Dijkstra, komunikasi pribadi kepada Donald Knuth pada 1974-01-03, dikutip dalam Knuth (1974, hlm. 278, Simple Iterations)
  12. 1 2 3 Knuth 1974, hlm. 279.
  13. ↑ "What is a loop and how we can use them?". Diarsipkan dari asli tanggal 2020-07-28. Diakses tanggal 2020-05-25.
  14. ↑ "redo - perldoc.perl.org". perldoc.perl.org. Diakses tanggal 2020-09-25.
  15. ↑ "control_expressions - Documentation for Ruby 2.4.0". docs.ruby-lang.org. Diakses tanggal 2020-09-25.
  16. ↑ "control_expressions - Documentation for Ruby 2.3.0". docs.ruby-lang.org. Diakses tanggal 2020-09-25.
  17. ↑ Merupakan cara umum untuk menyelesaikan masalah loop-and-a-half.
  18. ↑ Advanced Bash Scripting Guide: 11.3. Loop Control
  19. ↑ PHP Manual: "break"
  20. ↑ perldoc: last
  21. ↑ comp.lang.c FAQ list · "Question 20.20b"
  22. ↑ "named-loops". open-std.org. 18 September 2024.{{cite web}}: Pemeliharaan CS1: Tanggal diterjemahkan otomatis (link)
  23. ↑ "Information technology — Programming languages — C" (PDF). open-std.org. 4 Mei 2025.{{cite web}}: Pemeliharaan CS1: Tanggal diterjemahkan otomatis (link)
  24. ↑ [Python-3000] Announcing PEP 3136, Guido van Rossum
  25. 1 2 Kozen, Dexter (2008). "The Böhm–Jacopini Theorem is False, Propositionally". Mathematics of Program Construction (PDF). Lecture Notes in Computer Science. Vol. 5133. hlm. 177–192. doi:10.1007/978-3-540-70594-9_11. ISBN 978-3-540-70593-2.
  26. ↑ Kosaraju, S. Rao. "Analysis of structured programs," Proc. Fifth Annual ACM Syrup. Theory of Computing, (May 1973), 240-252; also in J. Computer and System Sciences, 9, 3 (December 1974), cited by Knuth (1974).
  27. ↑ David Anthony Watt; William Findlay (2004). Programming language design concepts. John Wiley & Sons. hlm. 215–221. ISBN 978-0-470-85320-7.
  28. ↑ Dahl & Dijkstra & Hoare, "Structured Programming" Academic Press, 1972.
  29. ↑ "6. Throw It For a Loop".
  30. ↑ "3.2.5.1 Looping Constructs", The GNU Bash Reference Manual, 2025-05-18
  31. ↑ "How could a language make the loop-and-a-half less error-prone?". Stack Exchange: Programming Language Design and Implementation.
  32. ↑ "3.2.4 Lists of Commands", The GNU Bash Reference Manual, 2025-05-18
  33. ↑ "What does the comma operator , do?". Stack Overflow.
  34. ↑ Meyer, Bertrand (1991). Eiffel: The Language. Prentice Hall. hlm. 129–131.
  35. ↑ "Common Lisp LOOP macro".
  36. ↑ for_each. Sgi.com. Retrieved on 2010-11-09.
  37. ↑ Chapter 1. Boost.Foreach Diarsipkan 2010-01-29 di Wayback Machine. Boost-sandbox.sourceforge.net (2009-12-19). Retrieved on 2010-11-09.
  38. ↑ Zahn, C. T. "A control statement for natural top-down structured programming" presented at Symposium on Programming Languages, Paris, 1974.

Pranala luar

Wikibooks logo
Wikibooks Ada Programming memiliki halaman di:
Wikibooks logo
Konten disalin dari Wikipedia Bahasa Indonesia (lisensi CC BY-SA) Lihat versi asli di Wikipedia

Rekomendasi Pilihan