duyuruElektroArge.com'a Hoşgeldiniz. Üye Olmak İçin Tıklayın. duyuru





houseForum ana sayfa   iletişimİletişim   bilgiSSS  
kırmızı yeşil mavi
ekleKayıt  anahtarGiriş
evForum ana sayfa goE-Kütüphane goE-Ders goC#
 

  • Reklam

Ders 28 - Prosedürler

C Dili Dersleri - Okan Bilke

Ders 28 - Prosedürler

Mesajgönderen okanbilke » 15 Oca 2015 00:24

Prosedür ve fonksiyonlar bütün bilgisayar dillerinde önemli yer tutmaktadırlar. Sebebi basittir, çok kullanılan kodları özel bir bloğa yazarak, her defasında aynı kodları uygulamanızda yazmazsınız. Bu sayede hem zamandan kazanır, hem de hata yapma şansınızı minimuma indirirsiniz.
Fonksiyonlarla prosedürler arasındaki fark geriye değer döndürme olayıyla açıklansa da aslında olay tam olarak öyle değildir. Öncelikle fonksiyon geriye değer döndürür doğru ama isterseniz prosedürlede uygulamaya istediğiniz kadar değer alabilirsiniz. İlerleyen konularda bu hususlara bolca örnekler verilecektir.

PROSEDÜR TANIMLAMAK
Prosedürler void ile deklare edilen kod bloklarından oluşur. Fonksiyonlardan farkları herhangi bir değişkene eşitlenmemelerinden kaynaklanmaktadır. Uygulamamıza ait kontrollerin kullandıkları yordamlar, aslında birer prosedürden ibarettir. Yalnız dikkat edin, bu özel yordamlar kendilerine has parametre içerirler. Öncelikle formunuzun üzerine bir adet "Button" kontrolü sürükleyerek üzerine Mouse ile çift tıklayın. Aşağıdaki şekilde bir blok otomatik olarak C# tarafından oluşturulacaktır.
private void button1_Click(object sender, EventArgs e)
{
// Kodlar
}

Dikkat edin, eklenen prosedürün ismi button1_Click olarak C# tarafından belirlenmiştir. Bu aşamada Source kod sayfasında aşağıdaki şekilde bir satır otomatik olarak eklenecektir. Örnek için Button1 kontrolüne tıklanıldığı zaman button1_Click prosedürünün işletilmesinin sebebini öğrenmek için Solution Explorer penceresinde yer alan Form1.Designer.cs dosyasının üzerine Mouse ile çift tıklayın.
Resim

Açılan dosyada yer alan InitializeComponent prosedürü içerisinde oluşan button1 kontrolüne ait kod satırlarına dikkat edin.
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(94, 106);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click); // Bu Satır Sayesinde
//
// Diğerleri
//
}

Şimdi formunuza ait Button kontrolüne ait yordamı aşağıdaki şekilde değiştirin.
private void DugmeyeBasildi(object sender, EventArgs e)
{
this.Text = "Okan Bilke";
}

Dikkat edin Button1_Click olan prosedür ismi "DugmeyeBasildi" olarak değiştirilmiştir. Şimdi aynı düğmeye tıklandığı zaman buradaki kodun işletilebilmesi için Form1.Designer.cs dosyasında aşağıdaki değişikliği de yapmak zorundasınız.
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(94, 106);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.DugmeyeBasildi); // Burası Değişecek
//
// Diğerleri
//
}

Artık uygulamayı çalıştırabilirsiniz. Button kontrolüne her tıkladığınızda başlık aşağıdaki şekilde olacaktır.
Resim

KONTROL YORDAMLARINDA KULLANILAN PARAMETRELER
Kontrollere ait yordamlarda özel parametrelerin olduğu görülmektedir. Şimdi bu parametreleri sizlere izah etmeye çalışacağım. Öncelikle bu parametreleri bir görelim.
private void button1_Click(object sender, EventArgs e)

Dikkat edin sender ve e isminde iki farklı değişken otomatik olarak oluşturulmuştur. Yeri gelmişken belirtelim, prosedürlerimiz içerisinde e diye bir değişken tanımlaması yapmayın dememizin sebebi zaten burada var olduğu içindir. Parametrelerin isimlerini değiştirebilirsiniz. Herhangi bir sorun çıkmayacaktır. Fakat dikkat edin yazacağınız kodlarda artık bu parametre isimlerini kullanmalısınız.
private void button1_Click(object Okan, EventArgs Bilke)

