19 Aralık 2014 Cuma

C Programlama Dersi - VIII

C Programlama Dersi - VIII


Kısa Devre Değerlendirme

Kısa devre değerlendirme, ne yazık ki pek iyi bir çeviri olmadı ve bu yüzden hiçbir anlam ifade etmeyebilir. İngilizce'de, Short Circuit Evaluation olarak geçen bu konu, mantıksal ifadelerle ilgilidir.
Hatırlarsanız, daha önce ki derslerimizde iki farklı AND ve OR operatörü görmüştük. Bu yapılardan biri AND için && işaretini kullanıyorken, diğeri sadece tek & simgesini kullanıyordu. Keza, OR ifadesi bir yerde, || şeklinde gösteriliyorken, diğer yerde, tek bir | simgesiyle ifade edilmekteydi. Bu işaretler, aynı sonucu üretiyor gibi görünseler de, farklı şekilde çalışırlar.
Çift şekilde yazılan operatörler, ( yani && ve || ) kısa devre operatörleridir. İngilizce, Short Circuit Operator olarak isimlendirilirler. Tek sembolle yazılan operatörlerden farkı, işlemleri kısaltmalarıdır.
Bir koşul içersinde AND ( && ) operatörü kullandığınızda, koşulun sol tarafı yanlışsa, sağ tarafı kontrol edilmez. Çünkü artık sağ tarafın doğru veya yanlış olmasının önemi yoktur; sonuç her şekilde yanlış olacaktır.
Benzer bir mantık OR ( || ) operatörü içinde geçerlidir. Eğer sol taraf doğruysa, sağ tarafın kontrol edilmesine gerek yoktur. Çünkü OR operatöründe taraflardan birinin doğru olması durumunda, diğerinin önemi kalmaz ve sonuç doğru döner.
Aşağıdaki örnekleri inceleyelim:
&& Operatörü& Operatörü
#include<stdio.h>
int main( void )
{
 int i, j;
 i = 0;
 j = 5;
 if( i == 1 && j++ ) {
  printf( "if içersine girdi\n" );
 }
 else {
  printf( "if içersine girmedi\n" );
  printf( "i: %d, j: %d\n", i, j );
 }
 return 0;
}
#include<stdio.h>
int main( void )
{
 int i, j;
 i = 0;
 j = 5;
 if( i == 1 & j++ ) {
  printf( "if içersine girdi\n" );
 }
 else {
  printf( "if içersine girmedi\n" );
  printf( "i: %d, j: %d\n", i, j );
 }
 return 0;
}
if içersine girmedi
i: 0, j: 5
if içersine girmedi
i: 0, j: 6
Gördüğünüz gibi, program çıktıları birbirinden farklıdır. Bunun sebebi, ilk örnekte, i == 1 koşulu yanlış olduğu için, && operatörünün ifadenin sağ tarafına bakmamasıdır. İkinci örnekteyse, & operatörü, koşulun her iki tarafına da bakar. Bu yüzden, j değişkenine ait değer değişir. Benzer bir uygulamayı, OR için || ve | kullanarak yapabilirsiniz.
ÖNEMLİ NOT: Özetle işlemlerinizi hızlandırmak istiyorsanız; AND kullanacağınız zaman, && operatörüyle çalışın ve yanlış olması muhtemel olan koşulu sol tarafa koyun. Eğer OR operatörü kullanacaksanız, doğru olma ihtimali fazla olan koşulu, ifadenin soluna koyun ve operatör olarak || ile çalışın. Bu şekillde yazılan bir program, kısa devre operatörleri sayesinde, gereksiz kontrolden kaçınarak işlemlerinizi hızlandıracaktır.
Elbette & veya | operatörlerinin kullanılması gereken durumlarda olabilir. Her n'olursa olsun, koşulun iki tarafınında çalışmasını istiyorsanız, o zaman & ve | operatörlerini kullanmanız gerekmektedir.

Önişlemci Komutları

Bir program yazdığınızı düşünün... Bu programda, PI değerini birçok yerde kullanmanız gerekiyor. Siz de PI değeri olması gereken her yere, 3.14 yazıyorsunuz. Oldukça sıkıcı bir iş. İleride PI'yi, 3.141592653 olarak değiştirmek isterseniz daha da sıkıcı hâle dönüşebilir. Veya canınız istedi, printf(  ) fonksiyonu yerine ekrana_yazdir(  ) kullanmaya niyetlendiniz... İşte bu gibi durumlarda, Önişlemci Komutlarını ( Preprocessor ) kullanırız. Önişlemci komutlarının amacı, bir şeyi başka bir şekilde ifade etmektir.
Konuya devam etmeden önce ufak bir uyarı da bulunmakta yarar var. Önişlemci komutlarını, değişkenler veya fonksiyonlarla karıştırmamak gerekiyor. Değişkenlerin ve fonksiyonların daha dinamik ve esnek bir yapıları varken, önişlemci komutları statiktir. Programınıza direkt bir kod yazdığınızı düşünün. Bu kod herhangi bir şey (sembol, program parçası, sayı, karakter vs...) olabilir. Örneğin, her yerde PI'nin karşılığı olarak 3.14 girmek yerine, PI diye bir sembol tanımlarız ve bunun görüldüğü her yere 3.14'ü koyulmasını isteriz. Önişlemci komutları bu gibi işlerde, biçilmiş kaftandır.

#define Önişlemci Komutu

#define komutu, adından da anlaşılabileceği gibi tanımlama işlemleri için kullanılır. Tanımlama komutunun kullanım mantığı çok basittir. Bütün yapmamız gereken, neyin yerine neyi yazacağımıza karar vermektir. Bunun için #define yazıp bir boşluk bıraktıkan sonra, önce kullanacağımız bir isim verilir, ardından da yerine geçeceği değer.
Altta ki program, PI sembolü olan her yere 3.14 koyacak ve işlemleri buna göre yapacaktır:
/* Çember alanını hesaplar */

#include<stdio.h>
#define PI 3.14
int main( void )
{
 int yaricap;
 float alan;
 printf( "Çemberin yarı çapını giriniz> " );
 scanf( "%d", &yaricap );
 alan = PI * yaricap * yaricap;
 printf( "Çember alanı: %.2f\n", alan );
 return 0;
}
Gördüğünüz gibi, PI bir değişken olarak tanımlanmamıştır. Ancak #define komutu sayesinde, PI'nin aslında 3.14 olduğu derleyici (compiler) tarafından kabul edilmiştir. Sadece #define komutunu kullanarak başka şeylerde yapmak mümkündür. Örneğin, daha önce dediğimizi yapalım ve printf yerine, ekrana_yazdir; scanf yerine de, deger_al isimlerini kullanalım:
/* Yarıçapa göre daire alanı hesaplar */

#include<stdio.h>
#define PI   3.14
#define ekrana_yazdir  printf
#define deger_al  scanf
int main( void )
{
 int yaricap;
 float alan;
 ekrana_yazdir( "Çemberin yarı çapını giriniz> " );
 deger_al( "%d", &yaricap );
 alan = PI * yaricap * yaricap;
 ekrana_yazdir( "Çember alanı: %.2f\n", alan );
 return 0;
}
#define komutunun başka marifetleri de vardır. İlerki konularımızda göreceğimiz fonksiyon yapısına benzer şekilde kullanımı mümkündür. Elbette ki, fonksiyonlar çok daha gelişmiştir ve sağladıkları esnekliği, #define tutamaz. Bu yüzden #define ile yapılacakların sınırını çok zorlamamak en iyisi. Ancak yine de bilginiz olması açısından aşağıda ki örneğe göz atabilirsiniz:
/* Istenen sayida, "Merhaba" yazar */

#include<stdio.h>
#define merhaba_yazdir( x ) int i; for ( i = 0; i < (x); i++ ) printf( "Merhaba\n" );
int main( void )
{ 
 int yazdirma_adedi;
 printf( "Kaç defa yazdırılsın> " );
 scanf( "%d", &yazdirma_adedi );
 merhaba_yazdir( yazdirma_adedi );
 return 0;
} 

#undef Önişlemci Komutu

Bazı durumlarda, #define komutuyla tanımladığımız şeyleri, iptal etmek isteriz. Tanımlamayı iptal etmek için, #undef komutu kullanılır. Örneğin #undef PI yazdığınız da, o noktadan itibaren PI tanımsız olacaktır. #define ile oluşturduğunuz sembolleri belirli noktalardan sonra geçerliliğini iptal etmek veya yeniden tanımlamak için #undef komutunu kullanabilirsiniz.

