C++ Ders5 - Donguler

43
Döngüler (while–for)

description

donguler

Transcript of C++ Ders5 - Donguler

Page 1: C++ Ders5 - Donguler

Döngüler(while–for)

Page 2: C++ Ders5 - Donguler

Seçimden Tekrara Geçiş� if önermesi ve if/else önermesi bir kod bloğunu belli bir koşula bağlı

olarak seçmemizi sağlarcout << "Lütfen negatif olmayan bir sayı giriniz: " << endl;cin >> sayı; if (sayı < 0){

cout << sayı << " negatif. Yanlış girildi!" << endl;}

� Bu yukarıdaki kod eğer girilen ilk sayı negatif ise yeni bir sayı daha girmenizi isteyemez.

------------------------------------------------------------------------------------------------------

� Öte yandan aşağıdaki while döngüsü koşul doğru (true) olduğu sürece altındaki kod bloğunu sürekli olarak çalıştırırcout << " Lütfen negatif olmayan bir sayı giriniz: " << endl;cin >> sayı; while (sayı < 0){

cout << sayı << " negatif! Tekrar deneyiniz." << endl;cin >> sayı;

}

Page 3: C++ Ders5 - Donguler

while döngüsünün anlamı

if (koşul) while (koşul){ {önerme listesi; önerme listesi;

} }

koşul

önerme listesi

sonraki önerme

true

false

koşul

önerme listesi

sonraki önerme

true

false

Page 4: C++ Ders5 - Donguler

Toplam Örneği: neden döngüler?� 10 positif sayının toplamını bulmak istiyoruz

� Şu şekilde yazabiliriz:

int sayı1, sayı2, sayı3, sayı4, sayı5;

int toplam;

cin >> sayı1 >> sayı2 >> sayı3 >> sayı4 >> sayı5;

toplam = sayı1 + sayı2 + sayı3 + sayı4 + sayı5;

cin >> sayı1 >> sayı2 >> sayı3 >> sayı4 >> sayı5;

toplam += sayı1 + sayı2 + sayı3 + sayı4 + sayı5;

Page 5: C++ Ders5 - Donguler

Toplam Örneği

� Ya toplamını hesaplamak istediğimiz� 100 sayı olsaydı?

� Belirsiz sayıda sayı olsaydı?

� Đhtiyacımız olan şey istediğimiz kadar sayıda değer okuyup onların toplamını hesaplamak aslında.

� Bunu yapmak döngülerle mümkün

� Güzel çözüm döngü kullanmak olacaktır.� Kodu sıfırdan yaz. sum10nums.cpp

� Bu tür döngülere sayan (counting) döngüler diyoruz� Đterasyon sayısı biliniyor

Page 6: C++ Ders5 - Donguler

Basit bir başka örnek

� 1 ile 10 arasındaki tamsayıların toplamını hesaplamak

int toplam = 0; // bu program parcasıint i = 1; // 1 ıle 10 arasındakıwhile (i <= 10) // tamsayıların toplamını{ // hesaplıyor

toplam += i;i += 1;

}

Page 7: C++ Ders5 - Donguler

Örneği adım adım gözden geçirme

int toplam = 0;

int i = 1;

while (i <= 10)

{

toplam += i;

i = i + 1;

}

cout << toplam;

i<=10

toplam+=i;i=i+1;

true

cout<<toplam;

false

1i

toplam 0

2

1

Page 8: C++ Ders5 - Donguler

Örneği adım adım gözden geçirme

int toplam = 0;

int i = 1;

while (i <= 10)

{

toplam += i;

i = i + 1;

}

cout << toplam;

i<=10

toplam+=i;i=i+1;

true

cout<<toplam;

false

2i

toplam 1

3

3

Page 9: C++ Ders5 - Donguler

Örneği adım adım gözden geçirme

int toplam = 0;

int i = 1;

while (i <= 10)

{

toplam += i;

i = i + 1;

}

cout << toplam;

i<=10