Öncelikle object sender parametresini izah edelim (değiştirildikten sonraki isimde aynı şeyi yapacaktır. Sender parametresini anlamanız için formunuzun üzerine yeni bir Button kontrolü daha yerleştirin. İkinci Button kontrolünün Properties penceresinde yer alan Şimşek düğmesine tıklayarak aşağıdaki şekilde Click yordamına button1_Click prosedürünü gösterin.
Resim

Yukarıdaki adımdan sonra o forma ait Designer.cs dosyasına bakarsanız, aşağıdaki şekilde bir satırın eklendiğini göreceksiniz. İki düğmede Button1_Click yordamını göstermektedir.
private void InitializeComponent()
{
//
// button1
//
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Click += new System.EventHandler(this.button1_Click); // Dikkat button1_Click
//
}

Dikkat edin bilgisayar Button2 kontrolüne tıklandığı zaman button1_Click yordamını işletecektir. Şimdi gelelim asıl olaya, iki Button da aynı prosedürü işletecekse C# olayı gerçekleştiren kontrolü nasıl ayırt edecektir. İşte sender bu işe yaramaktadır.
Aşağıda, Button2 kontrolüne ait Click yordamının, daha önce Button1 tarafından oluşturulan button1_Click yordamına nasıl yönlendirileceği gösterilmektedir.
private void button1_Click(object sender, EventArgs e)
{
if (sender == button1)
{
label1.Text = "İlk Düğme";
}
else if (sender == button2)
{
label1.Text = "İkinci Düğme";
}
}

Verilen kodları ekledikten sonra iki düğmeyede basın. Ekran görüntüleri aşağıdaki şekilde oluşacaktır.
Resim

Şayet parametrelerin isimlerini değiştirdiyseniz kodunuzu aşağıdaki şekilde kullanabilirsiniz. Hiçbir mahsuru yoktur. Hatta daha anlaşılır bir kod bloğu elde etmiş olursunuz.
private void button1_Click(object Okan, EventArgs Bilke)
{
if (Okan == button1)
{
label1.Text = "İlk Düğme";
}
else if (Okan == button2)
{
label1.Text = "İkinci Düğme";
}
}

İkinci olarak kullanılan e parametresi ise ilerleyen derslerimizde izah edilecektir.

KULLANICI TANIMLI PROSEDÜR OLUŞTURMAK
Bir programcı için uygulama içerisinde prosedür oluşturmak son derece önemlidir. Dedik ya aynı kodların tekrar tekrar yazdırılmasından bu sayede kurtulabilirsiniz. Şimdi sizlere bu prosedürlerin nasıl oluşturulabileceğini göstereceğim.
private void ElektroArge()
{
// Kodlar
}

Yapılan işlem şudur. Programcı ElektroArge isminde bir prosedür oluşturmuştur. Bu ismi kullanarak istediği bir anda bu bloktaki kodları işletebilir.
private void ElektroArge()
{
this.Text = "www.elektroarge.com";
}
private void button1_Click(object Okan, EventArgs Bilke)
{
ElektroArge(); // Prosedürü Çalıştır
}

Resim

Uygulamayı çalıştırdıktan sonra uygun olan button1 kontrolüne tıklarsanız ekran görüntünüz yukarıdaki şekilde oluşacaktır.
Prosedürler tanımlanırken aşağıdaki hususlara dikkat etmelisiniz. Yoksa sonuç başarısız olacaktır.
  • Prosedürler void bildirisiyle tanımlanır.
  • Diğer formların veya classların kullanması istenirse Public 'le (internal) Sadece bu formun kullanılması içinse Private ile tanımlanır. Eğer isim kullanılmazsa Private olarak algılanır.
  • Prosedürünüze düzgün bir isim vermelisiniz.
  • Aynı isimle birden fazla prosedür tanımlayabilirsiniz. Fakat bilgisayarın bunu anlayabilmesi için en az bir parametre sayısı veya tipi değişik olmalıdır.

PARAMETRE İÇEREN PROSEDÜR TANIMLAMAK
Aşağıdaki örnek uygulamada oluşturduğunuz prosedür içerisinde nasıl parametre tanımlayabileceğiniz gösterilmektedir. Bu sayede program içerisinden göndereceğiniz değerler ile prosedürü işletebilir, uygun sonuçları elde edebilirsiniz. Önceki prosedüre ait kod bloğunu aşağıdaki şekilde yeniden düzenleyin.
private void ElektroArge(string Deger)
{
this.Text = Deger;
}
private void button1_Click(object Okan, EventArgs Bilke)
{
String Deger;
Deger = textBox1.Text;
ElektroArge(Deger); // Prosedürü Çalıştır
}

Şimdiki uygulamada Button kontrolüne tıklamadan önce TextBox içeriğine prosedüre göndereceğiniz değeri girmelisiniz. Ekran görüntüsüne dikkat edin, formun başlığında gönderdiğiniz parametre değeri yer almaktadır.
Resim

BİRDEN FAZLA PARAMETRELİ PROSEDÜR OLUŞTURMAK
Oluşturduğunuz prosedür içerisinde parametre sayısının birden fazla olması hiçbir sorun çıkarmayacaktır. Kolayca tanımlayabilirsiniz.
private void ElektroArge(string ad, string soyad)
{
label1.Text = "Adı=" + ad;
label2.Text = "Soyadı=" + soyad;
}
private void button1_Click(object Okan, EventArgs Bilke)
{
ElektroArge(textBox1.Text, textBox2.Text); // Prosedürü Çalıştır
}

Uygulamayı çalıştırdıktan sonra sayfa üzerindeki uygun bölümlere değerlerinizi girin. Göster düğmesinden sonra ekran görüntünüz aşağıdaki şekilde oluşacaktır.
Resim

DİZİ PARAMETRELİ PROSEDÜR TANIMLAMAK
Prosedüre gönderilecek olan parametreler dizi içerikli olabilir. Bu sayede bir çok değer hesaplamalarını da yaptırabilirsiniz. Gerçekten parametrelerin dizi ile bildirilmeleri sizlere çok özel imkanlar sağlayacaktır. Hemen gösterelim.
Resim

Şimdi amacımız birinci listede yer alan isimlerin başına akademik ünvanları ekleyerek ikinci listede yerlerini almalarını sağlamak olacaktır.
namespace ElektroArge_Ders28
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void AkademisyenGoster(Object[] OgrUyeleri)
{
foreach (Object Eleman in OgrUyeleri)
{
string Deger;
Deger = Convert.ToString(Eleman);
listBox2.Items.Add("Prof. Dr. " + Deger);
}
}
private void button1_Click(object sender, EventArgs e)
{
int Adet;
Adet = listBox1.Items.Count; // Eleman Sayısını Al
Object[] DiziEleman = new Object[Adet];
for (int i = 0; i <= Adet - 1; i++)
{
DiziEleman[i] = listBox1.Items[i];
}
AkademisyenGoster(DiziEleman); // Prosedürü İşlet
}
}
}

