Ana sayfa > Programlama > C++ Programlama > Döngüler

Döngüler

► Kısa anlatım

Tek bir işlem satırını veya kod bloğunu bir defadan fazla çalıştırmak için tekrar yazmak yerine, daha pratik bir uygulama olan döngü kavramını kullanabiliriz.

Bir veya birden fazla işlem satırını, bir koşula bağlı olarak, belirli sayıda veya bir koşul sağlandığı sürece tekrarlayarak çalıştıran kalıplara döngü adı verilir.

C++'da, for, while ve do while olmak üzere 3 farklı döngü kullanılmaktadır.

for döngüsü

C++'da kullanılan 3 adet döngüden bir tanesi for döngüsüdür. Programların yazılmasında çok büyük kolaylık sağlar. for döngüsü tek bir işlem satırını veya birden fazla işlem satırından oluşan bir kod bloğunu programcının istediği sayıda tekrar etmek için kullanılır. for döngüsünün genel yapısı aşağıda gösterilmektedir:

for (ilk-değer-atama; koşul; artırma/azaltma) işlem-satırı;

for (ilk-değer-atama; koşul; artırma/azaltma) {
	işlem-satırı;
	.
	.
	.
	işlem-satırı;
}	

Bir for döngüsü içinde for deyiminin kendisi hariç toplam 4 ana bölüm vardır. Bunlardan üçü for satırında parantezler içinde yer alan ilk-değer-atama, koşul ve artırma/azaltma bölümleridir. Dördüncü ve son bölüm ise döngü içinde programın istediğimiz sayıda tekrar ettiği tek bir işlem-satırı veya kod bloğudur.

İlk değer atama bölümünde, döngüyü kontrol eden değişkene bir ilk değer verilir. İlk değer atama bölümü, program tarafından bir defaya mahsus olmak üzere sadece döngünün başlangıcında çalıştırılır. Tanımlanması gerekli değildir.

Koşul bölümünde, döngü kontrol değişkeni döngünün her tekrarında belirli bir değer ile karşılaştırılır. Eğer koşula bağlı bu kontrol doğru bir sonuç verirse döngü tekrar eder, aksi takdirde döngü sona erer ve program döngüden sonra yer alan satırdan çalışmasına devam eder. Daha açık bir ifade ile, bu bölüm döngünün devam edip etmeyeceğinin belirlendiği bölümdür. Bu nedenle, koşul bölümü döngünün her tekrarlanmasında, döngünün başlangıcında program tarafından çalıştırılır. Eğer döngü başlangıcında koşul doğru sonuç vermezse döngü hiç çalışmaz.

Artırma/azaltma bölümünde, döngü kontrol değişkeni döngünün her tekrarında belirli bir oranda artırılır veya azaltılır. Artırma/azaltma bölümü, işlem satırı veya kod bloğundan sonra ve koşul bölümünden önce program tarafından çalıştırılır.

Şimdi örnekler üzerinde döngüsüz ve döngü kullanarak yapılan tekrar işlemlerini incelemeye çalışalım:


#include <iostream>

using namespace std;