#ifdef ve #ifndef Önişlemci Komutları

Önişlemci komutlarında bir sembol veya simgenin daha önce tanıtılıp tanıtılmadığını kontrol etmek isteyebiliriz. Tanıtılmışsa, şöyle yapılsın; yok tanıtılmadıysa, böyle olsun gibi farklı durumlarda ne olacağını belirten yapılar gerekebilir. Bu açığı kapatmak için #ifdef (if defined - şayet tanımlandıysa) veya #ifndef (if not defined - şayet tanımlanmadıysa) operatörleri kullanılır.
#include<stdio.h>
#define PI 3.14
int main( void )
{
 // Tanımlı PI değeri, tanımsız hâle getiriliyor.
 #undef PI

 int yaricap;
 float alan;
 printf( "Çemberin yarı çapını giriniz> " );
 scanf( "%d", &yaricap );

 // PI değerinin tanımlı olup olmadığı kontrol ediliyor.
 #ifdef PI
  //PI tanımlıysa, daire alanı hesaplanıyor.
  alan = PI * yaricap * yaricap;
  printf( "Çember alanı: %.2f\n", alan );
 #else
  //PI değeri tanımsızsa, HATA mesajı veriliyor.
  printf("HATA: Alan değeri tanımlı değildir.\n");
 #endif
 
 return 0;
}
Yukardaki örneğe bakacak olursak, önce PI değeri tanımlanıyor ve sonrasında tanım kaldırılıyor. Biz de sürprizlerle karşılaşmak istemediğimizden, PI değerinin tanım durumunu kontrol ediyoruz. Tek başına çalışan biri için gereksiz bir ayrıntı gibi gözükse de, ekip çalışmalarında, bazı şeylerin kontrol edilmesi ve istenmeyen durumlarda, ne yapılacağı belirlenmelidir. Yukarda ki programı şöyle de yazabilirdik:
#include<stdio.h>
int main( void )
{
 int yaricap;
 float alan;
 printf( "Çemberin yarı çapını giriniz> " );
 scanf( "%d", &yaricap );

 // Şu noktaya kadar tanımlı bir PI değeri bulunmuyor.
 // #ifndef opertörü bu durumu kontrol ediyor.
 // Eğer tanımsızsa, PI'nin tanımlanması sağlanıyor.
 #ifndef PI  
  #define PI 3.14
 #endif

 alan = PI * yaricap * yaricap;
 printf( "Çember alanı: %.2f\n", alan );

 return 0;
}

#if, #else, #endif, #elif Önişlemci Komutları

Bazen bir değerin tanımlanıp, tanımlanmadığını bilmek yetmez. Bazı değerler, bayrak (flag) olarak kullanılır. Yani eğer doğruysa, böyle yapılması lâzım, aksi hâlde böyle olacak gibi... Bazı programlar, önişlemci komutlarından yararlanır. Değişken yerine, önişlemcileri kullanarak tanımlanan simgeler, bu programlarda flag görevi görür.
Konumuza dönersek, #if, #else, #endif yapısı daha önce işlemiş olduğumuz if-else yapısıyla hemen hemen aynıdır. if-elif yapısı da if-else if yapısına benzer. Her ikisinin de genel yazım kuralı aşağıda verilmiştir:
#if - #else Yapısı:#if - #elif Yapısı:
#if koşul
 komut(lar)
#else 
 komut(lar)
#endif
#if koşul 1
 komut(lar) 1
#elif koşul 2
 komut(lar) 2
.
.
.
#elif koşul n-1
 komut(lar) n-1
#else 
 komut(lar) n
#endif
Bir program tasarlayalım. Bu programda, pi sayısınının virgülden sonra kaç basamağının hesaba katılacağına karar veren bir mekanizma olsun. Soruyu, şu ana kadar gördüğümüz, if - else gibi yapılarla rahatça yapabiliriz. Önişlemci komutuyla ise, aşağıdakine benzer bir sistem oluşturulabilir:
/* Daire alanını hesaplar */

#include<stdio.h>
#define HASSASLIK_DERECESI 2
int main( void )
{
 int yaricap;
 float alan;
 printf( "Çemberin yarı çapını giriniz> " );
 scanf( "%d", &yaricap );

 // Hassaslık derecesi, pi sayısının virgülden kaç 
 // basamak sonrasının hesaba katılacağını belirtir.
 // Eğer hassaslık derecesi bunlara uymuyorsa, alan 
 // değeri -1 yapılır.
 
 #if ( HASSASLIK_DERECESI == 0 )
  alan = 3 * yaricap * yaricap;
 #elif ( HASSASLIK_DERECESI == 1 )
  alan = 3.1 * yaricap * yaricap;
 #elif ( HASSASLIK_DERECESI == 2 )
  alan = 3.14 * yaricap * yaricap;
 #else
  alan = -1;
 #endif

 printf( "Çember alanı: %.2f\n", alan );
 return 0;
}

#include Önişlemci Komutu

#include oldukça tanıdık bir operatördür. Her programımızda, #include önişlemci komutunu kullanırız. Şayet kullanmasak, printf(  ) veya scanf(  ) gibi fonksiyonları tekrar tekrar yazmamız gerekirdi. #include komutu, programımıza bir başlık dosyasının (header file) dâhil edileceğini belirtir. Bu başlık dosyası, standart giriş çıkış işlemlerini içeren bir kütüphane olabileceği gibi, kendimize ait fonksiyonların bulunduğu bir dosya da olabilir.
Eğer sistem kütüphanelerine ait bir başlık dosyasını programınıza dâhil edeceksek, küçüktür ( < ) ve büyüktür ( > ) işaretlerini kullanırız. Örneğin stdio.h sisteme ait bir kütüphane dosyasıdır ve Linux'ta /usr/include/stdio.h adresinde bulunur. Dolayısıyla stdio.h kütüphanesini programımıza eklerken, #include<stdio.h> şeklinde yazarız. Kendi oluşturduğumuz başlık dosyaları içinse, durum biraz daha farklıdır.
Çalışma ortamımızla aynı klasörde olan bir başlık dosyasını, programımıza eklemek için #include "benim.h" şeklinde yazarız. İlerki derslerimizde, kendi başlık dosyalarımızı oluşturmayı göreceğiz. Ancak şimdilik burada keselim...

Önemli Noktalar...

Konuyu noktalarken, söylemek istediğim bazı şeyler bulunuyor. Olabildiğince, önişlemci komutlarından - #include komutu hariç - uzak durun. Çünkü bu komutlar, esnek bir yapıya sahip değiller ve bu durum, bir noktadan sonra başınızı ağrıtacaktır. Önişlemci komutlarıyla yazılmış kodları takip etmek oldukça zordur ve debug edilemezler. Java gibi gelişmiş dillerde, #define komutu bulunmaz. Modern dillerde, bu yapıdan uzaklaşılmaya başlanmıştır.
Yukarda saydıklarıma rağmen, bazı durumlarda, önişlemci komutlarını kullanmak uygun olabilir. Kaldı ki bu komutların kullanıldığı birçok yer bulunuyor ve biz kullanmasak bile, bilmeye mecbur durumdayız. Sözün özü; bu konuyu es geçmek uygun değil. Ancak üzerine düşmek oldukça gereksiz.

18 Aralık 2014 Perşembe

C Programlama Dersi - VII

C Programlama Dersi - VII



Örnek Sorular

Soru 1.a: Aşağıdaki programın çıktısı nedir?Soru 1.b: Aşağıdaki programı doğru olarak yazınız.
#include<stdio.h>
int main( void )
{
 int i = 0;
 for( ; i < 12; i++ ) {
  if( ( i++ + 1 ) == 5 )  
   printf( "%d\n",i );
  else 
   if( i % 2 == 0 ) break;
   else if( i % 3 == 0)
    continue;
   else 
    printf("%d\n", i );
 }
 return 0;
}
#include<stdio.h>
int main( void )
{
 int sum;
 float average;
 int weight_1, weight_2;
 printf( "1.agirlik> " );
 scanf( "%d", &weight_1 );
 sum += weight_1;
 printf( "2.agirlik> " );
 scanf( "%d", weight_2 );
 sum += weight_2;
 average = sum / 2;
 printf( "Ortalama: %.2f\n", average );
 return 0; 
}