toplam+=i;i=i+1;

true

cout<<toplam;

false

3i

toplam 3

4

6

Page 10: C++ Ders5 - Donguler

Örneği adım adım gözden geçirme

int toplam = 0;

int i = 1;

while (i <= 10)

{

toplam += i;

i = i + 1;

}

cout << toplam;

i<=10

toplam+=i;i=i+1;

true

cout<<toplam;

false

10i

toplam45

11

55

Page 11: C++ Ders5 - Donguler

while döngüsünün sentaksı

<başlangıç durumu>

while (<koşul>)

{

<önerme_1>;

...

<önerme_N>;

<güncelleme>

}

Page 12: C++ Ders5 - Donguler

while döngüsü toplam örneği

� 1..10 arasındaki sayıların toplamı

int toplam = 0;

int i = 1;

while (i <= 10)

{

toplam += i;

i = i + 1;

}

cout << toplam;

initialization

önermeler

update

koşul

Page 13: C++ Ders5 - Donguler

Döngünün Anatomisi� Döngünün bloğunda ve koşulunda kullanılan değişkenlerin ilk

değerlerini verin (döngüden önce)� Genel bir kural yok. Duruma bağlı olarak ilk değerlerini atayın.

� Döngünün koşulu her döngü tekrarından önce değerlendirilir� Döngünün bloğundaki her bir önermeden sonra değerlendirilmez� Er döngü tekrarından önce koşulun değerlendirmesinde değişkenlerin

o anki değerleri kullanılır

� Döngünün önermeleri döngü koşulunda kullanılan bazıdeğişkenleri mutlaka değiştirmelidir ki döngü eninde sonunda son bulsun� Eğer döngünün koşulu hep true ise, döngü sonsuza girer

� Sonsuz döngülerden sakınmak gerekir

� Döngü tasarımındaki basit kural:� Başlangıç durumu, döngü koşul ve güncelleme kısımları döngünün

yeterli sayıda tekrarlaması için dikkatlice tasarlanmalıdır. Ama döngüne bir az ne de bir fazla tekrarlamamalıdır.

� Maalesef hatasız bir döngü tasarlamak için direk bir yöntem yoktur

Page 14: C++ Ders5 - Donguler

for döngüsü sentaksı

for (<başlangıç>; <koşul>; <güncelleme>)

{

<önerme_1>;...< önerme_N>;

}

� Başlangıç, koşul ve güncelleme kısımları birleştirilmiştir

� Sayı sayan ve bir indeksi olan döngüler için idealdir.

Page 15: C++ Ders5 - Donguler

for döngüsünün while ile karşılaştırması

<başlangıç>

while (<koşul>)

{

<önerme_1>;

...

<önerme_N>;

<güncelleme>

}

for (<başlangıç>;

<koşul>;

<güncelleme> )

{

<önerme_1>;...<önerme_N>;

}

Page 16: C++ Ders5 - Donguler

for döngüsü örneği

• Aynı döngüyü bu kez for ile yazalım: 1..10 arasındaki sayıların toplamı

int toplam = 0;

int i = 1;

while (i <= 10)

{

toplam += i;

i = i + 1;

}

int toplam = 0;

for (int i=1; i <= 10; i=i+1)

{

toplam += i;

}

Page 17: C++ Ders5 - Donguler

for döngüsü

� Başlangıç önermeleri� Döngüden önce çalıştırılır

� Koşul ifadesi� boolean ifade� her döngü içine girmeden önce kontrol edilir

� Eğer doğru ise döngü önermeleri çalıştırılır, yanlış ise döngü sonlandırılır

� Güncelleme önermesi� En son önermeden sonra çalıştırılır

� Birden fazla başlangıç durumu önermesi ve güncelleme önermeleri virgül ile ayrılabilirfor(len = s.length(), k=0; k < len; k+=1)

� Başlangıç durumu önermesi ve/veya koşul ve/veyagüncelleme kısımları eksik olabilir� Ama noktalı virgül her zaman orada olmalıdır