Resim

PARAMETRE OLARAK MATRIX DİZİ KULLANMAK
Oluşturacağınız prosedürlerin içerisinde Matrix dizileride kullanabilirsiniz. Bir çok projenizde bu hususa yer vermek zorunda kalacaksınız. Sebebi basittir, muhtemelen bir çok koleksiyon değerini bloğa sokup sonuç değerini isteyeceksiniz. Buda ancak göstereceğimiz yöntemle gerçekleşebilecektir. Şimdi bu hususu örneklendireceğim. Dikkatlice takip ediniz.
namespace ElektroArge_Ders28
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}

private void DegerGoster(int[,] DiziDeger)
{
System.Collections.IEnumerator DiziOku = DiziDeger.GetEnumerator();
int Toplam = 0;
while (DiziOku.MoveNext())
{
int Deger;
Deger = Convert.ToInt32(DiziOku.Current);
Toplam += Deger;
}
MessageBox.Show("Toplam=" + Toplam);
}

private void button1_Click(object sender, EventArgs e)
{
int[,] Dizi = new int[,] { { 10, 20, 30 }, { 100, 101, 102 } };
DegerGoster(Dizi); // Prosedürü İşlet
}
}
}

Resim

Dikkat edin gönderilen değerlerin toplamı mesaj olarak kullanıcıya gösterilmektedir.

PROSEDÜRLERİN AŞIRI YÜKLENMESİ
Class içerisinde bazı durumlarda aynı isimde birden fazla prosedür tanımlayabilirsiniz. Doğrusunu isterseniz böyle bir zorunluluk olmamasına rağmen opsiyonel parametreli durumların olması gerektiği zamanlar methodların çok anlaşılır olmasını sağlamaktadır. Öncelikle aşağıdaki yapıya dikkatinizi çekmek istiyorum.
Resim