Soru 2: Bir üçgende, iki kenarın toplam uzunluğu, üçüncü kenardan az olamaz. Ayrıca iki kenarın birbirinden farkının mutlak değeri, üçüncü kenardan büyük olmamalıdır. Bu bilgileri kullanarak, verilen üç kenar uzunluğuna göre bir üçgen çizilip çizilmeyeceğini gösteren programı yazınız. Girilecek kenar uzunlukları tam sayı olacaktır.

Soru 3: Klavyeden girilecek bir sayının asal sayı olup olmadığını ekrana basan bir program yazınız.

Soru 4: Klavyeden girilecek 0 ile 999 arasında bir tam sayının, yazıyla ifade eden ( örneğin 49, 'kırkdokuz' gibi ) bir program oluşturunuz.

Soru 5: Dört basamaklı bir sayının rakamları ters yazılıp, 4 ile çarpılırsa, çıkan sonuç, kendisiyle aynıdır. Dört basamaklı bu sayıyı bulunuz.

Soru 6: Fibonacci serisinin ilk iki elemanı 0 ve 1'dir. Bundan sonra gelen sayılar, kendisinden önceki iki sayının toplamıyla bulunur. Yani seri elemanları 0 1 1 2 3 5 8 13 21 ... şeklinde gitmektedir. Verilecek adım sayısına göre, Fibonnaci serisinin elemanlarını gösterecek bir program yazınız.

Soru 7: Verilecek kenar uzunluğuna göre, yıldız (*) işareti kullanarak kare çizen, bir program yazınız.

Soru 8: Aşağıdaki eşkenar dörtgen çıktısını üretecek bir program yazınız:
    *
   ***
  *****
 *******
*********
 *******
  *****
   ***
    *

Soru 9: Hipotenus'u 500 birime kadar olan dik üçgenlerin, kenar uzunluklarını gösteren bir program yazınız. Kenar uzunlukları, sadece tam sayı olacaktır.

HTML Kodlama Dersi - VI

HTML Kodlama Dersi - VI


HTML5 ile Gelen Yenilikler

Merhaba arkadaşlar,
Bu dersimizle HTML5''e başlıyoruz. Öncelikle <!DOCTYPE> etiketinden söz etmek istiyorum. .<!DOCTYPE> bir web sayfasını tarayıcıya tanıtır ve sayfanın düzgün görüntülenmesini sağlar. Kullanımı şart olmasa da, tarayıcının kodları daha sağlıklı yorumlamasını sağlayıp, hata riskini azaltır. Bu etiketi sayfanın en başına yazarız ve kapatmayız. Her HTML sürümü için farklı bir <!DOCTYPE> tanımı vardır. Ben sadece HTML 1.0 ve HTML5'teki kullanımlarını göstereceğim. Amacım HTML5 ile gelen gelişimi göstermek... Diğer sürümlere dair bilgileri Internet'te bulabilirsiniz.
- HTML 1.0 için:
  <!DOCTYPE HTML
  PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  
- HTML5 için:
<!DOCTYPE HTML>
Gördüğünüz gibi DOCTYPE etiketimiz, HTML5'te gayet sade bir hâl almış. <!DOCTYPE> etiketiyle tarayıcıya "Ben HTML5 kullanıyorum. Sayfayı ona göre yorumla." demiş oluyoruz.
İlk dersimizde de söylediğimiz gibi HTML5, HTML'in son sürümüdür; yani en güncel hâlidir. HTML5 içinde biraz CSS ve Javascript barındırır ve diğer HTML sürümlerine göre daha esnektir. Bu sürüme özgü bazı yeni kodlar gelirken, eskiden kullandığımız bazı kodlar da artık kullanılmayacaktır. HTML5'te kullanılmayacak kodları sıralarsak:
<acronym> , <applet>,  <basefont>, <big>, <center>, <dir>, <font>,  
<frame> <frameset>, <noframes>,  <strike>, <tt>, <u>,  <xmp>
Bu kodların artık kullanılmamasının sebebi olarak, CSS ile de bu kodlarla yapılabileceklerin yapılması, HTML’de bunlara duyulan ihtiyacın azalmasını söyleyebiliriz. HTML5 ile gelen yeni etiketler ise  açıklamalarıyla beraber şöyle sıralayabiliriz:
<canvas>: Sayfada bir tuval alanı oluşturur. Tuvale çizim javascript  ile yapılabilir.
<audio>: Sayfaya ses oynatıcı bir modül ekler.
<video>: Video oynatıcı bir modül  ekler.
<progress>: İşlem süreci göstergesi ekler.
<caption>: Başlık olarak düşünülen metinleri düzenler.
<header>: Sitenin başlık  ve açıklama içeriğini alır.
<nav>: Menüleri ve bir takım zaruri işlevleri içine alır.
<footer>: Sitelerin en alt  kısmını içine alır.
<article>: Makale, deneme tarzı yazıları kapsar.
<aside>: Ana içerikte ayrı yazılan kısımdır.
<datalist>: Düzenlenebilir elementlere otomatik tamamlama özelliği  verilmesini sağlar.
<details>: Detay bilgisi  içerir.
<embed>: Dışarıdan eklenen componentler için kullanılır. (Örn : .swf uzantılı dosyalar)
<figcaption>: <figure> elementinin başlığını belirler.
<figure>: Çeşitli medya içeriği gruplarını belirler.
<hgroup>: Başlık grubunu belirtir. H1, H2 gibi başlık elementleri burada tanımlanabilir.
<mark>: Yazı içerisinde özellikle üstünde durulan kelimeleri  belirler.
<summary>: Yazının başlığını belirler.
<time>: Tarih, saat verilerini kapsar.
Bunların dışında <command>,<meter>,<output>,<rp>,<source>,<ruby>,<section>, <rt> ve <keygen> de HTML5 ile gelen yeni etiketler arasındadır. Şimdi ilk olarak <canvas> etiketiyle bir örnek yapalım.
<!DOCTYPE HTML>
 <html>
  <body>
   <canvas width="200" height="100"style="border:1px solid black;">
    <script type=”text/javascript”>
     ...
    </script>
   </canvas>
  </body>
 </html>
Tarayıcıdaki görüntüsü sayfanın sol üstünde siyah kenarlıklı içi boş bir tablodur. İçi javascriptle çizim yapılması için ayrılan alandır. Javascript’e şimdi girmiyorum. Ancak yazdığım kodları açıklayayım. Width ve height ile oluşturduğumuz alanın enini ve boyunu pixel cinsinden belirlemiş olduk. Style, kenarlık özelliklerini belirlemek için açıldı. ”border:1px “ ifadesi kenarlık kalınlığını belirler. Solid kenarlığın düz çizgi olmasını sağladı. Solid yerine dashed i kullansaydık kenarlık kesik çizgi halinde olacaktı. Son olarak black ise kenarlık rengi. Onu da red yellow şeklinde değiştirmek mümkün veya #000000 şeklinde renk kodunu yazabiliriz.
Şimdi de sırasıyla <audio> ve <video> etiketlerinden bahsedelim.
<!DOCTYPE HTML>
 <html>
  <body>
   <audio src="ses.mp3" controls="controls" autoplay="autoplay" loop="loop"> 
    Tarayıcınız desteklemediği için ses dosyası çalınamıyor.
   </audio>
  </body>
 </html>
Audio nun yanında kullandığımız dört ifadenin anlamlarını açıklayalım:

src="ses.mp3" ses dosyasının yerini belirler. Hatırlarsanız resim dosyalarında da aynı şeyi yapmıştık. Benim ses dosyam aynı klasörde yer aldığı için sadece adını yazdım.
controls="controls"  eğer bunu yazmasaydık play tuşu gibi kontrol tuşları görünmeyecekti.
autoplay="autoplay" bu ifade sayesinde sayfa yüklendiği gibi ses dosyası yürütülmeye başlanır. Eğer kullanmazsak ses dosyasının çalması için 'play' tuşuna basılması gerekir.
loop="loop" Kullandığımız takdirde ses doyası biter bitmez baştan başlayacaktır.
Bu arada şunu da belirtelim ki <audio> elementinin desteklediği 3 tür ses uzantısı (.mp3 .ogg ve .wav) vardır. Tarayıcı ses dosyasını desteklemiyorsa ekranda bizim yazmış olduğumuz uyarı gözükür. Destekler ise uyarı yazısı görünmez.
Artık bir video dosyası ekleyebiliriz:
<!DOCTYPE HTML>
 <html>
  <body>
   <video src="video.ogg" width="250" height="200" controls="controls" loop="loop">
    Tarayıcınız desteklemediği için video açılmamaktadır.
   </video>
  </body>
 </html>