int main(void)
{
  char cd='A';
  int id;

  cout << cd << " ";
  cout << cd << " ";
  cout << cd << " ";
  cout << cd << " ";
  cout << cd << "\n";

  for (id=0; id<5; id=id+1) cout << cd << " ";

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

A A A A A
A A A A A

Program her satır için 'A' karakterini 5 kez ekrana yazmak için farklı bir yöntem kullanır. İlk satır için 5 işlem satırında cout fonksiyonunu, ikinci satır için ise bir for döngüsü kullanır. Burada, for döngüsünün sağladığı esnekliği daha kolay değerlendirebilmek için iki yöntem aynı program içinde kullanılmaktadır. Bu program içinde her satırda 'A' harfini 20 kez ekrana yazmak için bir değişiklik yapmak istediğimizde ilk yöntem için 15 işlem satırı eklememiz gerekir. Döngü yönteminde ise sadece for satırında yer alan 5 değerini 20 yapmak yeterlidir.

Program, for satırının ilk değer atama bölümünde id değişkenine 0 sayısını atar. for satırının koşul bölümünde 0<5 ifadesi doğru bir sonuç verdiği için for satırında yer alan işlem satırı çalışır ve cd değişken değeri olan 'A' karakteri ekrana yazılır. Sonra, artırma bölümü devreye girer ve id değişken değeri 1 artarak 1 değerini alır. Yine, 1<5 ifadesi doğru bir sonuç verdiği için for satırında yer alan işlem satırı çalışır ve cd değişken değeri ekrana yazılır. Döngü id değişkeni 5 değeri alana kadar devam eder. Değişken 5 değerini aldığında 5<5 ifadesi yanlış bir sonuç vereceğinden döngü sona erer.


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  for (id=1; id<=10; id++) cout << id << " ";

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 2 3 4 5 6 7 8 9 10

Program, for satırının ilk değer atama bölümünde id değişkenine 1 sayısını atar. for satırının koşul bölümünde 1<=10 ifadesi doğru bir sonuç verdiği için for satırında yer alan işlem satırı çalışır ve ilk id değişken değeri olan 1 sayısı ekrana yazılır. Sonra, artırma bölümü devreye girer ve id değişken değeri 1 artarak 2 değerini alır. Yine, 2<=10 ifadesi doğru bir sonuç verdiği için for satırında yer alan işlem satırı çalışır ve id değişken değeri olan 2 sayısı ekrana yazılır. Döngü id değişkeni 10 sayısından büyük bir değer alana kadar devam eder. Değişken 11 değerini aldığında 11<=10 ifadesi yanlış bir sonuç vereceğinden döngü sona erer.

Şimdi, for döngüsü içinde kontrol değişkeni ile farklı bir değişkenin birlikte kullanıldığı bir örneği incelemeye çalışalım:


#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2;

  for (id1=1, id2=0; id1<=10; id1++) {
       id2 += id1;
       cout << id1 << ".safha toplamı: " << id2 << "\n";
  }

  cout << "\n" << "Toplam: " << id2;

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1.safha toplamı: 1
2.safha toplamı: 3
3.safha toplamı: 6
4.safha toplamı: 10
5.safha toplamı: 15
6.safha toplamı: 21
7.safha toplamı: 28
8.safha toplamı: 36
9.safha toplamı: 45
10.safha toplamı: 55

Toplam: 55

Program, for satırının ilk değer atama bölümünde id1 ve id2 değişkenlerine birer değer atar. Döngü ile 1-10 arasındaki sayıların toplamı id2 değişkenine aktarılarak her safhada ve döngü sonunda ekrana yazılır.

Şimdi, for döngüsü içinde kontrol değişkeni ile iki farklı bir değişkenin birlikte kullanıldığı bir örneği incelemeye çalışalım:


#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2, id3;

  for (id1=1, id2=1, id3=0; id1<=10; id1++, id2+=4) {
	   id3 += (id1*id2);
	   cout << id1 << ".safha toplamı: " << id3 << "\n";
  }

  cout << "\n" << "Toplam: " << id3;

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1.safha toplamı: 1
2.safha toplamı: 11
3.safha toplamı: 38
4.safha toplamı: 90
5.safha toplamı: 175
6.safha toplamı: 301
7.safha toplamı: 476
8.safha toplamı: 708
9.safha toplamı: 1005
10.safha toplamı: 1375

Toplam: 1375

Program, for satırının ilk değer atama bölümünde id1, id2 ve id3 değişkenlerine birer değer atar. Döngü ile 1-10 arasındaki sayılar, her defasında 4 artırılmış id2 değişken değeri ile çarpılarak, elde edilen toplam id3 değişkenine aktarılarak her safhada ve döngü sonrasında ekrana yazılır.


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  for (id=1; id<10; id++) {
       cout << id << " sayısının karesi: " << id*id << ", küpü: " << id*id*id << "\n";
  }

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 sayısının karesi: 1, küpü: 1
2 sayısının karesi: 4, küpü: 8
3 sayısının karesi: 9, küpü: 27
4 sayısının karesi: 16, küpü: 64
5 sayısının karesi: 25, küpü: 125
6 sayısının karesi: 36, küpü: 216
7 sayısının karesi: 49, küpü: 343
8 sayısının karesi: 64, küpü: 512
9 sayısının karesi: 81, küpü: 729

Program, bir for döngüsü içinde 1'den 10'a kadar olan sayıların karelerini ve küplerini ekrana yazar.

Şimdi aynı programı döngü içinde fonksiyon kullanarak uygulamaya çalışalım.


#include <iostream>

using namespace std;

int kare_al(int id);
int kup_al(int id);

int main(void)
{
  int id;

  for (id=1; id<10; id++) {
       cout << id << " sayısının karesi: " << kare_al(id) << ", küpü: " << kup_al(id) << "\n";
  }

  return 0;
}

int kare_al(int id)
{
  return id * id;
}

int kup_al(int id)
{
  return id * id * id;
}

Program, bu kez bir for döngüsü içinde 1'den 10'a kadar olan sayıların karelerini ve küplerini sırasıyla kare_al() ve kup_al() fonksiyonlarını kullanarak ekrana yazar.


#include <iostream>

using namespace std;

int topla(int id1);

int main(void)
{
  int id;

  for (id=1; id<10; id++) {
       cout << id << " sayısı altındaki sayılar toplamı: " << topla(id) << "\n";
  }

  return 0;
}

int topla(int id1)
{
  int id2, id3=0;

  for (id2=1; id2<id1; id2++) id3 = id3 + id2;

  return id3;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 sayısı altındaki sayılar toplamı: 0
2 sayısı altındaki sayılar toplamı: 1
3 sayısı altındaki sayılar toplamı: 3
4 sayısı altındaki sayılar toplamı: 6
5 sayısı altındaki sayılar toplamı: 10
6 sayısı altındaki sayılar toplamı: 15
7 sayısı altındaki sayılar toplamı: 21
8 sayısı altındaki sayılar toplamı: 28
9 sayısı altındaki sayılar toplamı: 36

Program, bir for döngüsü içinde 1'den 10'a kadar olan sayıların kendinden küçük sayıların toplamını fonk1() fonksiyonu içindeki bir döngüyü kullanarak ekrana yazar. Burada, fonk1() fonksiyonunun direk olarak printf() fonksiyonunun bir argümanı olarak aynı satırda tanımlandığına dikkat ediniz.


#include <iostream>

using namespace std;

long int fonk(int id1);

int main(void)
{
  int id;

  for (id=1; id<10; id++) {
       cout << id << " sayısının faktoriyel değeri: " << fonk(id) << "\n";
  }

  return 0;
}

long int fonk(int id1)
{
  int id2;
  long int lid=1;

  for (id2=1; id2<=id1; id2++) lid = lid * id2;

  return lid;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 sayısının faktoriyel değeri: 1
2 sayısının faktoriyel değeri: 2
3 sayısının faktoriyel değeri: 6
4 sayısının faktoriyel değeri: 24
5 sayısının faktoriyel değeri: 120
6 sayısının faktoriyel değeri: 720
7 sayısının faktoriyel değeri: 5040
8 sayısının faktoriyel değeri: 40320
9 sayısının faktoriyel değeri: 362880

Program, bir for döngüsü içinde 1'den 10'a kadar olan sayıların faktöriyel değerini fonk() fonksiyonu içindeki bir döngüyü kullanarak ekrana yazar.


#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2=0;

  for (id1=1; id1<100; id1++) {
       if((id1%4==0) && (id1%7==0)) {
          cout << id1 << " ";
          id2++;
       }
  }

  cout << "\n" << "4 ve 7 sayılarına tam olarak bölünebilen sayı adedi: " << id2;

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

28 56 84 
4 ve 7 sayılarına tam olarak bölünebilen sayı adedi: 3

Yukarıdaki örnekte, program 1'den 100'e kadar olan sayılardan 4 ve 7 sayılarına tam olarak bölünebilenleri ve bu sayıların adedini ekrana yazar.


#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2=0;

  for (id1=1; id1<100; id1++) {
       if(!(id1%4) && !(id1%7)) {
          cout << id1 << " ";
          id2++;
       }
  }

  cout << "\n" << "4 ve 7 sayılarına tam olarak bölünebilen sayı adedi: " << id2;

  return 0;
}

Yukarıdaki program, bir önceki programın yaptığı işlemin aynısını gerçekleştirir. Tek fark for döngüsü içindeki koşul satırında (id1%4==0) yerine !(id1%4) ifadesinin ve (id1%7==0) yerine !(id1%7) ifadesinin kullanılmış olmasıdır.


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  for (id=65; id<91; id++)
       cout << (char) id << " karakterinin ASCII kodu: " << id << "\n";

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

A karakterinin ASCII kodu: 65
B karakterinin ASCII kodu: 66
C karakterinin ASCII kodu: 67
D karakterinin ASCII kodu: 68
E karakterinin ASCII kodu: 69
F karakterinin ASCII kodu: 70
G karakterinin ASCII kodu: 71
H karakterinin ASCII kodu: 72
I karakterinin ASCII kodu: 73
J karakterinin ASCII kodu: 74
K karakterinin ASCII kodu: 75
L karakterinin ASCII kodu: 76
M karakterinin ASCII kodu: 77
N karakterinin ASCII kodu: 78
O karakterinin ASCII kodu: 79
P karakterinin ASCII kodu: 80
Q karakterinin ASCII kodu: 81
R karakterinin ASCII kodu: 82
S karakterinin ASCII kodu: 83
T karakterinin ASCII kodu: 84
U karakterinin ASCII kodu: 85
V karakterinin ASCII kodu: 86
W karakterinin ASCII kodu: 87
X karakterinin ASCII kodu: 88
Y karakterinin ASCII kodu: 89
Z karakterinin ASCII kodu: 90

#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2, id3=0;

  for (id1=0; id1<5; id1++) {
       cout << "Bir int değer giriniz: " << id1+1 << ". giriş: ";
       cin >> id2;
       id3 += id2;
  }

  cout << "Girdiğiniz sayıların toplamı: " << id3;

  return 0;
}

Pprogram, klavyeden 5 adet int değer girmenizi ister. Girdiğiniz sayıların toplamını id3 değişkenine atayarak ekrana yazar.


#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2, id3=0, id4=0;

  for (id1=1; id1<5; id1++) {
       cout << id1 << " sayısının karesi kaç eder?";
       cin >> id2;

       if(id2 == id1 * id1) {
          cout << "Cevabınız doğrudur!" << "\n";
          id3++;
       }
       else {
	      cout << "Cevabınız yanlıştır!" << "\n";
		  cout << "Doğru cevap " << id1*id1 << " sayısıdır!" << "\n";
		  id4++;
       }
  }
  cout << "Doğru cevap sayısı: " << id3 << " yanlış cevap sayısı: " << id4;

  return 0;
}

