Setelah if dan switch statements , salah satu operasi yang akan sering kita gunakan dan temukan adalah loop atau operasi perulangan.
Seperti namanya, loop adalah sebuah statement yang bertujuan untuk mengeksekusi sebuah blok kode secara berulang-ulang. Kode akan dieksekusi di dalam sebuah iterasi, dan setiap sebelum menjalankan eksekusi selanjutnya, akan dilakukan evaluasi terhadap kondisi untuk menentukan apakah eksekusi akan dihentikan atau dilanjutkan.
Dalam bahasa C ada 3 jenis loop yang bisa kita gunakan, yaitu for , while , dan do-while . Perbedaan utama dari ketiga jenis loop ini adalah dimana dan kapan kondisi ini dievaluasi. Dimana dengan while dan for statement, kondisi akan dievaluasi sebelum eksekusi berjalan, dengan do-while statement, kondisi akan dievaluasi setelah eksekusi berjalan.
The while Loop Statement
Dari semua cara melakukan looping di dalam bahasa C , while loop statement adalah jenis loop yang paling sederhana dan fundamental.
while (condition) {
// Will executed if condition is true
} Kode di dalam blok {} akan dieksekusi jika kondisi yang ditempatkan di dalam () adalah berupa true .
int i = 0;
// The condition is evaluated first
while (i < 10) {
printf("%d\n", i);
i++; // This is executed after the body of the loop
} Kode di atas akan menampilkan angka 0 hingga 9, karena kondisi i < 10 akan bernilai true selama i kurang dari 10. Setelah i bernilai 10, kondisi akan bernilai false dan eksekusi akan berhenti. Nilai dari variabel i akan terus bertambah 1 setiap kali eksekusi berjalan karena kita menggunakan i++ di dalam blok {} .
Seandainya kita ingin membuat program yang meminta kita untuk memasukkan sebuah angka, dan program akan menampilkan angka yang kita masukkan bersamaan dengan kelipatan 2 dari angka yang kita masukkan, maka kita bisa menggunakan loop seperti ini:
#include <stdio.h>
int main() {
// The flag variable is commonly used as a temporary variable
// or a signal variable to indicate whether certain condition is met
int input, flag = 1;
printf("Enter a number: ");
scanf("%d", &input);
while(flag <= input) {
printf("%d\t%d\n", flag, flag * flag);
flag++;
}
} Maka program akan menampilkan output seperti ini:
Enter a number: 10
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
10 100 Seperti dilihat, program kita akan terus berjalan dan melakukan komputasi selama kondisi flag <= input bernilai true .
The do-while Loop Statement
Seperti namanya, do-while loop statement mirip sekali dengan while loop statement. Perbedaannya adalah kondisi akan dievaluasi setelah eksekusi blok kode di dalam loop berjalan.
do {
// Will executed if condition is true
} while (condition); Dengan struktur seperti di atas, maka blok kode di dalam {} akan dieksekusi setidaknya satu kali, dan kemudian kondisi akan dievaluasi. Jika kondisi bernilai true , maka eksekusi akan dilanjutkan ke blok kode di dalam {} dan kondisi akan dievaluasi lagi.
Hal ini membuat, setidaknya kode yang berada di dalam {} akan dieksekusi sekurang-kurangnya satu kali. Tidak peduli apakah kondisi bernilai true atau false pada eksekusi pertama.
Mari kita coba tulis ulang contoh program sebelumnya dengan menggunakan do-while loop statement:
#include <stdio.h>
int main() {
int input, flag = 1;
printf("Enter a number: ");
scanf("%d", &input);
do {
printf("%d\t%d\n", flag, flag * flag);
flag++;
} while(flag <= input);
} Jika kita menjalankan program dan memasukkan angka yang tidak valid dari awal, maka program akan tetap berjalan pada eksekusi pertama seperti ini:
Enter a number: 0
1 1 Angka 0 bukanlah angka yang valid dikarenakan flag kita saja dimulai dari nilai 1 . Namun, dikarenakan kondisi dievaluasi setelah eksekusi blok kode di dalam {} berjalan, maka eksekusi akan berhenti setelah eksekusi pertama.
The for Loop Statement
for Loop statemetn adalah jenis loop terakhir yang akan kita bahas disini. Dan mungkin juga, ini adalah jenis loop yang paling sering digunakan dan temukan di dalam kode-kode diluar sana.
Tidak heran kalau for loop biasanya adalah jenis loop yang pertama kali akan diajarkan kepada pemula dalam bahasa pemrograman C diluar sana. Meskipun strukturnya yang βagak lainβ, tapi tidak sulit untuk membiasakan diri dengan struktur dari for loop ini.
for (expr1; expr2; expr3) {
// Statements
} Meskipun terlihat rumit, namun jenis struktur dari for loop ini biasanya diringkas menjadi seperti ini:
for (initialization; condition; increment) {
// Will executed if condition is true
} Meskipun struktur kedua ini terlihat lebih berbeda, sebenarnya keduanya adalah sama. Namun jenis struktur kedua ini yang lebih sering digunakan sebagai contoh dalam penerapan for loop diluar sana. Struktur tersebut valid-valid saja, namun implementasi for loop di dunia nyata bisa menjadi sangat kompleks, sehingga kita tidak boleh melupakan struktur pertama.
Dari struktur for loop yang kedua, kita bisa melihat initialization sebagai sebuah ekspresi yang akan dieksekusi sebelum eksekusi blok kode di dalam {} berjalan. condition sebagai sebuah ekspresi yang akan dievaluasi untuk menentukan apakah eksekusi blok kode di dalam {} akan dilanjutkan atau dihentikan. Dan increment sebagai sebuah ekspresi yang akan dieksekusi setelah eksekusi blok kode di dalam {} berjalan.
Mari kita lihat contoh penerapan dari for loop ini:
for (int i = 0; i < 10; i++) {
printf("%d\n", i);
} Ketika kita menjalankan program di atas, maka output yang akan kita dapatkan adalah seperti ini:
0
1
2
3
4
5
6
7
8
9 // 9 is the last number before the condition is false Dan jika kita mencoba menerjemahkan kode di atas ke dalam while loop, maka akan menjadi seperti ini:
// The initialization is executed first
int i = 0;
// The condition is evaluated first
while (i < 10) {
printf("%d\n", i);
i++; // The increment is executed after the body of the loop
} Namun bagaimana jika kita tidak ingin menginisialisasi variabel i di dalam for loop? Kita bisa meninggalkan ekspresi initialization kosong, dan hanya menulis condition dan increment .
// The initialization is outside the for loop
int i = 0;
for (; i < 10; i++) {
printf("%d\n", i);
} Tidak hanya bagian initialization saja, kita juga bisa meninggalkan bagian increment juga.
for (int i = 0; i < 10; ) {
printf("%d\n", i);
// The increment is inside the loop body
i++;
} Bisa dilihat, dikarenakan ekspres increment tidak berada di dalam for loop , maka kita menaruh ekspres increment di dalam blok kode di dalam {} .
Lalu bagaimana jika kita ingin melakukan lebih dari satu initialization atau increment di dalam for loop sekaligus? Kita bisa melakukannya dengan memisahkan masing-masing ekspres dengan menggunakan koma , .
#include <stdio.h>
int main() {
for (int i = 0, j = 0; i < 10 && j < 10; i++, j++) {
printf("%d\t%d\n", i, j);
}
} Ketika kita menjalankan program di atas, maka output yang akan kita dapatkan adalah seperti ini:
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9 Bisa dilihat kita melakukan initialization dan increment lebih dari satu kali di dalam for loop sekaligus dan semuanya tetap berjalan.
Exiting or Skipping a Loop
Ada beberapa alasan kenapa kita mungkin ingin keluar dari sebuah loop atau melewati eksekusi sebuah iterasi di dalam loop .
Salah satu alasan yang paling umum adalah kita ingin menghentikan eksekusi loop jika kondisi tertentu terpenuhi. Kita bisa melakukan hal ini dengan menggunakan statement break .
Atau kita ingin melewati eksekusi sebuah iterasi di dalam loop berdasarkan suatu kondisi. Kita bisa melakukan hal ini dengan menggunakan statement continue .
Ada juga goto statement yang agak tricky dan dianggap bad practice di dalam pemrograman C , namun tidak ada salahnya jika kita bahas agar kita tahu bahwa statement ini ada.
The break Statement
break statement adalah statement yang akan menghentikan eksekusi loop dan keluar dari loop tersebut. Dan break statement ini bisa digunakan pada while , do-while , dan for loop .
Sebagai contoh, anggap saja kita ingin membuat program yang akan menerima input berupa angka, dan program kita nantinya akan melakukan looping dari angka 0 sampai dengan angka yang kita masukkan.
#include <stdio.h>
int main() {
int input, flag = 0;
printf("Enter a number: ");
scanf("%d", &input);
// Infinite Loop
for(;;) { // Or we can use while(1)
printf("%d\n", flag);
flag++;
if(flag > input) {
break; // This will exit the loop
}
}
} Kita dengan sengaja menggunakan infinite Loop untuk menunjukkan bahwa break statement akan menghentikan eksekusi loop dan keluar dari loop tersebut ketika ada suatu kondisi terpenuhi.
The continue Statement
Dibandingkan dengan break statement yang akan menghentikan keseluruhan eksekusi dari loop , continue statement adalah statement yang berguna untuk melewati eksekusi blok kode pada iterasi loop saat ini dan melanjutkan eksekusi loop ke iterasi berikutnya.
Perlu diketahui juga, berbeda dengan break statement , continue statement hanya bisa digunakan di dalam operasi loop saja, dan tidak bisa digunakan di dalam switch statement .
#include <stdio.h>
int main() {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
continue; // skip the rest of the loop when i == 5
}
printf("%d\n", i);
}
return 0;
} Ketika kita menjalankan program di atas, maka output yang akan kita dapatkan adalah seperti ini:
1
2
3
4
6 // 5 is skipped
7
8
9
10 Bisa dilihat, bahwa angka 5 tidak pernah dicetak karena kita menggunakan continue statement untuk melewati eksekusi blok kode pada iterasi loop saat ini dan melanjutkan eksekusi loop ke iterasi berikutnya, berbeda dengan break statement yang akan menghentikan keseluruhan eksekusi dari loop .
The goto Statement
Inti dari goto statement adalah untuk melompat ke bagian tertentu dari program dengan menggunakan penanda yang kita sebut dengan label . Dari sisi namanya sendiri, goto yang terbuat dari kata go dan to yang bisa diartikan sebagai βpergi keβ.
Apa yang disebut dengan label dalam goto statement ini berguna sebagai penanda yang akan kita panggil untuk melompat ke bagian tertentu dari program.
label:
// Statements Dan kita bisa menggunakan label ini di dalam goto statement untuk melompat ke bagian tertentu dari program.
goto label; 1 hal yang perlu diingat adalah, goto statement hanya bisa digunakan di dalam fungsi yang sama.
#include <stdio.h>
int main() {
for (int i = 1; i <= 10; i++) {
if (i == 5) {
goto special; // jump to label when i is 5
}
printf("Number: %d\n", i);
}
special: // This is the label
printf("Hello from special!\n");
return 0;
} Ketika kita menjalankan program di atas, maka output yang akan kita dapatkan adalah seperti ini:
Number: 1
Number: 2
Number: 3
Number: 4
Hello from special! Hal menarik dari program diatas adalah, kita tidak perlu menuliskan break statement untuk keluar dari loop . in a sense , dengan menggunakan goto statement kita sudah melakukan hal yang sama seperti menggunakan break statement untuk keluar dari loop .
Lalu bagaimana jika kita ingin melanutkan loop lagi setelah melompat ke label ? mungkin kita bisa melakukannya seperti ini:
#include <stdio.h>
int main() {
int i;
for (i = 1; i <= 10; i++) {
if (i == 5) {
goto special; // jump to label when i is 5
}
printf("Number: %d\n", i);
// continue; // skip label if i is not 5
}
special:
printf("Hello from special! i = %d\n", i);
// Resume the rest of the loop manually
for (i = i + 1; i <= 10; i++) {
printf("Number: %d\n", i);
}
return 0;
} Gimana ? ribet kan ?
Inilah alasan kenapa goto statement sudah jarang digunakan di dalam pemrograman C diluar sana. Mungkin bisa dibilang kalau goto statement ini merupakan bagian dari cara ngoding yang udah kuno. Jadi lebih baik kita menghindari juga penggunaan goto statement ini.
Mungkin salah satu kasus penggunaan goto statement yang valid di dunia nyata adalah ketika kita ingin keluar dari dalam switch statement bersamaan dengan loop .
#include <stdio.h>
int main() {
int i;
while (1) {
switch(i) {
case 5:
goto loop_exit;
// We don't need a break here because we're using goto
default:
printf("Number: %d\n", i);
i++;
break;
}
}
loop_exit:
printf("Hello from loop_exit! i = %d\n", i);
// Resume the rest of the loop manually
for (i = i + 1; i <= 10; i++) {
printf("Number: %d\n", i);
}
return 0;
} The Null Statement Inside a Loop
Inti dari null statement adalah statement yang tidak melakukan eksekusi apapun atau tidak melakukan apa-apa.
int i = 0; ; j = 1; Contoh kode diatas, meskipun terlihat hanya terdapat 2 statement , namun sebenarnya terdapat 3 statement yang dijalankan.
-
int i = 0;, assignment nilai0ke variabeli -
;, null statement (literally, gak ngelakuin apa-apa) -
j = 1;, assignment nilai1ke variabelj
Bisa dilihat kalau null statement ini sebenarnya tidak melakukan apa-apa. Lalu mengapa ada orang yang perlu menggunakan sebuah statement yang tidak melakukan apa-apa?
Umumnya, ketika kita membicarakan looping atau iteration , null statement ini digunakan untuk menjadi sebuah penanda kalau semua eksekusi dari loop tersebut berada di dalam blok kondisi dari loop tersebut ( loop header).
Sebagai contoh, kita ingin membuat sebuah program yang akan menerima input berupa angka, lalu program kita akan melakukan kalkulasi (+) secara berurutan dari 0 sampai dengan angka yang kita masukkan.
#include <stdio.h>
int main() {
// Total must have an initial value!
int input, total = 0;
printf("Enter a number: ");
scanf("%d", &input);
// See the total += i and i++ are inside the loop header?
// That means all the code logic is inside the loop header
// Making the loop body empty
for (int i = 0; i <= input; total += i, i++)
; // This is a null statement
printf("The sum of all numbers from 0 to %d is %d\n", input, total);
return 0;
} Dari kode diatas, dikarenakan semua logic yang dibutuhkan berada di dalam loop header, hal tersebut meninggalkan loop body menjadi kosong. Disitu, kita mengisi loop body dengan null statement ; untuk menandakan bahwa semua logic yang dibutuhkan berada di dalam loop header.
Lalu kenapa kita melakukan hal tersebut? jujur saja, kita bisa saja menghindari penggunaan null statement , sehingga kita dapat menghilangkan penanda loop body kita.
for (int i = 0; i <= input; total += i, i++);
printf("The sum of all numbers from 0 to %d is %d\n", input, total); Ketika orang lain membaca kode diatas, mungkin saja dia bisa bingung dan menganggap bahwa eksekusi printf tersebut merupakan bagian dari loop atau berada di dalam loop body , padahal tidak seperti itu!
Jadi sebenarnya penggunaan utama dari null statement di dalam loop adalah untuk menandakan bahwa semua logic yang dibutuhkan berada di dalam loop header yang mengakibatkan loop body menjadi tidak dibutuhkan. Serta untuk menandakan kalau kode setelah loop tersebut bukan merupakan bagian dari loop tersebut.