Ses doyası eklerken kullandıklarımızın aynısını kullandık. Farklı olarak bu sefer etiketimiz <video> idi ve boyutunu belirten height="..." ve width="..." ifadelerine yer verdik. Bu boyutlar da pixel cinsindendir.
Bu dersimizde HTML5 hakkında bilgi sahibi olduk ve HTML5 etiketlerinin üçüyle örnekler yaptık. Diğer dersimizde görüşmek üzere...

HTML Kodlama Dersi - V

HTML Kodlama Dersi - V


HTML Form Elemanları

Bu yazıda HTML form elemanlarını öğreneceğiz. Nedir bunlar ne işe yarar önce bunlardan bahsedelim... Form elemanlarını, kullanıcı bilgi girişinde kullanır. Form elemanları kullanıcı adı, şifre girişi gibi alanlar oluşturmamızı sağlar. Aynı zamanda onay kutuları oluştururken de kullanırız. Mesela kullanıcıdan evli veya bekar olduğu, evi arabası olup olmadığı bilgilerini alırken form elemanlarıyla oluşturacağımız onay kutularından yararlanırız.
Form elemanları <form>..</form> etiketleri arasına yazılır. input en çok kullanacağımız form etiketidir. Kapatılmaz. input etiketi içerisinde kullanılan type ifadesiyle girdi türü belirlenir. Bir örnek yapacak olursak:
<html>
 <body>
  <form>
   Ad: <input type="text"  name="name"><br/>
   Soyad: <input  type="text" name="lastname">
  </form>
 </body>
</html>
Yukarıda yaptığımız örnek tarayıcıda aşağıdaki gibi gözükecektir:
Ad:  
Soyad:   
type="..." ve name="..." ifaderi dinamik web sayfası oluştururken daha iyi anlaşılacaktır. Henüz detaya girmeyelim. Ancak şunu bilmekte yarar var: text, name ve lastname yerine Türkçe karakter içermeyen Türkçe ifadeler de kullanabiliriz. (Yani name="kullaniciadi" şeklinde bir ifade de geçerli olurdu.) Şimdi örneğimizi biraz daha geliştirelim. Bir gönderme butonu oluşturalım ve ad soyad kutucuklarına sayfa açıldığında görüntülenecek yazılar ekleyelim.
<html>
 <body>
  <form>
    Ad: <input type="text" name="firstname" value="adınızı  giriniz"><br/>
    Soyad: <input type="text" name="lastname"  value="soyadınızı giriniz"><br/>
    <input type="submit" value="Gönder">
  </form>
 </body>
</html>
Sayfada göreceğimiz yapı aşağıdaki gibi olacaktır:
Ad:  
Soyad:  
Submit ifadesiyle buton oluşturduk. Value ise butonun ve kutucukların içindeki ifadeleri yazmamızda kullanıldı. Onay kutuları oluşturmamızda da işe yarayacağından bahsetmiştik. Bununla ilgili ilk örneğimizi de yapalım.
<html>
 <body>
  <form>
   <input type="radio" name="cinsiyet" value="bayan">Bayan<br/>
   <input type="radio" name="cinsiyet" value="erkek">Erkek<br/>
   <input type="submit" value="Kaydet">
  </form>
 </body>
</html>
Bayan
Erkek
Üstteki örnekte görülen "radio" ifadesi tek seçeneği seçmemizi sağlar. Birden fazla seçenek seçmemizi gerektiren durumlar da ise checkbox ifadesini kullanırız.
<html>
 <body>
  <h5>Hangi Tür Müzikleri Seversiniz</h5>
   <form>
    <input type="checkbox" name="music" >Pop<br/>
    <input type="checkbox" name="music" >Rock<br/>
    <input type="checkbox" name="music" >Arabesk<br/>
    <input type="checkbox" name="music" >Türk Sanat Müziği<br/>
    <input type="submit" value="Kaydet">
   </form>
  </body>
</html>
Yazılan kodun sonucunda, birden çok seçimi yapabiliyoruz:
Pop
Rock
Arabesk
Türk Sanat Müziği
Son olarak açılır liste oluşturmayı da görelim:
<html>
 <body>
  <h5>İlk  öğrendiğiniz programlama dilini seçiniz</h5>
   <form>
    <select name="proglamlama dilleri" >
     <option value="C">C<br/>
     <option value="C++">C++<br/>
     <option value="Pascal">Pascal<br/>
     <option value="Java">Java<br/>
    </select>
  </form>
 </body>
</html>
İlk öğrendiğiniz programlama dilini seçiniz
Form elemanları kullanıcıdan bilgi almak için kullanılır demiştik. Bu derste veri almanın, görsel kısımlarını gördük. Ancak alınan verinin işlenmesi için PHP, JSP veya ASP.NET gibi web programlama dillerini bilmek gerekir. Şayet verinin işlenmesi dışında, saklanması da gerekiyorsa, genellikle ilişkisel bir veritabanı (RDBMS) kullanılır. Bu konular farklı uzmanlıklar gerektiriyor. Konu fazlalılığı gözünüzü korkutmasın; aradaki noktaları zamanla birleştireceksiniz.

17 Aralık 2014 Çarşamba

C Programlama Dersi - VI

C Programlama Dersi - VI


Sayı Tabanları

Bilgisayar programlamayla, matematik arasında çok güçlü bir ilişki vardır. Geçmişe bakarsanız, bilgisayar alanında önemli adımların, hep matematik kökenli insanlar tarafından atıldığını görürsünüz. Bir bilgisayar programcısı için, matematikten uzak durmak düşünülemez.
Bugün ki dersimizde, biraz matematik içersine gireceğiz ve sayı sistemleriyle, Boole Cebiri (Boolean Algebra) konularını ele alacağız.
Genel kabul görmüş sayı sistemleri vardır ve içlerinde en yaygını, hepimizin gündelik hayatta kullandığı 10'luk sayı sistemidir. Yazması, okunması ve işlem yapması son derece kolay olduğundan bunu daha çocuk yaşta öğrenir ve bu şekilde sürdürürüz. Ancak bilgisayarlar bizim gibi işlem yapabilme yetisine sahip değildir. Onlar için iki ihtimal vardır. Bir şey ya 1'dir ya da 0. Bunu ikilik sayı sistemi olarak adlandırırız. Yani bizim yazdığımız bütün sayılar, bütün harfler ve aklınıza gelen-gelmeyen bütün işaretler, bilgisayar için 0 ve 1'in kombinasyonlarından ibarettir. İşte bu yüzden bizlerin, ikilik sayı sistemine hakim olması gerekir.
Sayı sistemlerini genel olarak aşağıdaki gibi ifade edebiliriz:
[number systems]
Burada, N sayı tabanına göstermektedir. k sayının hangi hanesinde olduğumuzu ifade ederken, dk ise, ilgili sayıdaki rakamı temsil eder. Şimdi basit bir örnek yapalım ve ikilik tabandaki 10011 sayısının, 10 tabanındaki eş değerini bulalım:
( d4d3d2d1d0 )2 = ( d0 . 20 ) + ( d1 . 21 ) + ( d2 . 22 ) + ( d3 . 23 ) + ( d4 . 24 )
( 10011 )2 = ( 1 . 20 ) + ( 1 . 21 ) + ( 0 . 22 ) + ( 0 . 23 ) + ( 1 . 24 ) = 19
ikilik sayı sistemi dışında, 16'lık (Hexadecimal) sayı sistemi de oldukça önemli bir başka tabandır. 16'lık sayı sisteminde, rakamları ifade etmek için 16 adet sembole gereksinim duyarız. Bu yüzden 0 ile 9 arasında olan 10 rakamı kullandıktan sonra, A, B, C, D, E ve F harflerini de rakam olarak değerlendiririz.
Decimal:0123456789101112131415
Hexadecimal:0123456789ABCDEF