Page 18: C++ Ders5 - Donguler

Kötü Döngüler1. for (int i = 10; i < 5; i++)

{

cout << "Kaç kez ekrana yazarım?";

}

2. for (int i = 10; i >= 1; i++)

{

cout << "Kaç kez ekrana yazarım?";

}

3. int i = 1;

while (i < 20)

{

cout << "Kaç kez ekrana yazarım?";

}

Page 19: C++ Ders5 - Donguler

Bad loops� Never executes

� Never stops (infinite loops)� Example: consider the following modified code from sum10nums� What’s the problem in the loop below? What is missing?

toplam = 0; count = 1;while (count <= 10){

cin >> num;toplam += num;

}

� count never reaches 10, because count is not updated in the loop

Page 20: C++ Ders5 - Donguler

Sonsuz Döngüler� Sonsuz döngülerden sakınmalısınız

� Döngünün koşulu hep doğru kalırsa başınıza gelir� Aynı döngü önermeleri tekrarlar durur

� Bazen ekranda birşeyler görürsünüz, bazen görmezsiniz bile� Ctrl-C ile durdurabilirsiniz programınızı

� Ya bir güncelleme önermesini unutmuşşunuzdur� Ya da yanlış yazılan bir koşul ifadesidir

Page 21: C++ Ders5 - Donguler

Sonsuz Döngüler� Aşağıdaki kodun problemi nedir?

� Sonsuz döngü var kesin diyemeyiz, girilen sayıya bağlı� örneğin, sayı tek ise, döngü sonsuzdur

cin >> sayı;int basla = 0;while (basla != sayı){

basla += 2;cout << basla << endl;

}

� Nasıl düzeltelim? � Döngüye başlamadan önce sayının çift sayı mı tek sayı mı

olduğunu kontrol edebiliriz.if (sayı % 2 == 0){ while (basla != sayı)

{ basla += 2;cout << basla << endl;

}}

Page 22: C++ Ders5 - Donguler

Diğer Problemler

� Easy to iterate one more or one less times

� Test each loop with the inputs that cause:� zero iterations of the loop body

� one iteration of the loop body

� maximum number of iterations

� one less than the maximum number of iterations

� Use the debugger and watch the variables.

Page 23: C++ Ders5 - Donguler

Matematiksel Döngüler� Şimdi matematiksel bazı uygulamalar yapacağız

� Faktoriyel hesaplaması

� Asal sayı bulunması

Page 24: C++ Ders5 - Donguler

Factoriyel

� n! = 1x2x…xn is “n factoriyel”;matematikte, istatistikte kullanılır

long factorial(long n)// pre: 0 <= n// post: returns n! (1 x 2 x … x n)

� Toplam hesabına benziyor, ama bu sefer döngüde çarpımı hesaplayacağız. En sonundaki çarpımıdöndüreceğiz. � Döngü n kere çalıştırılacak, sırasıyla 1, 2, …, n çarpılır� Diyelim ki product diye bir sonuç tutalım, product n! diye

bitecek döngünün sonunda. En sonunda da bu sonuç olarak döndürülür.

Page 25: C++ Ders5 - Donguler

Factorial

long Factorial(int num)// precondition: num >= 0// postcondition returns num! (1 x 2 x … x num){

long product = 1;int count = 0;while (count < num) {

count += 1;product *= count;

}return product;

}

� Issues� Why did we use long? What happens if we use int instead?� What happens if we initialize count to 1?

� Let’s see fact.cpp

Page 26: C++ Ders5 - Donguler

Asal Sayılar� 1 asal değildir, 2 is prime, 3 is prime, 5 is prime, 17 is prime, … 137,

193?� We do not need to check even numbers other than 2 (2 is a special case)� To check 193, divide it by 3, 5, 7, 9, 11, 13

� Note that 14x14 = 196, so 13 largest potential factor?� We will use modulus operator to check divisibility