Program, 1'den 5'e kadar olan sayıların karelerinin sıra ile girilmesini ister. Sonra, doğru ve yanlış cevap sayısını kaydederek ekrana yazar.


#include <iostream>

using namespace std;

int kare_kontrol(int deger, int kare);

int main(void)
{
  int id1, id2, id3=0, id4=0;

  for (id1=1; id1<5; id1++) {
       cout << id1 << " sayısının karesi kaç eder?";
       cin >> id2;

       if(kare_kontrol(id1, id2)) {
          cout << "Cevabınız doğrudur!" << "\n";
          id3++;
       }
       else {
	      cout << "Cevabınız yanlıştır!" << "\n";
		  cout << "Doğru cevap " << id1*id1 << " sayısıdır!" << "\n";
		  id4++;
       }
  }
  cout << "Doğru cevap sayısı: " << id3 << " yanlış cevap sayısı: " << id4;

  return 0;
}

int kare_kontrol(int deger, int kare)
{
  return (kare == deger * deger);
}

Yukarıdaki örnekte, program bir önceki programın yaptığı işlemin aynısını yapar. Tek farkı fonksiyon kullanılmasıdır. Sayı ve sayının karesi kare_kontrol() fonksiyonuna argüman olarak geçirilir. Cevap doğru olduğunda kare_kontrol() fonksiyonu doğru değer döndüreceği için if satırındaki koşul sağlanır ve id3 değişken değeri artırılır. Aksi takdirde, id4 değişken değeri artırılır.

Şimdiye kadar verdiğimiz örneklerde, biz ilk değer atama bölümünü bir döngü kontrol değişkenine ilk değer atayan bir bölüm olarak, koşul bölümünü döngüyü sona erdirmek için döngü kontrol değişkenini kullanan bir bölüm olarak ve artırma bölümünü bir döngünün her tekrarlanmasında bir değişken değerini artıran veya azaltan bir bölüm olarak kullandık.