Hexadecimal/16'lık sayı tabanıyla ilgili aşağıdaki örneklere göz atalım:
( 3FC )16 = ( 3 . 162 ) + ( F . 161 ) + ( C . 160 ) = 768 + 240 + 12 = 1020
( 1FA9 )16 = ( 1 . 163 ) + ( F . 162 ) + ( A . 161 ) + ( 9 . 160 ) = 4096 + 3840 + 160 + 9 = 8105
( 75 )16 = ( 7 . 161 ) + ( 7 . 160 ) = 112 + 5 = 117
16'lık sayı sisteminin diğer bir ismi Hexadecimal olduğundan, bazı yerlerde, bunu ifade etmek için 16 yerine 'H' harfi de kullanılabilir:
( BA3 )16 = ( BA3 )H ;   ( A1E )16 = ( A1E )H gibi...
Tabanlar arasında dönüştürme işlemi, üzerinde duracağımız bir başka konudur. Elinizde 16'lık sayı sisteminde bir sayı varsa ve bunu 2'lik sayı sistemiyle yazmak isterseniz önce 10'luk sayı sistemine çevirip daha sonra 2'lik sayı sistemine dönüştürebilirsiniz. Ancak 16'lık ve 2'lik sayı sistemlerini çok daha kolay birbirine dönüştürmeniz mümkündür. Aşağıdaki tabloda 16'lık sayı sistemindeki rakamlar ve bunun 2'lik sayı sistemindeki karşılığı verilmiştir:
Hexadecimal:0123456789ABCDEF
Binary ( İkilik ):0000000100100011010001010110011110001001101010111100110111101111

Bu durumu bir örnekle şöyle gösterebiliriz:
( A3F1 )H:A3F1
:1010001111110001

16'lık tabandaki her rakamın, 2'lik tabandaki karşılığını koyduğumuzda yukardaki eşitliği elde ediyoruz ve buna göre ( A3F1 ) = ( 1010 0011 1111 0001 )2 eşitliğini kurabiliyoruz. (2'lik tabandaki sayıya ait boşluklar, sayının daha rahat okunması için bırakılmıştır.) Bu tarz dönüşümler, 2 ve 2'nin katında olan sayı tabanlarında rahatlıkla yapılabilir.
Hatırlarsanız, değişken tiplerinde, işaretli ve işaretsiz değişken tanımlamalarından bahsetmiştik. Şimdi olayın biraz daha derinine inelim. Bir char, 1 byte alan kaplar ve 1 byte, 8 bit'ten oluşur. Aşağıdaki kutuların her birini bir bit ve kutuların oluşturduğu bütünü bir byte olarak düşünün:
 a7  a6  a5  a4  a3  a2  a1  a0 

Yukardaki kutuların toplamı olan bir byte, char değişkeninin kapladığı alanı temsil etmektedir. Pozitif sayıları ifade etmeyi zaten öğrenmiştik. Sayının karşılığını, 2'lik tabanda yazarak, gerekli sonuca ulaşırız. Ancak sayımız Negatif değerliyse, işler biraz farklılaşır. Burada devreye işaret biti (sign bit) devreye girer. Yukardaki şekilde, diğer kutulardan farklı renkte olan a7işaret bitidir. Özetle, a7 0 ise, sayı pozitiftir. Eğer a7 1 ise, sayı negatiftir.
İkilik tabandaki işaretli bir sayının, 10'luk tabandaki karşılığını şu şekilde bulabiliriz:
( a7a6a5a4a3a2a1a0 )2 = ( a7 . -27 ) + ( a6 . 26 ) + ... + ( a1 . 21 ) + ( a0 . 20 )
İkilik tabanda yazılmış ( 10000011 )2 sayısı, işaretsiz olarak düşünülürse, 131'e eşittir. Ancak işaretli bir sayı olduğu düşünülürse, karşılığı, -125 olacaktır. Konunun pekişmesi açısından aşağıdaki örneklere göz atabilirsiniz:
* ( 1011 1011 )2 = -69 (Sayı işaretliyse)
  ( 1011 1011 )2 = 187 (Sayı işaretsizse)
* ( 1100 1101 )2 = -51 (Sayı işaretliyse)
  ( 1100 1101 )2 = 205 (Sayı işaretsizse)
* ( 0110 1101 )2 = 109 (Sayı işaretliyse)
  ( 0110 1101 )2 = 109 (Sayı işaretsizse)
Negatif bir sayının 2'lik tabandaki karşılığını bulmak için, önce (i) sayıyı pozitif olarak ikilik tabanda yazarız. Daha sonra, (ii) ikilik tabanda yazılmış sayının 1 yazan rakamları 0, 0 yazan rakamları 1'e çevrilir. Son olarak (iii) çıkan sayıya, 1 eklenir. Bu size istediğiniz sayının ikilik tabanındaki eşini verecektir. Şimdi bir uygulama yapalım ve -7 sayını ikilik tabana çevirmeye çalışalım:
i ) -7 ==> ( 7 )10 = ( 0000 0111 )2
ii ) ( 0000 0111 ) ==> ( 1111 1000 )
iii ) ( 1111 1000 ) + 1 = ( 1111 1001 ) ==> ( -7 )10 = ( 1111 1001 )2

Bit Bazında ( Bitwise ) Operatörler

Bit bazında operatörlerin, İngilizce'deki karşılığı Bitwise Operators ( yani Bit bit Operatörler ) olarak geçmektedir. Bit bazında operatörler, ikilik sayı tabanında yapabileceğimiz işlemleri temsil eder. Kullanılan operatörleri aşağıda inceleyeceğiz.

AND ( & ) Operatörü

AND operatörü, kendisine verilen iki değişkenin bütün bitleri 1'e eşit olduğu takdirde, geriye 1 döndürür. Aksi halde -yani en ufak bir fark varsa- 0 değeri dönmektedir.
pqp&q
000
010
100
111
x00
x1x

Şimdi, AND ( & ) operatörünü 25 ve 14 sayılarını karşılaştırmak için kullanalım:
  25 ==> ( 0001 1001 )2
  14 ==> ( 0000 1110 )2
&
----------------------------
   8 ==> ( 0000 1000)2

OR ( | ) Operatörü

İki değişkenden herhangi biri 1 içeriyorsa, geriye 1 döner. Eğer her ikisi de 0 içeriyorsa, geriye 0 dönmektedir.
pqp|q
000
011
101
111
x0x
x11

Daha önce kullandığımız 25 ve 14 sayıları üzerinde OR ( | ) işlemi kullanalım:
  25 ==> ( 0001 1001 )2
  14 ==> ( 0000 1110 )2
|
----------------------------
  31 ==> ( 0001 1111)2
ÖNEMLİ NOT: Bit bazında kullanılan, AND( & ) ve OR ( | ) operatörleri, koşullu ifadelerde kullanılan, AND( && ) ve OR ( || ) ifadelerinden farklıdır. Şayet, & veya | bir koşullu ifade gibi kullanmaya kalkarsanız, işlem yine yapılacaktır. Ancak bunu yapmanız tavsiye edilmez. İlerki konularımızda neden uygun olmadığı, short-circuit ile ilgili bilgi verilirken açıklanacaktır.

NOT ( ~ ) Operatörü

NOT ( ~ ) Operatörü, kendisine verilen sayıya ait bit'leri tam tersine çevirir. Yani 0 gördüğü yeri 1; 1 gördüğü yeri 0 yapar.
p~p
01
10

  25 ==> ( 0001 1001 )2
~
----------------------------
 230 ==> ( 1110 0110 )2

XOR ( ^ ) Operatörü

XOR ( Exclusive OR ) Operatörü, sadece ve sadece karşılaştırma yapılan bitlerden biri, 1 değerine sahipse, geriye 1 döndürür. Eğer karşılaştırma yapılan bit'lerden her ikisi de 0 veya 1'se, o zaman sonuç 0 olarak çıkar.
pqp^q
000
011
101
110
x0x
x1~x

  25 ==> ( 0001 1001 )2
  14 ==> ( 0000 1110 )2
^
----------------------------
  23 ==> ( 0001 0111 )2

Kaydırma ( Shift ) Operatörleri