MessageBox nesnesine ait Show isimli aşırı yüklenmiş 21 adet methodu yazılmıştır. Aynı isimle dilediğinizi kullanabilirsiniz. Hangisini işleteceğine parametrelerin sayısına ve tipine bakarak karar verecektir. Buradan şu anlam çıkmaktadır. En az bir parametrenin tip veya sayıları farklı olmalıdır. Şimdi aynı mantığı birde oluşturmayı deneyelim. Aşağıdaki kod bloğunu uygulamanızda oluşturun.
private void Topla(int x, int y)
{
int Sonuc = x + y;
MessageBox.Show("İki Sayının Toplamı=" + Sonuc.ToString());
}

private void Topla(int[] Dizi)
{
int Sonuc = 0;
foreach (int Eleman in Dizi)
{
Sonuc += Eleman;
}
MessageBox.Show("Koleksiyonun Toplamı=" + Sonuc.ToString());
}
private void button1_Click(object sender, EventArgs e)
{
// www.elektroarge.com
Topla(2, 3);
}

Resim

En alttaki balon mesaja dikkat edecek olursanız iki adet Topla isimli prosedürün yazılmış olduğunu göreceksiniz. Hangisinin çağrılacağına göndereceğiniz parametreler karar verecektir. Şayet int tip tek parametre ile işletirseniz ilk prosedür, int tip dizi parametreli olarak işletirseniz ikinci prosedür çağrılacaktır.

REF
Prosedüre gönderdiğiniz değişkenin değeri, prosedür içerisinde ona karşılık gelen değişkene aktarılacaktır. İşte bu değişkenin değerinin prosedür içerisinde değişmesi durumunda uygulamadan ona gönderilen değişkeni etkilemesi isteniyorsa o değişkenin ref bildirisiyle deklare edilmesi gerekmektedir. Bu mantığı geliştirerek prosedür içerisinden istediğimiz kadar değişkeni uygulamanıza alabilirsiniz. Öncelikle basit bir örnek verelim.
namespace ElektroArge_Ders28
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}

private void MesajVer(ref String Sehir)
{
MessageBox.Show(Sehir);
Sehir = "ANKARA";
}

private void button1_Click(object sender, EventArgs e)
{
String MesajDeger;
MesajDeger = "AYDIN";
MesajVer(ref MesajDeger);
this.Text = MesajDeger; // ANKARA YAZAR
}
}
}

Bu örnekte prosedüre parametre değeri olarak AYDIN gönderilmiştir. Bu değer mesaj olarak kullanıcının karşısına aynen çıkacaktır. Prosedür içerisinde bu değer ANKARA olarak değiştirildiği ve ref ile bildirildiği için son değer uygulamaya dönecek, formun başlığında ANKARA yazacaktı.
Örnekte prosedür içerisinde değişken ref ile bildirilmeseydi, Mesaj olarak AYDIN bildirilecekti. Aynı şekilde buradaki değer değişimi uygulamayı etkilemeyeceği için formun başlığında da AYDIN yazacaktı.
Belirtmekte yarar görüyorum, prosedür içerisinde ref ile belirlenen parametreye uygulamadan yine ref bildirisini kullanarak değer yollayabilirsiniz. Aksi taktirde uygulamanız çalışmayacaktır. Yine ikinci bir uyarı, prosedürler içerisindeki dizi değişken parametreler otomatik olarak ref bildirili davranış gösterirler.

OUT
Oluşturduğunuz prosedür içerisinde, uygulamadan gönderdiğiniz bir değerin kesinlikle bir değişkene aktarılmasını istemiyorsanız (Atamalarda eşitlik karakterinin sağında kalması durumu) o değişkeni prosedür içerisinde out bildirisiyle deklare etmeli, uygulamadan gönderilecek parametrenin başına yine out bildirisi girilmelidir. Aşağıdaki kullanım bu açıdan hata ile sonuçlanacaktır.
private void MesajVer(out String AdiSoyadi)
{
String GelenVeri;
GelenVeri = AdiSoyadi; // Hata
AdiSoyadi = "Göksu Tuna";
}

private void button1_Click(object sender, EventArgs e)
{
String Deger;
Deger = "Okan Bilke";
MesajVer(out Deger);
}