for döngüsünün bütün bölümlerinde herhangi bir ifade kullanılabilir. Yani, ilk değer atama bölümünde bir döngü kontrol değişkenine bir ilk değer vermekten başka bir ifade, koşul bölümünde döngüyü sona erdirecek başka bir ifade, artırma bölümünde ise bir değişken değerini artırmak ya da azaltmak yerine döngünün her tekrarlanmasında değerlendirilecek bir ifade tanımlamak mümkündür. Bu özellikler sayesinde for döngüsüyle esnek ve detaylı özellikler sağlayan programlar geliştirebiliriz.

Ayrıca, for döngüsünde her bölüme bir değer atama zorunluluğu yoktur. İlk değer atama, koşul ve artırma bölümlerinden birini veya tamamını hiç kullanmayabilirsiniz. Döngü içinde kullanılmayan bölüm boş kalır. Şimdi, bahsettiğimiz özellikleri örnekler üzerinde incelemeye çalışalım:


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  // İlk değer atama, koşul ve artırma bölümlerinin tamamını kullanma
  for (id=1; id<=10; id++) cout << id << " ";

  cout << "\n";

  id = 1; // for döngü kontrol değişkenine ilk değer atama
  // Sadece koşul ve artırma bölümlerini kullanma
  for ( ; id<=10; id++) cout << id << " ";

  cout << "\n";

  id = 1;
  // Sadece koşul bölümünü kullanma
  for ( ; id<=10; ) {
       cout << id << " ";
       id++; // Döngü kontrol değişkeni artırma
  }

  cout << "\n";

  id = 1;
  // Sadece koşul bölümünü kullanma
  for ( ; id<=10; ) {
       cout << id++ << " "; // Döngü kontrol değişkeni artırma
  }

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 2 3 4 5 6 7 8 9 10 
1 2 3 4 5 6 7 8 9 10 
1 2 3 4 5 6 7 8 9 10 
1 2 3 4 5 6 7 8 9 10 

Program, 1'den 10'a kadar olan sayıları, for döngüsünü farklı şekilde kullanarak, dört defa ekrana yazar. İlk for döngüsünde, for döngüsünün ilk değer atama, koşul ve artırma bölümlerinin tamamını kullanır. Diğer üç for döngüsünde, ilk değer atama işlemini döngü öncesinde yapar. Üçüncü ve dördüncü for döngüsünde, döngü kontrol değişkeni değer artırma işlemini döngü kod bloğu içinde yapar.

for satırında ilk değer atama ve artırma bölümlerini boş bırakarak farklı yöntemlerle bu işlemleri gerçekleştirdik. Bu durumda yapılan iş açısından bir fark oluşmaz, sadece yöntem değişir. Ancak, koşul bölümünü boş bırakırsak, program herhangi bir kontrol yapmadan döngü içine girer, döngünün sona ermesi için herhangi bir koşul tanımlanmadığından, döngü sonsuza dek devam eder. Çünkü, döngüdeki koşul bölümü boş olduğunda, derleyici bu bölümün sonucunu daima doğru olarak kabul eder. for döngüsü içinde yer alan bütün bölümleri boş bırakarak sonsuz bir döngü tanımlayabiliriz. Sonsuz döngü hiç durmadan bir işlem satırını veya bir kod bloğunu çalıştıran bir döngü olarak tanımlanabilir.

for ( ; ; ) işlem-satırı

Şimdi, bu konuyu örnekler üzerinde incelemeye çalışalım:


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  for (id=0; ;id++) {
       cout << id << " ";
  }

  return 0;
}

Yukarıdaki örnekte, program 0'dan başlayarak ve her defasında 1 artırarak id değişken değerini ekrana yazar. Döngü koşul bölümünde herhangi bir tanımlama yapılmadığından, program sonsuz bir döngü içine girer. Bu programın çalışmasını konsol üzerinde CTRL-C tuşlarına basarak sona erdirebiliriz.

Programı, ilk değer atama ve artırma bölümleri for satırı dışında olacak biçimde, aşağıdaki şekilde yazabiliriz:


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  for ( ; ; ) {
       cout << id++ << " ";
  }

  return 0;
}

Şimdi vereceğimiz örneklerle öğrendiklerimizi pekiştirelim:


#include <iostream>

using namespace std;

int main(void)
{
  char cd='a';
  int id;

  for (id=0; cd!='s'; ) {
       cout << "Bir karakter giriniz : ";
       cin >> cd;
       id++;
  }

  cout << "Toplam " << id << " adet karakter girdiniz!";

  return 0;
}
 

Program, cd char değişkenine a harfini atar. Klavyeden bir karakter girmenizi ister. Girdiğiniz karakter s harfinden farklı olduğu sürece, girdiğiniz karakter ekrana yazılır ve döngü devam eder. Döngü sona erdiğinde girilen toplam karakter sayısını da ekrana yazar.


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  cout << "Bir int değer giriniz: ";
  cin >> id;

  for ( ; id; id--) {
       if(id%2) cout << "A ";
       else cout << "B ";
  }

  return 0;
}

Yukarıdaki örnekte, program sizin girdiğiniz sayıda ekrana A ve B harfi yazar. Program önce bir int değer girmenizi ister ve girdiğiniz sayıyı for döngüsünde kontrol değişkeni olarak kullanır. Değişken değeri çift bir sayı iken A harfini, tek bir sayı iken B harfini ekrana yazar. Koşul bölümünde kullanılan (id%2) ifadesi ((id%2)!=0) ifadesi ile aynı işlemi gerçekleştirmektedir.


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  for (id=120; id; id=id/2) cout << id << " ";

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