Kaydırma operatörleri, özellikle Assembly ile uğraşanlara tanıdık gelecektir. Bunları kullanarak son derece hızlı çarpma ve bölme yapılabilir. C'deyse benzer amaçlarla kullanmanız elbette mümkündür. İki çeşit kaydırma operatörü vardır:
i)  Sola Kaydırma - Shift Left ( << )
ii) Sağa Kaydırma - Shift Right ( >> )
Her iki durumda da genel kullanım şekli aşağıdaki gibidir:
    [ Tam Sayı ][ Operatör ][ Kaydırma Adım Sayısı ]
Aşağıdaki örnek, sola kaydırma operatörü kullanılarak yapılan bir işlemi göstermektedir. x değişkeni, 10 tabanında 22 sayısını tutmaktadır. 2 adım sola kaydırılması sonucu, sayı 88 olmuş ve y'ye atanmıştır.
x = ( 0001 0110 )2 ==> 22
y = x << 2 
y = ( 0101 1000 )2 ==> 88

Operatör Öncelikleri

Hatırlarsanız, aritmetik işlemlerde önceliklerin olduğunu ve örneğin çarpmanın, toplamadan daha önce yapılacağını anlatmıştık. Benzer bir durum, operatörler içinde geçerlidir. Altta bulunan tabloda, hangi operatörün daha önce işleme alındığını bulabilirsiniz:
OPERATÖR ÖNCELİK SIRASI
 DÜŞÜK  |  ^  &  <<  >>  +  -  * / %  !  ~  -  ++  --  (  )  YÜKSEK 

Aşağıda bulunan tablo, ilişkisel ve mantıksal operatörlerde ki öncelik sırasını göstermektedir:
İLİŞKİSEL ve MANTIKSAL OPERATÖR ÖNCELİK SIRASI
 DÜŞÜK  ||  &&  == !=  > >= < <=  !  YÜKSEK 

Yukardaki tablolarda, aynı hücrede olan operatörlerin işlem öncelikleri aynıdır. Önce hangisi yazılmışsa, ilk olarak o dikkate alınır. Ama bunun dışında tanınan bir işlem önceliği bulunmamaktadır.
Aşağıdaki örnek, operatör önceliklerini pekiştirmek açısından incelenebilir:
7 & 13 ^ 11 % 4 * 2 << 14 / 4
==> 7 & 13 ^ 6 << 3
==> 5 ^ 48 = 53
Şimdi de benzer bir örneği, C programı yazarak yapalım:
#include<stdio.h>
int main( void ) 
{
 printf( "İşlem Sonucu: %d\n", 117 & 11 << 2 * 3 );
 return 0;
} 
Yukardaki program, 64 sonucunu vermektedir. Programı çalıştırdığınızda, ikilik düzeyde işlemler yapılacak ve 64 cevabına ulaşılacaktır. 

HTML Kodlama Dersi - IV

HTML Kodlama Dersi - IV


HTML Tablo Oluşturma

Tablo oluştururken kullanacağımız temel etiketler <table> <tr> ve <td> dir. <table> tabloyu belirtir. <tr> satırları, <td> ise sütunları belirtir. Önce basit bir örnek yapalım.
<html>
  <body>
   <table>
    <tr>
     <td>Satır1, Sütun1</td>
     <td>Satır1, Sütun2</td>
    </tr>
    <tr>
     <td>Satır2, Sütun1</td>
     <td>Satır2, Sütun2</td>
    </tr>
   </table>
  </body>
</html>
Bu şekilde 2x2'lik bir tablo oluşturabiliriz. Ancak tablonun kenarları görünmeyebilir. Kenarlık kalınlığını ayarlamak için border ifadesini kullanırız. Kullanımı <table border="1"> şeklindedir. <th> etiketinden de bahsedelim. <th> tablo başlığıdır diyebiliriz. İfadeyi kalın ve bölmenin ortasında gösterir. Bir örnek daha yapalım.
<html>
  <body>
   <table border="2">
    <tr>
     <th>Mavi</th>
     <th>Beyaz</th>
    <tr>
     <td>Deniz</td>
     <td>Bulut</td>
    </tr>
    <tr>
     <td>Gökyüzü</td>
     <td>Duman</td>
    </tr>
   </table>
  </body>
</html>
Yazdığımız kodun çıktısı aşağıdaki gibi olacaktır:
MaviBeyaz
DenizBulut
GökyüzüDuman

Satır veya sütunları birleştirebiliriz. rowspan="..." satırlar, colspan="..." sütunlar için kullanılır. Araya da birleştirilecek satır veya sütun sayısını yazarız. Ayrıca bgcolor="..." ifadesini kullanarak tabloların arkaplan rengini de değiştirebiliriz. Örnekle görelim:
<html>
  <body>
   <table border="2" bgcolor="aqua">
    <tr>
     <td colspan="3">0</td>
     <td>1</td>
    </tr>
    <tr>
     <td>4</td>
     <td>5</td>
     <td rowspan="2">6</td>
     <td>7</td>
    </tr>
    <tr>
     <td>8</td>
     <td>9</td>
     <td>10</td>
    </tr>
   </table>
  </body>
</html>
Tablolarla ilgili son olarak cellspacing ve cellpadding ifadelerinden bahsedelim. cellspacing hücreler arası, cellpadding hücre içi genişliği belirtir. Kullanımlarından gösterecek olursak:
<html>
 <body>
   <table border="2" cellspacing="100" cellpadding="100">
    <tr>
     <td>A</td>
     <td>B</td>
    </tr>
    <tr>
     <td>C</td>
     <td>D</td>
    </tr>
   </table>
 </body>
</html>

C Programlama Dersi - V

C Programlama Dersi - V


Döngü Kavramı

Programlama konusunda -hangi dil olursa olsun- en kritik yapılardan biri döngülerdir. Döngüler, bir işi, belirlediğiniz sayıda yapan kod blokları olarak düşünülebilir. Ekrana 10 kere "Merhaba Dünya" yazan bir programda, "Merhaba Dünya" yazdıran kodu aslında tek bir defa yazarsınız, döngü burada devreye girip, sizin için bu kodu istediğiniz sayıda tekrarlar.
Döngüleri bu kadar kritik yapan unsur; iyi yazılıp, optimize edilmediği takdirde, bilgisayarınızın işlem gücünü gereksiz yere tüketmesi ve harcanan zamanı arttırmasıdır. Benzer şekilde, iyi yazılmış bir döngü, programınızı hızlı çalıştıracaktır.
Bütün döngüler temelde iki aşamayla özetlenebilir. Aşamalardan biri, döngünün devam edip etmeyeceğine karar verilen mantıksal sorgu kısmıdır. Örneğin, ekrana 10 kere "Merhaba Dünya" yazdıracaksanız, kaçıncı seferde olduğunu, koşul kısmında kontrol edersiniz. Diğer aşama, döngünün ne yapacağını yazdığınız kısımdır. Yani ekrana "Merhaba Dünya" yazılması döngünün yapacağı iştir.
Döngünün devam edip etmeyeceğine karar verilen aşamada, hatalı bir mantık sınaması koyarsanız, ya programınız hiç çalışmaz ya da sonsuza kadar çalışabilir.
C programlama diline ait bazı döngüler; while, do while, for yapılarıdır. Bunlar dışında, goto döngü elemanı olmasına rağmen, kullanılması pek tavsiye edilmemektedir.

while Döngüsü