� We’ll check odd numbers as potential divisors� Watch out for 2, it is a special case� How far should we go to check potential divisors?

� up to and including sqrt(number) + 1

� If there was a bigger factor, a smaller factor would exist. And this smaller one must have been checked before. So we do not need to go beyond this limit.

� +1 is there to make sure that there will be no problems with precision

� See primes.cpp for code

Page 27: C++ Ders5 - Donguler

Primeness Check – Details

� Special even number check is added before the loop to eliminate even numbers to be checked in the loop� In order to make the code more efficient

int limit = int(sqrt(n) + 1);

� To assign a double value to an int, a typecast is used, to tell the compiler that the loss of precision is intentional� Make typecasts explicit to tell the compiler you know what you are doing

� Compiler warnings are avoided

� We will see typecast in more detail later

Page 28: C++ Ders5 - Donguler

for loop compared with while

<initialization>

while (<test>)

{

<statement1>;

...

<statementN>;

<update>

}

for (<initialization>;

<test>;

<update> )

{

<statement1>;...<statementN>;

}

Page 29: C++ Ders5 - Donguler

Example

� Rewrite the while loop of main of primes.cpp using for

k = low;while (k <= high){

if (IsPrime(k)){

cout << k << endl;numPrimes += 1;

}k += 1;

}

for (k = low; k <= high; k += 1){

if (IsPrime(k)){

cout << k << endl;numPrimes += 1;

}}

Page 30: C++ Ders5 - Donguler

Shorthand for increment/decrement

� Lots of code requires incrementing a variable by one� Three methods, using = and +, using +=, and using ++

� effectively they are same

num = num + 1;num += 1;num++; // post increment

� It is also possible to write ++num;� pre-increment

� These differ on when the increment is performed, but this difference doesn’t matter when used as an abbreviation for the statement n += 1; in a single statement

� Similarly there are post-decrement (and pre-decrement)num = num - 1; num -= 1; num--;

Page 31: C++ Ders5 - Donguler

The do-while loop� Similar to while loop, but the test is after the execution of the loop body� The while loop may never execute, do-while loop executes at least once

<initialization>

do

{

<statement1>;...<statementN>;

<update>

} while (<condition>);

� Example: Prompt for a number between 0 and 100, loop until such a number is entered (user should enter at least one number)

do{

cout << "enter number in range [0..100] ";cin >> num;

} while (num < 0 || num > 100 );

Don’t forget

Page 32: C++ Ders5 - Donguler

Priming� Priming: reading an initial value before the loop

� do not get confused with prime numbers; this is something else

� Problem: enter numbers, add them up, stop when -1 entered

int toplam = 0;int num;cin >> num; // prime the loopwhile (num != -1){ toplam += num;

cin >> num;} cout << "total = " << toplam << end;

� Code duplication exists here: input (and perhaps prompt) code isrepeated before the loop and in the loop

Page 33: C++ Ders5 - Donguler

Pseudo infinite solution using break

� To avoid repeating code, include it in the body of the loop only, use a test to break out of the loop� break statement exits (inner-most) loop

� I don’t prefer this kind of loops (I’d prefer code duplication)� Because the loop condition is not clear, hence prevents readability

� Try not to use break in this course� Save it for later when you develop really complicated loops

int toplam = 0;int num;while (true) // seemingly infinite loop{ cin >> num;

if (num == -1){ break; // get out of loop}toplam += num;

} cout << "total = " << toplam << end;

Page 34: C++ Ders5 - Donguler

Fence Post Problem

� The problem that occurs when one or more operations of the loop body are executed one less then the others.

� Example: Display integers between 1 and 10 separated by comma

1,2,3,4,5,6,7,8,9,10� no comma after 10; no comma before 1.

for (n=1; n <= 10; n++)

{ cout << n << ",";

} Problem: comma after 10

for (n=1; n < 10; n++)

{ cout << n << ",";

}

cout << n; No problem, but code duplicates