120 60 30 15 7 3 1

Program for döngüsü azaltma bölümünde çevrim kontrol değişken değerinin yarısını alarak döngüyü devam ettirir.


#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2;

  cout << "Tek bir int değer giriniz: ";
  cin >> id1;

  cout << "Çift int değer giriniz: ";
  cin >> id2;

  if (id1 && id2 && (id1%2) && (id2%2==0)) {
      for ( ; id1>0 && id2>0; id1--, id2--) {
           cout << id1 << " " << id2 << "\n";
      }
  }

  return 0;
}

Program, girilen tek sayıyı id1 değişkenine, çift sayıyı ise id2 değişkenine atar. Eğer girilen değerlerin her ikisi de 0'dan büyük ve istenen tek çift sayı niteliğini taşıyorlarsa döngü satırı devreye girer. Aksi takdirde, istenilen koşul karşılanmadığından döngü satırı devreye girmez. for döngüsü her iki değişken değeri de 0'dan büyük olduğu sürece devam eder ve program değişken değerlerini ekrana yazar. Burada, artırma ve azaltma bölümünde her iki değişken değerinin de azaltıldığına ve değerlerin virgül ile ayrıldığına dikkat ediniz.


#include <iostream>

using namespace std;

int fonk(int id);

int main(void)
{
  int id;

  for (id=1; fonk(id); id++) {
       cout << id*id << " ";
  }

  return 0;
}