while döngüsü, en temel döngü tipimizdir. Bir kontrol ifadesiyle döngünün devam edilip edilmeyeceği kontrol edilirken, scope içinde ( yani ayraç işaretleri arasında ) kalan bütün alan işleme sokulur. İşleme sokulan kod kısmı döngü yapılacak adet kadar tekrar eder.
while döngüsünün genel yapısını ve akış şemasını aşağıda görebilirsiniz:
while Yapısıwhile Akış Diyagramı
while( koşul ) {
 komut(lar)
}
[while loop structure]
Yukarda 10 kere ekrana "Merhaba Dünya" yazan programdan bahsettik. Gelin bir anlaşma yapalım ve döngülerle alakalı bütün ilk örneklerimiz bu programın nasıl yazılacağını göstersin.
while döngüsü kullanarak, ekrana 10 kere "Merhaba Dünya" yazan program aşağıdaki gibidir:
/*
Ekrana 10 kere "Merhaba Dünya"
yazan program
*/
#include<stdio.h>
int main( void )
{
 //i değişkenine bir başlangıç değeri atıyoruz.
 //i'ye ilk deger atanmazsa, döngümüz yanlış çalışır.
 int i = 0;
 //i'nin degeri kontrol işleminden
 //sonra 1 artar.
 while( i++ < 10 ) {
  //2d bir tam sayının yazdırılacağı
  //ancak bu sayı tek rakamdan oluşsa da
  //2 rakamlık yer ayırılmasını belirtir.
  printf("%2d: Merhaba Dünya\n",i);
 }
 return 0;
}
Yukardaki program aslında son derece basit. i değişkenine ilk değer olarak 0 atıyoruz. Daha sonra, while döngüsüne başlıyoruz. İfadenin doğruluğu ( yani i'nin 10'dan küçük olup olmadığı) kontrol ediliyor. Eğer doğruysa, döngü içindeki kodların çalışması başlatılıyor. Elbette kodların başlamasından bir önceki adımda, i değişkeni arttırılıyor. ( Önceki derste anlatmış olduğumuz post-increment işlemini hatırlayın. ) Bu yapı toplamda 10 kere tekrar ediyor ve en sonunda i'nin degeri 10'a eşit olunca, döngü sonlandırılıyor.
Sum Operation
Yandaki işlem basit bir toplama ifadesidir. Yanda gördüğümüz ifade de, n değerini kullanıcıdan alacağımızı düşünerek bir program yazalım. Bu program, alacağı n değerine göre, kendisine kadar olan sayıların karelerinin toplamını gösterecektir. Bu programı yazarsak:
#include<stdio.h>
int main( void )
{
 int i = 0, toplam_deger = 0;
 int n;
 printf("Lütfen n değerini giriniz> ");
 scanf("%d",&n);
 while( i <= n ) {
  toplam_deger += i*i;
  i++;
 }
 printf("Sonuç: %d\n",toplam_deger);
 return 0;
}

do while Döngüsü

Göreceğimiz ikinci döngü çeşidi, do while döngüsüdür. Yaptığı iş, while ile hemen hemen aynıdır; verilen işi, döngü koşulu bozulana kadar sürdürür. Ancak while'a göre önemli bir farkı vardır.
while döngülerinde, döngü içersindeki işlem yapılmadan önce, sunulan koşul kontrol edilir. Şayet koşul sağlanmıyorsa, o while döngüsünün hiç çalışmama ihtimali de bulunmaktadır. do while döngülerindeyse, durum böyle değildir. İlk çalışmada koşul kontrolü yapılmaz. Dolayısıyla, her ne şartta olursa olsun, döngünüz -en azından bir kere- çalışacaktır.
Bazı durumlarda, döngü bloğu içersindeki kodların en azından bir kere çalışması gerektiğinden, do while yapısı kullanılır. do while ile ilgili genel yapıyı ve akış şemasını aşağıda bulabilirsiniz:
do while Yapısıdo while Akış Diyagramı
do {
 komut(lar)
} while( koşul );
[do while loop structure]
Önce Merhaba Dünya örneğimizi yapalım:
#include<stdio.h>
int main( void )
{
 int i = 0;
 do {
  //Önce i'nin değeri arttırılıyor
  //sonra ekrana Merhaba Dünya yazdırılıyor.
  printf("%2d: Merhaba Dünya\n",++i);
 } while( i < 10 );
 return 0;
}
Gördüğünüz gibi, bir önceki örneğimize oldukça benzer bir yapıda, yazıldı. Tek fark i'nin değeri 0'da olsa, 1000'de olsa, en azından bir kez Merhaba Dünya'nın yazılacak olmasıdır. Ancak while'de kontrol önce yapıldığı için, hiçbir şey ekrana yazılmaz.
Şimdi do while'in kullanılmasının daha mantıklı olacağı bir program yapalım. Kullanıcıdan iki sayı alınsın. Bu iki sayı toplandıktan sonra, sonucu ekrana yazdırılsın. Yazdırma sonunda "Devam etmek istiyor musunuz?" sorusu sorulsun ve klavyeden 'E' veya 'e' karakterlerinden birisi girilirse, program devam etsin. Yok farklı birşey girilirse, program sonlandırılsın. Örnek programımızı aşağıda bulabilirsiniz:
#include<stdio.h>
int main( void )
{
 int sayi_1, sayi_2;
 char devam_mi;
 do {
  printf("Birinci sayıyı giriniz> ");
  scanf("%d",&sayi_1);
  printf("İkinci sayıyı giriniz> ");
  scanf("%d",&sayi_2);
  printf("%d + %d = %d\n", sayi_1, sayi_2, sayi_1 + sayi_2);
  printf("Devam etmek ister misiniz? ");
  //C'de tek karakter okuma işlemi biraz sıkıntılı 
  //olduğundan, burada da bir do while kullandık.
  do {
   scanf("%c",&devam_mi);
  }while( devam_mi == '\n' );
  printf("\n");
 } while( devam_mi == 'E' || devam_mi == 'e' );

 return 0;
}
Program, kullanıcıdan iki sayı alıp, toplamını ekrana bastıktan sonra, yeniden işlem yapıp yapmak istemediğimizi sormaktadır. Bu programı while ile de yazabilirdik. Ancak while ile yazabilmek için,devam_mi değişkenine önceden 'E' değerini atamamız gerekmekteydi. do while döngüsündeyse, bu zorunluluğa gerek kalmamıştır.
Not: Yukardaki programda, farketmiş olduğunuz gibi karakter okumayı biraz farklı yaptık. Normalde, scanf(  ) fonksiyonunu kullanmak yeterliyken, burada, işin içine bir de, do while girdi. Açıklayacak olursak, C'de karakter okumaları, biraz sıkıntılıdır. Eğer giriş tampon belleğinde (Buffer) veri bulunuyorsa, bu direkt karaktere atanır. Bundan kurtulmak için birçok yöntem olduğu gibi, uygulanabilecek bir yöntem de, yukarda yazılmış olan döngü şeklinde değer almaktır. Çünkü siz daha bir şey girmeden, ilk değer '\n' geleceğinden, döngünün ikinci çalışmasında, doğru değer atanacaktır. İlerki konularda, daha detaylı ele alacağımız bir problem olarak şimdilik önemsemeyelim. Sadece karakter okuyacağınız zaman problem çıkarsa, yukardaki gibi bir yöntem uygulanabileceğini bilmeniz -şimdilik- yeterli.

for Döngüsü

while ve do while dışında, üçüncü bir döngü tipi olarak, for yapısı bulunmaktadır. Diğer iki döngüden farklı olarak, for yapısı, yenilemeli-tekrarlamalı (İngilizce iterative) yapılarda kullanıma daha uygundur. Bunu performans anlamında söylemiyorum. Demek istediğim yazım tekniği olarak, for döngüsünün daha kullanışlı olmasıdır. Örneğin birbirini, sürekli tekrar eden işlemlerin yapıldığı Nümerik Analiz gibi alanlar, for döngüsü için iyi bir örnek olabilir. Ancak bu dediklerim sizi yanıltmasın; for döngüsü sadece soyut alanlarda çalışsın diye yaratılmış bir şey değildir.
Programlarda, diğer iki döngüden çok daha fazla for kullanırsınız. Çünkü for sadece matematiksel hesaplama işlemlerinde değil, diziler ( array ) gibi konularda sürekli kullanılan bir yapıdır. Yazımı diğerlerine nazaran daha sade olduğundan, iteratif işlemlerde kullanılması elbette ki tesadüf olarak düşünülemez.
Aşağıda for döngüsünün genel yazımını ve akış diyagramını göreceksiniz:
for Yapısıfor Akış Diyagramı
for( ilk_deger_atama; koşul; arttırma/azaltma ){
 komut(lar)
}
[do while loop structure]
İlk atacağımız adım; elbette ki ekrana 10 kere "Merhaba Dünya" yazdırmak olacak. ( Umarım bu Merhaba Dünya'larla sizi fazla sıkıp, programlama işinden vazgeçirmemişimdir. Programlama mantığını kaptıktan sonra, dünyayı daha farklı görmeye başlayacak ve Merhaba Dünyalar'ın sebebini daha iyi anlayacaksınız. Ve inanın bütün bu eziyete değer... ) Buyrun programımız:
#include<stdio.h>
int main( void )
{
 int i;
 for( i = 0 ; i < 10; i++ ) {
  printf("%2d: Merhaba Dünya\n",(i+1));
 }
 return 0;
}
Gördüğünüz gibi çok daha sade ve açık gözükür bir kod oldu. for altında tek satır komut olduğundan, küme parantezleri koymamız opsiyoneldi ama ne yaptığınızı karıştırmamak için, her zaman koymanızı öneririm.
for döngüleriyle ilgili bazı özel durumlarda vardır. for döngüsü içersine yazdığınız ilk değer atama, kontrol ve arttırma işlemlerini tanımlama esnasında yapmanız gerekmez. Aşağıda verilen kod, yukardakiyle tamamen aynı işi yapar. Farkı, i'nin daha önce tanımlanmış olması ve arttırma/azaltma işinin döngü içinde yapılmasıdır.
#include<stdio.h>
int main( void )
{
 int i;
 i = 0;
 for( ; i < 10; ) {
  printf("%2d: Merhaba Dünya\n",(i+1));
  i = i + 1;
 }
 return 0;
}