� Think of other solutions! (see page 175 of Tapestry)

Page 35: C++ Ders5 - Donguler

Downward-counting loop

� Calculate n to the power of m: nm=nxnx…xn

� Example: 25=2x2x2x2x2=32

int power = 1;

int n, m;

cin >> n >> m;

for (int i = m; i <= 1; i--)

{

power = power * n;

}

Page 36: C++ Ders5 - Donguler

Nested loops

� Sometimes one loop occurs in another� Generating 2-dimensional tabular data

� multiplication table

� Sorting vectors (which will be studied much later)

� Display some geometric figures using character * (or any other character)� display rectangles, triangles

� Although other loops can be nested as well, most of the time, for loops are used in nested manner

Page 37: C++ Ders5 - Donguler

Nested loops - Example� Write a function to display a rectangle of stars (height and width are

parameters)� e.g. if height is 4 and width is 7, the output should look like

****************************

for (i=1; i<= height; i++){

for (j=1; j<=width; j++) // inner loop prints 1 line of stars{

cout << "*";}cout << endl; // end of line is put to the end of each line

}

� See drawfigures.cpp for the complete function and its use in main

Page 38: C++ Ders5 - Donguler

Nested loops - Example� Write a function to display a perpendicular isosceles triangle of stars

(perpendicular side length is parameter)� e.g. if side length is 6 , the output should look like

*********************

for (i=1; i <= side; i++){

for (j=1; j<=i; j++) // inner loop prints 1 line of stars{

cout << "*";}cout << endl; // end of line is put to the end of each line

}

� See drawfigures.cpp for the complete function and its use in main

Page 39: C++ Ders5 - Donguler

Same loop: downward-counting

for (i=1; i <= side; i++)

{

for (j=1; j<=i; j++)

{

cout << "*";

}

cout << endl;

}

for (i=1; i <= side; i++)

{

for (j=i; j>=1; j--)

{

cout << "*";

}

cout << endl;

}

Page 40: C++ Ders5 - Donguler

Drawfigures – Other Considerations� What about having a function to display a line of stars (number

of stars is a parameter)� useful for both rectangle and triangle

void PrintLine (int numstars)// pre: numstars > 0// post: displays numstars stars in one line{

int i;for (i=1; i<= numstars; i++){ cout << "*";}cout << endl; // end of line is put to the end of the line

}

� in rectangle function, inner loop is replaced by a function callfor (i=1; i<=height ; i++){

PrintLine(width);}

� use of PrintLine in triangle function is similar

Page 41: C++ Ders5 - Donguler

Example – Multiplication Table� On ith line print, i*1, i*2, i*3, ... , i*i

� Total number of lines is an input. Display lines starting with 1.� See multiply.cpp

#include <iostream>#include <iomanip> // for setwusing namespace std;

int main(){

int i,k,numlines;const int WIDTH = 4;

cin >> numlines;

for (i=1; i <= numlines; i++){

for (k=1; k <= i; k++){

cout << setw(WIDTH) << i*k;}cout << endl;

}return 0;

}

Page 42: C++ Ders5 - Donguler

Constants� Sometimes very useful

� provides self documentation� re-use the same value across the program� avoid accidental value changes

� like variables, but their value is assigned at declaration and can never change afterwards� declared by using const before the type name (any type is OK)const double PI = 3.14159;

const string thisclass = "CS201"

const int WIDTH = 4;

� later you can use their valuecout << (PI * 4 * 4);

� but cannot change their valuePI = 3.14; causes a syntax error

Page 43: C++ Ders5 - Donguler

Formatting Output� We use stream manipulator setw to specify the total number of

spaces that the next output will use� setw(field length)

� written in cout and affects only the next output value

not the whole cout line

� output is displayed using field length spaces in right justified manner (any empty space is on the left)

� defined in header file <iomanip>, so you have to have #include <iomanip>

� Examplecout << setw(9) << "cs201";

� output shown is four blanks and cs201