int fonk(int id)
{
  return (id<=10);
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 4 9 16 25 36 49 64 81 100

Program 1'den 10'a kadar olan sayıların karelerini ekrana yazar. Bu işlemi yaparken for döngüsünün koşul bölümünde bir fonksiyon çağrısı kullanır. Fonksiyonun geri verdiği değer doğru olduğu sürece döngü çalışmasına devam der.

C++'da döngüleri tek başına kullanabileceğimiz gibi, birbiri içinde de kullanabiliriz. Eğer bir döngüyü, başka bir döngünün kod bloğu içinde tanımlarsak, iç içe döngü oluşturulmuş olur. Şimdi basit bir örnek üzerinde bu özelliği inceleyelim:


#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2;

  for (id1=0; id1<5; id1++ ) {
       for (id2=0; id2<10; id2++) cout << id2 << " ";
       cout << "\n";
  }

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9

Program, önce ilk for döngüsünde id1 değişkenine 0 değerini atar. Koşul bölümünde doğru bir sonuç elde ettiği için ilk for döngüsü ile ilgili kod bloğunu çalıştırır. Kod bloğu içindeki for döngüsüne ait id2 değişkenine 0 değerini atar. Koşul bölümünde doğru bir sonuç elde ettiği için ikinci for döngüsü ile ilgili işlem satırını çalıştırır ve ekrana 0 değerini yazar. İkinci döngü, daha önce gördüğümüz gibi, id2 değişken değeri 10'dan küçük olduğu sürece çalışmasına devam eder ve ekrana aşağıdaki satırı yazar:

0 1 2 3 4 5 6 7 8 9

İkinci for döngüsü sona erdiğinde program kod bloğu içinde yer alan ikinci satır ile satır başı yapar. Daha sonra program ilk for döngüsünde id1 değişkeninin değerini 1 artırarak tekrar kod bloğunu çalıştırır. İlk for döngüsü de id1 değişken değeri 5'den küçük olduğu sürece çalışmasına devam eder. İlk for döngüsünün her tekrarında kod bloğunda yer alan ikinci for döngüsü 10 defa tekrar eder.

Şimdi öğrendiklerimizi örneklerle pekiştirmeye çalışalım:


#include <iostream>

using namespace std;

int main(void)
{
  int id;
  char cd;

  for (id=0; id<4; id++) {
       for (cd='A'; cd<='Z'; cd++) cout << cd << " ";
       cout << "\n";
  }

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Program büyük harfleri sıra ile dört defa ekrana yazar. Bu işlemi yaparken iç içe 2 döngü kullanır.


#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2;
  char cd;

  for (id1=0; id1<5; id1++) {
       for (cd='a'; cd<='f'; cd++) {
            for (id2=0; id2<3; id2++) cout << cd << " ";
       }
       cout << "\n";
  }

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

a a a b b b c c c d d d e e e f f f
a a a b b b c c c d d d e e e f f f
a a a b b b c c c d d d e e e f f f
a a a b b b c c c d d d e e e f f f
a a a b b b c c c d d d e e e f f f

Program, iç içe ü. for döngüsü kullanarak a harfinden f harfine kadar olan harfleri, her tekrarda üçer defa olmak üzere, 5 kez ekrana yazar.

while döngüsü

C++'da kullanılan diğer bir döngü de while döngüsüdür. Döngünün genel yapısı aşağıda gösterilmektedir:

while (ifade) işlem-satırı;

while (ifade) {
	işlem-satırı;
	.
	.
	.
	işlem-satırı;
}	

Daha önce for döngüsünde gördüğümüz gibi işlem satırı yerine bir kod bloğu da kullanılabilir. Program while döngüsünün bulunduğu satıra geldiği zaman önce ifade sonucunun doğru olup olmadığını kontrol eder. Eğer ifade yanlış bir sonuç verirse döngüye hiç girmeden döngüden hemen sonra yer alan işlem satırından çalışmasına devam eder. Eğer ifade doğru bir sonuç verirse, döngüde yer alan ifade yanlış bir sonuç verene kadar, döngü içinde yer alan işlem satırlarını çalıştırır. Yani, ifade doğru olduğu sürece döngü çalışmasına devam eder. while döngüsünde ifadenin sonucu döngünün başlangıcında kontrol edildiğinden, ifadenin yanlış sonuç verdiği durumlarda döngü bir defa bile çalışmaz.

while döngüsünde, for döngüsünden farklı olarak, ilk değer atama ve artırma/azaltma bölümleri bulunmamaktadır. while döngüsünde ilk değer atama işlemi döngü öncesinde, artırma/azaltma işlemi ise döngü kod bloğu içinde yapılır.

Şimdi öğrendiklerimizi örnekler üzerinde inceleyelim:


#include <iostream>

using namespace std;

int main(void)
{
  int id=1; // Döngü kontrol değişkenine ilk değer atama

  while (id<=10) {
     cout << id << " ";
     id++; // Döngü kontrol değişkeni değer artırma
  }

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 2 3 4 5 6 7 8 9 10

Program, 1'den 10'a kadar olan sayıları ekrana yazar. Döngü kontrol değişkeninin başlangıç değerini döngüden önce verir. Değişken değerinin artırılması ise while döngüsüne bağlı kod bloğu içinde yapılır. while döngüsü id değişkeni 10 sayısından büyük bir değer alana kadar çalışır.

Aynı programı aşağıdaki şekilde de yazabiliriz:


#include <stdio.h>

int main(void)
{
  int id=1;

  while (id<=10) cout << id++ << " ";
  
  return 0;
}

Şimdi, iç içe iki while döngüsünün kullanılmasını bir örnek üzerinde incelemeye çalışalım:


#include <iostream>

using namespace std;

int main(void)
{
  int id=1;
  char cd;

  while (id<=5) {
     cd = 'A';
     while (cd<='K') {
        cout << cd++ << " ";
     }
     cout << "\n";
     id++;
  }

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

A B C D E F G H I J K 
A B C D E F G H I J K 
A B C D E F G H I J K 
A B C D E F G H I J K 
A B C D E F G H I J K 

Program, iç içe iki while döngüsü kullanarak alfabenin 11 karakterini ekrana yazar.

Şimdi, farklı örneklerle öğrendiklerimizi incelemeye devam edelim:


#include <iostream>

using namespace std;

int main(void)
{
  char cd;

  cd = 'a';

  while (cd != 'c') {
     cout << "Bir harf giriniz: ";
     cin >> cd;
     cout << cd << "\n";
  }

  cout << "c harfini girdiniz ve döngüden çıktınız!";

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

c harfini girdiniz ve döngüden çıktınız!

Program, c harfinden farklı bir harf girildiği sürece bir harf girilmesini isteyen bir while döngüsünü çalıştırır. c harfi girildiğinde döngü sona erer ve yukarıdaki cümleyi ekrana yazar:

Döngüden önce, cd değişkenine a harfinin atanmasının nedeni döngüye girişin sağlanması içindir.


#include <iostream>

using namespace std;

int main(void)
{
  int id=1;

  while (id<=100) {
     cout << "Bir int değer giriniz: ";
     cin >> id;
  }

  cout << "Girilen sayı 100'den büyük olduğundan döngü sona erdi!";

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

Girilen sayı 100'den büyük olduğundan döngü sona erdi!

Program, girilen sayı 100'den küçük olduğu sürece bir int değer girilmesini ister. Eğer girilen değer 100'den büyük ise döngü sona erer ve program yukarıda yer alan cümleyi ekrana yazar:

id değişkenine atanan 1 değerinin döngüye girişi sağlamak için verildiğine dikkat ediniz. Bu değer verilmediğinde id değişkeni rastgele bir değer alacağı için döngüye giriş kesin olmaz.


#include <iostream>

using namespace std;

int main(void)
{
  int id1=11;
  int id2;

  while (id1>10) {
     cout << "Bir int değer giriniz: ";
     cin >> id1;
  }
  cout << "Girilen sayı 10 veya daha küçük bir sayı olduğundan döngü sona erdi!" << "\n";

  id2=1;

  while (id2<id1) cout << id2++ << " ";

  return 0;
}

Yukarıdaki örnekte, program girdiğiniz sayı 10'dan büyük olduğu sürece sizden bir int değer girmenizi ister. Eğer girdiğiniz int değer 10 veya daha küçük ise döngü sona erer ve aşağıdaki cümleyi ekrana yazar:

Girilen sayı 10 veya daha küçük bir sayı olduğundan döngü sona erdi!

Daha sonra, ikinci while döngüsü ile 1'den başlayarak girdiğiniz sayıya kadar olan değerleri ekrana yazar.


#include <iostream>

using namespace std;

int main(void)
{
  int id1=11, id2, id3;

  while (id1>10) {
     cout << "Bir int değer giriniz: ";
     cin >> id1;
  }
  cout << "Girilen sayı 10 veya daha küçük bir sayı olduğundan döngü sona erdi!" << "\n";

  id3 = 0;
  while (id3<10) {
     id2 = 1;
     while (id2<id1) {
        cout << id2++ << " ";
     }
     cout << "\n";
     id3++;
  }

  return 0;
}

Program, bir önceki programın yaptığı işe ek olarak, ikinci while döngüsü yerine iç içe iki adet while döngüsü kullanarak ekrana yazdırma işlemini 10 kez tekrar eder.

do while döngüsü

C++'da kullanılan döngülerden sonuncusu do while döngüsüdür. Döngünün genel yapısı aşağıda gösterilmektedir:

do {
   işlem-satırı;
   .
   .
   .
   işlem-satırı;
} while (ifade);

Program do döngüsüne geldiğinde hiç bir koşula bağlı olmadan direk olarak döngüye giriş yapar. Döngünün içinde yer alan işlem satırlarını çalıştırır. Eğer döngünün son satırında yer alan while deyimi ile ilgili ifade doğru sonuç vermez ise döngü sona erer. do döngüsünde eğer sadece tek bir işlem satırı tekrarlanacaksa { } işaretlerine gerek yoktur. Döngü, while satırındaki ifade sonucu doğru olduğu sürece çalışmasına devam eder.

do döngüsünde koşul kontrolü döngü sonunda yapıldığından koşul sağlanmasa bile döngü en az bir defa çalışır. Bu yönü ile do döngüsü for ve while döngülerinden farklıdır.

Şimdi öğrendiklerimizi örnekler üzerinde inceleyelim:


#include <iostream>

using namespace std;

int main(void)
{
  int id=1; // Döngü kontrol değişkeni ilk değer atama

  do {
     cout << id++ << " ";
  } while (id<=10);

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 2 3 4 5 6 7 8 9 10

Program, 1'den 10'a kadar olan sayıları ekrana yazar. Döngü kontrol değişkeninin başlangıç değerini döngüden önce verir. Değişken değerinin artırılması ise do while döngüsüne bağlı kod bloğu içinde yapılır. Döngü id1 değişkeni 10 sayısından büyük bir değer alana kadar çalışır. Döngüye giriş için herhangi bir koşula gerek olmadığına, sadece sonraki tekrarlar için koşul sağlanması gerektiğine dikkat ediniz.


#include <iostream>

using namespace std;

int main(void)
{
  char cd;

  cd = 'a';

  do {
     cout << "Bir harf giriniz: ";
     cin >> cd;
     cout << cd << "\n";
  } while (cd != 'c');

  cout << "c harfi girildiğinden döngü sona erdi!";

  return 0;
}

Program, c harfinden farklı bir harf girildiği sürece bir harf girmenizi isteyen bir do while döngüsünü çalıştırır. c harfi girildiğinde, döngü sona erer ve aşağıdaki cümleyi ekrana yazar:

c harfi girildiğinden döngü sona erdi!

Program direk olarak döngünün içine girer ve işlem satırlarının en az bir defa olmak üzere gereğini yapar.


#include <iostream>

using namespace std;

int main(void)
{
  char cd;

  cout << "Bir karakter giriniz:" << "\n";

  do {
     cin >> cd;
     cout << "Girdiğiniz karakter: " << cd << " ASCII kodu: " << (int)cd << "\n";
  } while (cd!='\r');

  return 0;
}

Program, bir karakter girmenizi ister. Girdiğiniz karakteri ve ASCII kodunu ekrana yazar. ENTER tuşuna basmadığınız sürece program do döngüsünü çalıştırmaya devam eder.


#include <stdio.h>

int main(void)
{
  int id1, id2=0;

  do {
     id1=1;
     do {
        cout << id1++ << " "
     } while (id1<=10); 
     cout << "\n";  
  } while (++id2<5); 
  
  return 0;
}

Yukarıdaki örnekte, program aşağıdaki satırları ekrana yazar:

1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

Program, iç içe 2 adet do while döngüsü kullanarak 1'den 10'a kadar olan sayıları 5 kez ekrana yazar. Aşağıdaki işlem satırındaki özelliğe dikkat ediniz:

while (++id2<5);

Burada değişkenin artırılan değerinin aynı satırda değerlendirilmesi için ++ işlemcisi değişken adından önce kullanılmıştır. Eğer döngü koşul kontrolü koşul ifadesini aşağıdaki şekilde tanımlarsak döngü beş defa yerine altı defa çalışır:

while (id2++<5);

for, while ve do while döngülerini bir örnek üzerinde incelemeye çalışalım:


#include <iostream>

using namespace std;

int main(void)
{
  int id1, id2, id3=3;

  cout << "do while döngüsü ile yazdırma:" << "\n\n";

  id2 = 0;

  do {
     id1=1;
     do {
        cout << id1++ << " ";
     } while (id1<=10);
     cout << "\n";
  } while (++id2<id3);

  cout << "\n" << "while döngüsü ile yazdırma:" << "\n\n";

  id2 = 0;

  while (id2++<id3) {
     id1=1;
     while (id1<=10) {
        cout << id1++ << " ";
     }
     cout << "\n";
  }

  cout << "\n" << "for döngüsü ile yazdırma:" << "\n\n";

  for (id2=0; id2<id3; id2++) {
       for (id1=1; id1<=10; id1++) {
            cout << id1 << " ";
       }
       cout << "\n";
  }

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

do while döngüsü ile yazdırma:

1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

while döngüsü ile yazdırma:

1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

for döngüsü ile yazdırma:

1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

Program, 1'den 10'a a kadar olan sayıları her defasında iç içe farklı döngü sistemi kullanarak 3 kez ekrana yazar. Aşağıda gösterildiği gibi do while döngüsünde artırma işlemcisinin (++) id2 değişken değerinden önce, diğer döngülerde ise sonra kullanıldığına dikkat ediniz:

} while (++id2<id3); // do while döngüsü artırma satırı

while (id2++<id3) // while döngüsü artırma satırı

for (id2=0; id2<id3; id2++) { // for döngüsü artırma satırı

for, while ve do while döngülerinin birlikte incelenmesi

C++'da kullanılan 3 farklı döngü inceledik. Şimdi, bu üç döngünün özelliklerini aşağıdaki örnekler üzerinde tekrar gözden geçirelim:


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  for (id=1; id<11; id++) cout << id << " ";

  cout << "\n";
  id=1;
  for ( ; id<11; ) cout << id++ << " ";

  cout << "\n";
  id=1;
  while (id<11) {
     cout << id++ << " ";
  }

  cout << "\n";
  id=1;
  do {
     cout << id++ << " ";
  } while (id<11);

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10

Program, for döngüsünü iki defa, while ve do while döngülerini ise birer defa kullanarak, 1-10 arasındaki sayıları dört defa ekrana yazar. İlk for döngüsünde, ilk değer atama, koşul ve kontrol değişkeni artırma işlemlerini, ikinci for döngüsünde ise, sadece koşul işlemini for işlem satırında yapar.

Döngülerle ilgili olarak 3 temel kavram bulunmaktadır:

1. İlk değer atama
2. Koşul
3. Artırma (Azaltma)

* for döngüsünde bütün kavramlar for satırında yer alan parantezler içinde tanımlanabileceği gibi, ilk değer atama bölümü döngü öncesinde ve artırma/azaltma bölümü döngü kod bloğu içinde tanımlanabilir.

* while döngüsünde ilk değer atama bölümü döngü öncesinde, koşul bölümü while satırında yer alan parantezler içinde, artırma/azaltma bölümü ise koşul sağlandığı takdirde çalışan kod bloğunun içinde tanımlanır.

* do döngüsünde ise, ilk değer atama bölümü döngü öncesinde, koşul bölümü döngü sonundaki while satırında yer alan parantezler içinde, artırma/azaltma bölümü ise döngüye bağlı kod bloğu içinde tanımlanır.

do döngüsünün diğer döngülerden en büyük farkı, koşul kontrolü döngü sonunda yapıldığı için, koşul sağlanmasa bile döngünün en az bir kez çalışmasıdır. for ve while döngüleri ise, koşul sağlanmadığı takdirde hiç çalışmaz.

İhtiyacımıza bağlı olarak bu döngülerden herhangi birini kullanmak tamamen tercihe bağlıdır. Program içinde kullanma yerine bağlı olarak bu döngülerden hangisinin daha yararlı ve pratik olacağına karar verebiliriz.

break deyimi

Normal koşullarda, bir döngü koşul bölümü doğru sonuç verdiği sürece çalışmasına devam eder. Ancak, döngü kod bloğu içinde özel bir tanımlama yaparak da döngüyü sona erdirebiliriz. Bu işlemi gerçekleştirmek için break deyimini kullanabiliriz.

Bir döngüyü, döngünün koşul bölümüne bağlı kalmaksızın sona erdirmek için break deyimi kullanılır. break deyimi döngüye bağlı kod bloğunun herhangi bir işlem satırında yer alabilir. Program kod bloğunda break deyimini görür görmez, döngü başlangıç koşulu sağlanmış olsa bile, döngüden çıkar ve döngüden sonra gelen ilk işlem satırından çalışmasına devam eder. break deyimi C++'deki her 3 döngü ile kullanılabilir. İç içe döngülerde break deyimi kullanıldığında sadece içinde kullanıldığı döngüden çıkışı sağlar. Şimdi, break deyiminin kullanılmasını örnekler üzerinde incelemeye çalışalım:


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  for (id=1; id<=20; id++) {
       cout << id << " ";
       if (id==15) break;
  }

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Program, break işlem satırı tanımlanmadığında 1'den 20'ye kadar olan sayıları ekrana yazar. Ancak, for döngüsüne bağlı kod bloğunun ikinci satırında kullanılmış olan break deyimi kullanıldığı için, program for döngüsünde id değişkenine 15 değerini atadığında if satırında koşul doğru sonuç verdiğinde, break deyimi devreye gireceğinden, döngü hemen sona erer. Eğer break deyimi printf() fonksiyon işlem satırından önce yazılmış olsaydı, program 15 sayısını da yazmadan döngü sona erecekti.


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  for (id=1; id<100; id++) {
       if((id%2==0) && (id%3==0) && (id%4==0) && (id%5==0)) {
          cout << "2, 3, 4 ve 5 sayılarına kalansız olarak bölünebilen en küçük sayı:" << id;
          break;
       }
  }

  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

2, 3, 4 ve 5 sayılarına kalansız olarak bölünebilen en küçük sayı: 60

Program, for döngüsünde 1 sayısından başlayarak her sayının 2, 3, 4 ve 5 sayılarına bölündüğünde kalanlarını bir if koşuluyla değerlendirerek çalışmasına devam eder. 2, 3, 4 ve 5 sayılarına kalansız olarak bölünen 60 sayısına geldiğinde if koşulu karşılanır ve cout fonksiyonu ile sayı ekrana yazıldıktan sonra break deyimi ile döngü sona erer.

continue deyimi

continue deyimi, bir döngünün herhangi bir satırından itibaren döngünün geri kalan işlem satırlarını çalıştırmadan, döngünün baş tarafına dönme olanağı sağlar.

do ve while döngülerinde, program continue deyimi ile karşılaştığında, koşul bölümünü kontrol eder ve döngünün çalışmasını devam ettirir. for döngüsünde ise, artırma ve koşul bölümünü çalıştırdıktan sonra döngünün çalışmasını devam ettirir. Şimdi continue deyiminin kullanılmasını bir örnek üzerinde incelemeye çalışalım:


#include <iostream>

using namespace std;

int main(void)
{
  int id;

  for (id=0; id<20; id++) {
       if (id%2==0) continue;  
       cout << id << " ";
  }
  
  return 0;
}

Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:

1 3 5 7 9 11 13 15 17 19

Program, for döngüsü içindeki continue deyiminden dolayı, döngünün ilk satırında eğer id değişken değeri çift bir sayı ise geri kalan kalan satırları devre dışı bırakarak, değişken değerini ekrana yazmadan, bir sonraki döngü değeri ile çalışmasına devam eder.