break Komutu

Bazı durumlarda, döngüyü aniden sonlandırmak isteriz. Bunun için 'break' komutunu kullanırız. Döngüyü aniden sonlandırmak veya döngüyü kırmak işlemini, zaten daha önce switch case'lerde kullanmıştık. Bahsetmediğimiz şey, bunun her döngü içersinde kullanılabileceğiydi.
Aşağıdaki programı inceleyelim:
/*
0 ile 99 arasında tesadüfi sayılar üreten 
bir programın, kaçıncı seferde 61 sayısını
bulacağını yazan program aşağıdadır.
*/
#include<stdio.h>
int main( void )
{
 int i,tesadufi_sayi;
 int deneme_sayisi = 0;
 //while içinde 1 olduğundan sonsuza kadar döngü çalışır.
 while( 1 ){
  //tesadufi_sayi değişkenine, 0 ile 99 arasında 
  //her seferinde farklı bir sayı atanır.
  //rand( ) fonksiyonu tesadüfi sayı atamaya yarar.
  //mod 100 işlemiyse, atanacak sayının 0 ile 99
  //arasında olmasını garantiler.
  tesadufi_sayi = rand() % 100;
  //Döngünün kaç defa çalıştığını deneme_sayisi
  //değişkeniyle buluruz.
  deneme_sayisi++;
  //Eğer tesadufi sayı 61'e eşit olursa, 
  //döngü kırılıp, sonlandırılır.
  if( tesadufi_sayi == 61 ) break;
 }
 printf("Toplam deneme sayısı: %d\n",deneme_sayisi);
 return 0;
} 
Program için koyulmuş açıklamalar ( comment ) zaten neyin n'olduğunu açıklıyor. Kısaca bir şeyler eklemek gerekirse, bitişinin nerede olacağını bilmediğimiz bir döngüyü ancak, break komutuyla sonlandırabiliriz. Şartlar sağlandığında, break komutu devreye girer ve döngü sonlandırılır. Bunun gibi bir çok örnek yaratmak mümkündür.

continue Komutu

break komutunun, döngüyü kırmak için olduğundan bahsetmiştik. Bunun dışında işlem yapmadan döngüyü devam ettirmek gibi durumlara da ihtiyacımız vardır. Bunun içinde continue ( Türkçe: devam ) komutunu kullanırız.
/*
Sadece tek sayıları yazdıran bir
program
*/
#include<stdio.h>
int main( void )
{
 int i;
 for( i = 0; i < 10; i++ ) {
  //i değişkeninin 2'ye göre modu
  //0 sonucunu veriyorsa, bu onun 
  //bir çift sayı olduğunu gösterir.
  //Bu durumda ekrana yazdırılmaması 
  //için döngü bir sonraki adıma geçer.
  if( i%2 == 0 ) continue;
  printf("%2d\n",i);
 }
 return 0;
} 
0 ile 10 arasındaki tek sayıları gösteren program örneğini yukarda görebilirsiniz. Elbette ki bu işi daha farklı ve daha iyi yapan bir program yazabilirdik. Ama şimdilik continue komutunun nasıl kullanıldığını inceleyelim.
Program bir for döngüsü çalıştırmaktadır. Her defasında i değişkenin 2'ye göre modu alınır. Eğer sonuç 0'sa, bu sayının çift olduğunu gösterir. Dolayısıyla, bunun ekrana yazdırılmaması gerekir. Bu yüzden, döngü içersindeki işlemleri sürdürmek yerine, altta kalan kodları atlarız. Burada continue komutu kullanılır ve kullanıldığı noktadan itibaren olan işlemler yapılmaz. Döngü başa döner, aynı işlemleri yapar. Bu sefer i tek sayı olacağından continue komutu çalışmaz ve sayıyı ekrana bastırırız.

goto Yapısı

C programlama dilinde bulunan bir başka yapı, goto deyimidir. Koyacağınız etiketler sayesinde, programın bir noktasından bir başka noktasına atlamanızı sağlar. goto, bir döngü değildir ancak döngü olarak kullanılabilir.
goto, çalışabilmek için etiketlere ihtiyaç duyar. Etiketler, vereceğiniz herhangi bir isme sahip olabilir. Etiket oluşturmak için bütün yapmanız gereken; etiket adını belirleyip, sonuna iki nokta üst üste eklemek ( : ) ve programın herhangi bir yerine bunu yazmaktır. goto deyimi kullanarak bu etiketleri çağırırsanız, etiketin altında bulunan kodlardan devam edilir. goto ve etiketlere dair genel yapıyı, akış diyagramıyla birlikte aşağıda bulabilirsiniz:
goto Yapısıgoto Akış Diyagramı
label_name: 
 .
 .
 .
 
if( kosul ) {
 goto label_name
}
 .
 .
 .

[goto structure]
NOT: goto deyimi tek başına da kullanılabilir. Fakat mantıksal bir sınama olmadan, goto yapısını kullanmanız, sonsuz döngüye neden olacaktır.
Şimdi goto ifadesiyle basit bir döngü örneği oluşturalım. Önceki seferlerde olduğu gibi ekrana 10 defa "Merhaba Dünya" yazdıralım:
#include<stdio.h>
int main( void )
{
 int i = 0;
 // baslangic_noktasi adinda bir etiket koyuyoruz.
 // i degiskeni 10 degerine ulasmadigi surece, 
 // program buraya donecektir. 
 baslangic_noktasi:
 printf( "Merhaba Dünya\n" );
 // i degerini arttiriyoruz.
 i++;
 // i degeri kontrol ediliyor. Sayet 10'dan kucukse, 
 // en basa donuyor.
 if( i<10 ) goto baslangic_noktasi;
 
 return 0;
}
İstediğiniz sayıda etiket koyup, goto kullanarak, programın herhangi bir noktasına ulaşabilirsiniz. Programınız, etiket altında kalan kısımdan itibaren çalışır. goto yapısıyla gelen esneklik, ilk bakışta oldukça güzel görünüyor. Ancak goto için birçok kaynak, "ya hiç kullanmayın ya da olabildiğince az kullanın" demektedir.
Okunup, anlaşılması zor ve üzerinde çalışılması güç bir koddan, herkesin uzak durması gerekir. İngilizce'de, karman çorman koda, "spagetti kod" adı verilmiştir. goto deyimi, kodunuzun spagetti koda dönüşmesine neden olur. Çünkü program akışının takibini zorlaştırıp, kodun okunabilirliğini azaltır. Diliyorsanız, goto deyimini kullanabilirsiniz. Ama zorunlu kalmadıkça kaçınmak en iyisi...

Örnek Sorular

Soru 1: Klavyeden girilen sayının faktöriyelini hesaplayıp, ekrana yazdıran bir program yazınız.

Soru 2: Klavyeden girilen sayının tersini (örneğin 1234 ==> 4321 gibi) ekrana bastıran programı yazınız.

Soru 3: Kullanıcıdan sınırsız sayıda, pozitif sayı alacak ve aldığı sayıların ortalamasını ekrana bastıracak bir program yazınız. Kullanıcı negatif bir sayı girdiği takdire, bu sayı hesaba alınmayacak ve program sonlandırılıp, o zamana kadar girilmiş pozitif sayıların ortalamasını yazdıracaktır.

Soru 4: Aşağıdaki çıktıyı üreten programı yazınız:
*
* *
* * *
* * * *
* * * * *

Soru 5: 4 numaralı sorunun cevabında bulunan for döngülerini, while döngülerine çeviriniz.