Belirtmekte fayda görüyorum, prosedür içerisinde bu değişkene değer aktarılabilir, bu işlem hata vermeyecektir.
private void MesajVer(out String AdiSoyadi)
{
AdiSoyadi = "Göksu Tuna"; // Hata Yok
}

private void button1_Click(object sender, EventArgs e)
{
String Deger;
Deger = "Okan Bilke";
MesajVer(out Deger);
}

PARAMS
Gönderilecek olan değişkenler dizi olarak değil birden fazla değişken ismiyle yapılacaksa params bildirisinden faydalanabilirsiniz. Aşağıdaki örnekte bu husus işlenmektedir.
private void IsimGoster(params String[] AdiSoyadi)
{
System.Collections.IEnumerator DiziOku = AdiSoyadi.GetEnumerator();
while (DiziOku.MoveNext())
{
String Deger;
Deger = (String)DiziOku.Current;
MessageBox.Show(Deger);
}
}

private void button1_Click(object sender, EventArgs e)
{
String Bir, Iki, Uc, Dort;
Bir = "Okan Bilke";
Iki = "Göksu Bilke";
Uc = "Onur Bilke";
Dort = "Neriman Bilke";
IsimGoster(Bir, Iki, Uc, Dort);
}

IsimGoster prosedürünü çağırırken kullanılan parametrelerin dizi değişken değil, birden fazla değişken ismi olduğuna dikkat ediniz. Burada bir esnekliği gözünüzden kaçırmamanızı istiyorum. Biz örneğimizi 4 parametreyle işlettik. Siz dilerseniz 3 veya daha değişik bir sayıyla da işletebilirdiniz. Gönderdiğiniz parametreler hangileriyse ona göre bir prosedür işletilecektir.
Aşağıdaki örnek ise günlük yazdığınız bir çok kod içerisinde karşılaşabileceğiniz bir durumdur. Öncelikle verilen ekran görüntüsünü oluşturunuz.
Resim

Şimdi aşağıdaki kod satırlarını uygulamanıza ekleyin.
using System.Collections;

namespace ElektroArge_Ders28
{
public partial class Form3 : Form
{
ArrayList Dizi = new ArrayList();
public Form3()
{
InitializeComponent();
}

private void KelimeleriBul(params Char[] Karakterler)
{
Dizi.Clear();
int Ilk, Son;
String Kelime;
string Deger = textBox1.Text;
Ilk = 0;
for (int i = 0; i <= Deger.Length - 1; i++)
{
for (int j = 0; j <= Karakterler.Length - 1; j++)
{
if (Karakterler[j] == Deger[i])
{
Son = i;
Kelime = Deger.Substring(Ilk, Son - Ilk);
Dizi.Add(Kelime);
Ilk = Son;
}
}
}
}

private void button1_Click(object sender, EventArgs e)
{
// textBox1.Text = "Yıldırım Beyazıt Üniversitesi Mühendislik ve Doğa Bilimleri Fakültesi";
KelimeleriBul(' ','.','_','-','*');
for (int i = 0; i <= Dizi.Count - 1; i++)
{
listBox1.Items.Add(Dizi[i].ToString());
}
}
}
}

Bu aşamadan sonra uygulamanızı çalıştırabilirsiniz. TextBox içerisine metni girildikten sonra Bul düğmesine tıklarsanız girmiş olduğunuz metin boşluk, nokta, virgül, iki nokta üst üste, tire, alt çizgi veya yıldız karakterine göre kelimelere ayrılacaktır.
Uygulama çalıştıktan sonra ekran görüntüsü aşağıda verilmiştir. Dikkat edin boşluk karakterine göre kelimeler birbirinden ayrıştırılmıştır.
Resim

Şimdi TextBox içerisindeki metni aşağıdaki şekilde değiştirerek sayfayı yeniden yükleyin. Dikkat edin bu sefer metin içerisindeki kelimeler "." karakterine göre ayrıştırılacaktır.
Resim
okanbilke@gmail.com
Kullanıcı avatarı
okanbilke
Site Kurucusu
Site Kurucusu
 
Mesajlar: 721
Beğendiklerim: 0 mesaj
Beğenilenlerim: 0 mesaj
Kayıt: 15 Mar 2013 13:09
Konum: Ankara

Reklam

Dön C#

Kimler çevrimiçi

Bu forumu gezen kullanıcılar: Hiç bir kayıtlı kullanıcı yok ve 1 misafir


  • Reklam
cron