üye ol Üye Girişi Söyle Sözünü Anasayfa Yukari Çik
Bilgi Paylaştıkça Büyür

C#-CSharp Programlama Dili

Her Yönüyle C# Programımız

C# dili ortaya çıkalı daha hiç birşey yapmayan varsa ya da birşeyler yapıp da ne yaptığından emin olmayan varsa işte bu yazı tam size göre. Bu yazımızda klasik Merhaba Dünya programımızı yazacağız.Ama programımızı yazarken her şeyi adım adım öğreneceğiz. Unutmayın amacımız burada Merhaba Dünya yazmak değil. :) O halde aşağıdaki programı iyice inceleyin önce, şöyle bir süzün programı yukarıdan aşağıya, fazla detaylara inmeden yazımızı okumaya devam edin;

//dosya adı : Merhaba.cs

using System;

namespace MerhabaDunya

{
    class Sınıf1
    {
        static void Main(string args[])
        {
        Console.WriteLine(“Merhaba Dünya”);
        }
    }
}

Yukarıdaki ilk programımızı incelediğinize göre açıklamalarımıza geçebiliriz. Eğer önceden C++ ve Java ile ilgilenmiş arkadaşlar varsa yukarıdaki kodlar tanıdık gelebilir. Nitekim, her ne kadar Microsoft firması ilk başlarda bunu kabul etmese de C# dili Java ve C++ dillerinin harmanlanmasından oluşmuş bir dildir. Bugün bunu kabul etmeyen yoktur sanırım.

Yukarıdaki ilk programımızın kodunu ben Notepad ile yazdım. Ama kodu derleyip çalıştırmak için bir C# derleyicisine ihtiyacımız olacak. C# derleyicisi Visual Studio.NET ile kurulabileceği gibi www.microsoft.com web sitesinden .NET Framework yazılımını indirerek de kurulabilir. Eğer Visual Studio ortamında çalışıyorsanız yukarıdaki kodları Visual Studio .NET ‘ in sunduğu hazır proje şablonlarından rahatlıkla oluşturabilirsiniz. Visual Studio programını çalıştırdıktan sonra Project->New menüsünden dil olarak Visual C# ve proje şablonu olarak da “Console Application” seçerseniz, main işlevi içindeki kodlar dışındaki yapı otomatikmen oluşturulacaktır.Eğer .NET Framework yapısını kurduysanız Console Ekranından C# derleyicisini çalıştırmalısınız. Komut ekranını <csc Merhaba.cs> yazarak kaynak kodumuzu derleyebilirsiniz.

Şimdi kodlarımızı inceleyelim. İlk satırdaki <using System;> ifadesi System adlı bir isim alanının kullanılacağını belirtiyor.Peki nedir bu isim alanı(Namespace). İsimalanı kavramı son yıllarda program modüllerinin çok sayıda artmasından dolayı popüler hale gelmiştir. Kolay ve hızlı programlama yapmamızı sağlayan bir takım hazır kütüphaneler her ne kadar işimizi kolaylaştırsa da eğer isimalanları olmasaydı kullanacağımız her kütüphane bizim için işin içinden çıkılmaz bir hale gelebilirdi. Düşünün ki iki ayrı firma iki ayrı sınıf kütüphaneleri oluşturdu ve bu kütüphanelerin içinde aynı isimli birden çok sınıf yapısı var. Eğer biz programcı olarak iki firmanın da kütüphanesini kullanmak istiyorsak her ikisini aynı kod içinde kullanamayız. Çünkü aynı isimli sınıflar derleme aşamasında hata verecektir. Bu durumda yapılması gereken tek şey ya da en etkili yöntem isimalanlarını kullanmaktır. Yani bir sınıfa(class) ulaşabilmek için onun isim alanıyla çağırmak. İsim alanları hiyerarşik yapıda olabilir. Mesela System isim alanının altında başka bir isim alanı onun altında başkaları vs. İşte .NET isimalanı(namespace) hiyerarşisinin en tepesinde bulunan isim alanı System adlı isimalanıdır. En temel işlemlerimiz için bile bu isim alanını kullanmalıyız. Aksi halde programımız çalışmayacaktır. İsimalanlarını kullanmak için isimalanının başına using sözcüğü getirilir.

Soru: System isim alanının içinde Data isimalanında bulunan bir cs adlı sınıfı kullanabilmek için kaynak kodumuza ne eklememiz gerekir.

Cevap : Kaynak kodumuzun en başına aşağıdaki ifadeyi yazmamız gerekir.

using System.Data;

Bildiğiniz gibi C# dili %100 nesne tabanlı bir dildir. Yaptığımız herşey bir sınıf nesnesidir C# dilinde. Nesne olmayan hiçbirşey yoktur. C++ dilindeki main işlevini hatırlarsınız çoğunuz. Programımız c++ dilinde main işlevinden başlar ama main işlevi hiç bir zaman bir sınıf içinde olmamıştır.C# dilinde herşey sınıflarla temsil edildiği için main işlevi de bizim belirlediğimiz bir sınıfın işlevi olmak zorundadır. Yukarıdaki programımızda <class Sınıf1> ifadesi ile programımızda bir sınıf nesnesi oluşturuyoruz. Sınıf1 sınıfının bir işlevi olan main’in elbette eskiden de olduğu gibi özel bir anlamı vardır. Biliyorsunuz ki derleyiciler programın nerden çalışacağını bilmek isterler, aksi halde derleme işleminden sonra “programınız için başlama noktası bulunamadı” hatası alırız. Bu yüzden main işlevi bizim için eskiden de olduğu gibi programımızın başlangıç noktasıdır. Yani biz programda yapmak istediklerimizi main işlevi içinde gerçekleştireceğiz. Sınıf tanımlamalarımızı ise istediğimiz noktada yapabiliriz. Daha öncede dediğimiz gibi isimalanları birçok sınıfın veya tek bir sınıfın oluşturduğu kümedir. Bizim ana programımız da bir sınıf olduğuna göre Class1 sınıfını istediğimiz isimli bir isimalanına sokabiliriz. Yukarıda <namespace MerhabaDunya> yazarak isimalanını başlatıyoruz.

Şimdi main işlevinin içine bakalım, System isimalanında bulunan Console sınıfının bir metodu olan WriteLine() ile ekrana bir string ifadesi yazdırıyoruz. Biz burda iki tırnak ifadesi içinde yazımızı belirtmemize rağmen fonksiyonun kullanmı bununla sınırlı değildir. C# dilindeki fonksiyon aşırı yükleme (function overloading)kullanılarak fonksiyonu birçok parametrik yapıda kullanabilmemiz sağlanmıştır. Fonksiyon aşırı yükleme konusuna bundan sonraki yazılarımızda değineceğimizi belirtelim. WriteLine() işlevinin adından da anlaşılacağı gibi ekrana basmak istediğimiz yazıdan sonra satır atlama işlemi yapar.Bunu test etmek için bir tane “Merhaba Dünya” da siz yazdırın. Göreceksiniz ki siz belirtmemenize rağmen alt alta iki tane “Merhaba Dünya” yazısı çıkacak.

Eğer bu programı yazıp derlediyeseniz ne mutlu size ki C# dünyasına güzel bir adım attınız.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Visual C# ile Windows Menüleri Hazırlama

Merhaba, bu makalemizde, hemen hemen tüm Windows uygulamalarının temel yapı taşı olan Windows menülerinin nasıl hazırlandığını ve basit bir uygulamasını adım adım göreceğiz. Bildiğiniz gibi Windows menülerini şimdiye kadar Visual Basic ortamında çok basit bir şekilde yapmak mümkündü. Ama artık Visual C# ile menü hazırlamak hem daha kolay hem de daha eğlenceli. Bu makalede yapacağımız uygulamadaki amacımız, File ve Edit bölümünden oluşan Windows menüsünü tek bir Windows butonuyla aktif ya da pasif duruma getirmek.

Şimdi uygulamamızın ilk adımı olan yeni proje oluşturma sayfasını açalım.
File->New -> Project menüsünü kullanarak aşağıdaki gibi yeni bir proje oluşturalım.
Proje tipi olarak Visual C# Project, template olarak da Windows Application seçtikten sonra projemize uygun isim verip OK butonuna tıklayalım.

 

Projemizi oluşturduğumuzda Visual C# IDE ‘sinin bizim için bir başlangıç formu oluşturduğunu görürüz. Bu form doğal olarak şu anda boştur. Toolbox menüsünü kullanarak Form üzerine istediğimiz kontrolleri sürükle bırak yöntemiyle yerleştirebiliriz. Ya da istediğimiz kontrolü çift tıklayarak da aynı işlevi gerçekleştirebiliriz. Eğer toolbox menüsünü göremiyorsanız ekranın sol alt küşesinde bulunan

 

ToolBox ikonuna tıklayın. Şimdi formumuza basit bir MainMenu kontrolu ekleyelim. Yine ToolBox menüsünden aşağıdaki ikona şekline benzeyen kısma çift tıklayın. Eğer işlem başarılıysa formunuzun en üst kısmında edit edilmek üzere bir menü oluşacaktır.

 

MainMenu üzerine fare ile gelerek istediğiniz menü elemanlarını ekleyin.Ben önce File elemanını sonra Edit elemanını ve Edit elemanının içinde de Copy ve Paste menü elemanlarını aşağıdaki gibi oluşturdum.

 

Şimdi menü elemanlarımıza Properties penceresinden isim verelim. Aşağıda gördüğünüz pencereden form design penceresinden seçtiğiniz elemanla ilgili özelliklere ulaşabilirsiniz.Şimdi Edit menü elamanına tıklayarak Properties ekranındaki name özelliğine “menuEdit” yazalım. Burda menu elemanına verdiğimiz ismi daha sonra kod yazarken kullanacağımız için aklımızda kalacak bir isim vermemiz düzenli kod yazmak için önemli bir sebeptir. Menü elemanlarıyla işimiz bittiğine göre sıra menüyü kontrol edeceğimiz butonu yerleştirmeye geldi. ToolBox penceresinden “Buton” a çift tıklayarak forma bir buton yerleştirelim .Daha sonra butona tıklayıp Properties penceresinden buton ismi (Name) olarak “BizimButon ” yazalım. BizimButon ‘ un text özelliğine ise “MENU PASİF ET” yazısını yazalım. Bu yazıyı yazmamızın sebebi ise şudur: Mene elemanları varsayılan olarak aktif durumdadırlar. Bu yüzden menüyü pasif hale getirmek için bu yazıyı seçtik.

 

Evet,Form tasarım işlemi bitti. Şimdi sıra geldi BizimButon ile menüye aktif ve pasif durumları arasında geçiş yaptırmak. Tabi asıl işte şimdi başlıyor.
Form üzerindeki butona çift tıklayarak kod yazma ekranına gelelim.

Gördüğünüz gibi Visual C# bizim için bir takım kodlar oluşturdu. Biraz bu hazır kodları ana hatlarıyla inceleyelim.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

Yukarıdaki kodlarla programımızın kullanacağı bir takım sistemler derleyiciye bildiriliyor.

public class Form1 : System.Windows.Forms.Form

System.Windows.Froms.Form sınıfından yeni bir Form1(bizim form) sınıfı türetilerek bu form içindeki elemanlar tanımlanıyor.

private System.Windows.Forms.MainMenu mainMenu1;
private System.Windows.Forms.MenuItem menuFile;
private System.Windows.Forms.MenuItem menuEdit;
private System.Windows.Forms.MenuItem menuItem3;
private System.Windows.Forms.MenuItem menuItem4;
private System.Windows.Forms.Button BizimButon;
private System.ComponentModel.Container components = null;

private void InitializeComponent() işlevi ile Form1 sınıfı içindeki elemanlarla ilgili ilk işlemler yapılıyor. Elemanların form üzerindeki yeri ve elemanlara ait Properties penceresinden tanımladığımız bütün özellikleri bu işlev ile yerine getirilir.

static void Main()
{
Application.Run(new Form1());
}

Uygulamamızın Form1 üzerinden gerçekleştirileceğini belirtir.

İşte bu da bizim kodumuz :

private void BizimButon_Click(object sender, System.EventArgs e)
{
if (menuEdit.Enabled)
{
menuEdit.Enabled=false;
BizimButon.Text=”MENU AKTIF ET”;
}
else
{
menuEdit.Enabled=true;
BizimButon.Text=”MENU PASIF ET”;
}
}

Bu kodu yazabilmek için form design penceresinden BizimButon çift tıklayarak BizimButon_click() işlevinin içine geçelim. Yukarıdaki kodda eğer menuEdit aktifse pasif duruma getiriyoruz ve BizimButon ‘a da “MENU AKTIF ET” yazıyoruz. Eğer menuEdit zaten pasifse Menuyu aktif hale getirip BizimButon yazısını da “MENU PASIF ET” yapıyoruz. Aşağıda her iki durum için programımızın çıktısı mevcuttur.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

C ve C++ bakış açısıyla C# dili

 

Bildiğimiz gibi bilgisayarları programlamak için programlama dillerine ihtiyaç duyulur.Bu dillerden en popülerleri Basic,C,C++,Pascal,Java ve Assembler ‘dır.Makina dili ise donanımı kontrol etmek için donanımı üreten firma tarafından tanımlanan komutlar kümesidir. Bazı programlama dilleri derleyicilere ihtiyaç duymasına karşın bazıları ise yorumlayıcılara ihtiyaç duyarlar, mesela bir c++ programını çalıştırabilmek için C++ derleyicisine ihtiyacımız varken, Perl ile yazılmış bir CGI scripti için komut yorumlayıcısına ihtiyacımız vardır. Derleyiciler programı çalıştırmadan önce kodları makina komutlarına çevirirler fakat yorumlayıcılar bir grup kodu satır satır ya da bloklar halinde yorumlayarak çalıştırırlar.

Aslında derleyiciler de, komut yorumlayıcıları da birer bilgisayar programından başka birşey değildirler.Yani c ve c++ dilleri bir giriş bekleyen ve çıkış veren birer bilgisayar programları gibi düşünülebilir.Giriş olarak kaynak kodu veren bu programlar çıkış olarak ise makina kodu üretirler.

C ve C++ dillerine kısa bir bakış:

C dili en popüler yapısal programlama dilidir.C dili Dennis Ritchie tarafından, Martin Richards ve Ken Thompson tarafından geliştirilen BCBL ve B dillerinin temelleri üzerine kuruldu.

C dili “The C Programming Language by Brian Kernighan and Dennis Ritchie” kitabıyla büyümüştür.C dili için, 1983 yılının büyük önemi vardır.Çünkü 1983 yılında ANSI standartlar komitesi C standartları için toplanmıştır.Bu standartlaşma süreci tam 6 yıl sürmüştür.Ve tabi ki şu anki standartların oluşumuna katkıda bulunan ANSI 99 standartları da diğer önemli bir gelişmedir.

C programcılar tarafından herhangi bir tür program geliştirmek için yazılmış genel amaçlı bir dildir. C ile bir düşük seviyeli sistem için program yazabileceğimiz gibi, yüksek seviyeli bir GUI(Grafik Arabirimi) tasarlamamız da mümkündür.Ve elbette kendi kütüphanemizi de C ile oluşturabiliriz.C dilinin ortaya çıkmasından bunca yıl geçmesine rağmen popülaritesini hiçbir zaman kaybetmemiştir. Günümüz programcıları çeşitli amaçlar için programlarını geliştirirken C dili ile yazılmış kaynak kodlarını kullanırlar.

Bjarne Stroustrup 1980 yıllında C++ dilini ortaya çıkarmıştır. C++ dili C temelli ve C nin bir üst kümesi olarak düşünülebilir. C++ en popüler nesne temelli programlama dilidir. C++ dilinin ilk ismi “C with Classes”(C ile sınıflar) idi. C++ dili C diline nazaran daha etkili ve güçlüdür.Ve en önemli özellği ise C ‘den farklı olarak nesne temelli bir dildir.Şu anda C++ dili ANSI ve ISO kuruluşları tarafından standartlaştırılmıştır. Bu standartların son versiyonu 1997 yılında yayınlanmıştır.

C# diline kısa bir bakış:

C#, güçlü, modern, nesne tabanlı ve aynı zaman type-safe(tip-güvenli) bir programlama dilidir.Aynı zamanda C#, C++ dilinin güçlülüğünü ve Visual Basic’ in ise kolaylığını sağlar.Büyük olasılıkla C# dilinin çıkması Java dilinin çıkmasından bu yana programcılık adına yapılan en büyük gelişmedir. C#, C++ ‘ın gücünden , Visual Basic ‘in kolaylığından ve Java ‘nın da özelliklerinden faydalanarak tasarlanmış bir dildir. Fakat şunu da söylemeliyiz ki, Delphi ve C++ Builder ‘daki bazı özellikler şimdi C# ‘da var. Ama Delphi ya da C++ Builder hiçbir zaman Visual C++ ya da Visual Basic ‘in popülaritesini yakalayamamıştır.

C ve C++ programcıları için en büyük sorun, sanırım hızlı geliştirememedir. Çünkü C ve C++ programcıları çok alt seviye ile ilgilenirler.Üst seviyeye çıkmak istediklerinde ise zorlanırlar.Ama C# ile artık böyle bir dert kalmadı.Aynı ortamda ister alt seviyede isterseniz de yüksek seviyede program geliştirebilirsiniz.C# dili Microsoft tarafından geliştirilen .NET paltformunun en temel ve resmi dili olarak lanse edilmiştir.C# dili Turbo Pascal derleyicisini ve Delphi ‘yi oluşturan takımın lideri olan Anders Heljsberg ve Microsoft’da Visual J++ takımında çalışan Scott Wiltamuth tarafından geliştirilmiştir.

.NET framework’ünde bulunan CLR (Common Language Runtime), JVM (Java Virtual Machine)’ ye, garbage collection, güvenilirlik ve JIT (Just in Time Compilation) bakımından çok benzer.

CLR, .NET Framework yapısının servis sağlama ve çalışma zamanının kod organizasyonu yapan ortamıdır. CLR, ECMA standartlarını destekler.

Kısacası C# kullanmak için CLR ve .NET Framework sınıf kütüphanesine ihtiyacmız vardır. Bu da demek oluyor ki C#, JAVA, VB ya da C++ değildir. C,C++ ve JAVA ‘nın güzel özelliklerini barındıran yeni bir programlama dilidir. Sonuç olarak C# ile kod yazmak hem daha avantajlı hem daha kolay hem de etkileyicidir.

Bir başka yazıda buluşmak ümidiyle …

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

C#’da İfadeler, Tipler ve Değişkenler

 

Bu derste C# dilindeki ifadeler,tipler ve değişkenler anlatılacaktır.

Dersimizin hedefleri : 

  • Değişken kavramının anlaşılması. 
  • C# dilinde bulunan basit tiplerin öğrenilmesi.
  • C# dilindeki ifadelerin temel olarak anlaşılması. 
  • String veri tipinin öğrenilmesi.

Değişkenleri en sabit şekilde verilerin depolandğı yerler olarak tanımlayabiliriz. Değişkenlerin içine verilerimizi koyabilirirz veya değişkenlerimizin içindeki verileri C# programındaki işlemlerimiz için kullanabilliriz. Değişkelerin tipini belirleyen faktör, onların içerdikleri verilerin çeşitleridir. 

C# dilinde kullanacağımız her değişkenin bir tipi olmak zorundadır ( Vbscript ve JavaScript gibi dillerde değişken tanımlarken onun tipini de ayrıca belirtmeye gerek yoktur.) Bir değişken üzerinde yapılan tüm işlemler de onun hangi tipte bir değişken olduğu göz önüne alınarak yapılır. Böylece programda bütünlük ve güvenlik korunmuş olur.

Boolean ( doğru/yanlış ), ve üç sayısal veri tipi; integer( tamsayı ), floating point (ondalıklı sayı ) ve decimal( muhasebe ve finansal işlemler için) C# dilinin en basit veri tipleri olarak sayılabilir.

 Kod 1 : Boolean değerlerin görüntülenmesi : Boolean.cs

 using System;

 class Booleans

{

 public static void Main()

{

  bool content = true;

 bool  noContent = false;

 Console.WriteLine(“It is {0} that C# Station provides C# programming language content.”, content);

 Console.WriteLine(“The statement above is not {0}.”, noContent);

}

}

Yukarıdaki Kod 1’de de görüleceği gibi boolean değişkenler ya true(doğru) veya false(yanlış) değerlerini alabilirler. Programın çıktısı şöyle olacaktır.

>It is True that C# Station provides C# programming language content.
>The statement above is not False.

Aşağıdaki tablo tamsayı tiplerini, boyutlarını ve alabilecekleri değer aralıklarını göstermektedir.

Type ( Tip ) Size (in bits)(boyut ) Range (aralık)
sbyte 8 -128 to 127
byte 87 0 to 255
short 16 -32768 to 32767
ushort 16 0 to 65535
int 32 -2147483648 to 2147483647
uint 32 0 to 4294967295
long 64 -9223372036854775808 to 9223372036854775807
ulong 64 0 to 18446744073709551615
char 16 0 to 65535

Tamsayı tipleri küsuratsız işlemler için çok elverişlidirler. Fakat char( karakter) tipi Unicode standartlarına uygun olarak bir karakteri temsil eder. Yukarıdaki tablodan da göreceğiniz gibi elimizde çok sayıda tamsayı tipimiz vardır. Bunlardan istedikleriminizi ihitiyaçlarımıza göre rahatça kullanabiliriz.

Bir sonraki tablo ise ondalık (floating point ) ve decimal veri tiplerini,boyutlarını, hassasiyetlerini ve geçerli oldukları aralıkları listeler.

Type ( Tip ) Size (in bits)(boyut ) Precision Range
float 32 7 digits 1.5 x 10-45 to 3.4 x 1038
Double 64 15-16 digits 5.0 x 10-324 to 1.7 x 10308
Decimal 128 28-29 decimal places 1.0 x 10-28 to 7.9 x 1028

Ondalıklı sayıları küsuratlı işlemlerde kullanmak iyi olur. Bunun yanında muhasebe ve finansal işlemler için decimal veri tipi daha uygun olacak şekilde tasarlanmıştır.

Bilgisayar programları işlemleri yaparken ifadeleri kullanırlar ve sonuç ortaya çıkartırlar. Programlarda yer alan ifadeler değişkenler ve işleçlerden ( operatör) oluşurular. Bir sonraki tabloda işleçleri, işleçlerin işlem sıralarını ve işleme yönlerini görebilirsiniz.

Category ( kategori) Operator(s) (işleç/işleçler) Associativity(işeme yönü)
Primary (x) x.y f(x) a[x] x++ x– new typeof sizeof checked unchecked left Unary + – ! ~ ++x –x (T)x left
Multiplicative * / % left
Additive + - left
Shift << >> left
Relational < > <= >= is left
Equality == != right
Logical AND & left
Logical XOR ^ left
Logical OR | left
Conditional AND && left
Conditional OR || left
Conditional ?: right
Assignment = *= /= %= += -= <<= >>= &= ^= |= right

Sol işleme yönü demek işlemlerin soldan sağa doğru yapıldığıdır. Sağ işleme yönü demek işlemlerin sağdan sola doğru yapıldığıdır. Mesala atama işleçlerinin hepsinde önce sağ tarafın sonucu bulunur ve bu sonuç sol tarafa aktarılır.

Kod 2 : Unary Operators: Unary.cs

using System;

class Unary
{
    public static void Main()
      {
          int unary = 0;
          int preIncrement;
          int preDecrement;
          int postIncrement;
          int postDecrement;
          int positive;
          int negative;
          sbyte bitNot;
          bool logNot;
         

         preIncrement = ++unary;
           Console.WriteLine(“Pre-Increment: {0}”, preIncrement);

           preDecrement = –unary;
         Console.WriteLine(“Pre-Decrement: {0}”, preDecrement);

         postDecrement = unary–;
         Console.WriteLine(“Post-Decrement: {0}”, postDecrement);

         postIncrement = unary++;
         Console.WriteLine(“Post-Increment: {0}”, postIncrement);
         Console.WriteLine(“Final Value of Unary: {0}”, unary);

         positive = -postIncrement;
         Console.WriteLine(“Positive: {0}”, positive);

         negative = +postIncrement;
         Console.WriteLine(“Negative: {0}”, negative);

        logNot = false;
        logNot = !logNot;
        Console.WriteLine(“Logical Not: {0}”, logNot);

     }

}

 

İfadeler işlemler yapılırken arka-artırma ve arka-azaltma işleçleri önce değişkenin değerini döndürür sonra değişken üzerinde artırma veya azaltma işlemini yapar. Diğer taraftan, ön-artırma ve ön-azaltma işleçleri önce değişken üzerinde artırma veya azaltma işlemini yapar sonra değişkenin son halini döndürür.

Kod 2‘de unary (tek) değişken önce sıfır olarak atanıyor. Ön-artırma (pre-increment) işleci uygulandığında, unary değişkenin değeri 1’e çıkıyor ve “preIncrement” değişkenine atanıyor. Hemen arkasında Ön-azaltma(pred-decrement) işleci sayesinde unary değişkenimiz tekrar sıfır değerini alıyor preDecrement değişkenine bu değer atanıyor.

Arka-azaltma (post-decrement) işleci unary değişkenimize uygularsak bu değişkenimizin değeri değişiyor ama önce değişkenin ilk değeri postDecrement değişkenine atanıyor. Sonra ise arka-artırma (post-increment) işlecini uygularsak unary değişkenimizin değeri azalıyor fakat postIncrement değişkenin değeri unary değişkenimizin ilk değeri olarak kalıyor.

Mantıksal değil işareti, doğru ifadeyi yanlış, yanlış ifadeyi ise doğru olarak değiştirir. Kod 2’inin çıktısı şöyle olacaktır :

   >Pre-Increment: 1
   >Pre-Decrement 0
   >Post-Decrement: 0
   >Post-Increment -1
   >Final Value of Unary: 0
   >Positive: 1
   >Negative: -1
   >Logical Not: True

Kod 3. Binary Operators: Binary.cs

using System;

class Binary
{
    

public static void Main()
       {
          int x, y, result;
          float floatResult;

          x = 7; y = 5;

         result = x+y;
         Console.WriteLine(“x+y: {0}”, result);

         result = x-y;
         Console.WriteLine(“x-y: {0}”, result);

         result = x*y;
         Console.WriteLine(“x*y: {0}”, result);

         result = x/y;
         Console.WriteLine(“x/y: {0}”, result);

         floatResult = (float)x/(float)y;
         Console.WriteLine(“x/y: {0}”, floatResult);

         result = x%y;
         Console.WriteLine(“x%y: {0}”, result);

         result += x;
         Console.WriteLine(“result+=x: {0}”, result);

     }

}

Kod 3: te birçok aritmetik işlemler yapılıyor. Bu işlemlerin sonucunu da sizler tahmin edebilirsiniz…

“floatResult” değişkenin tipi ondalıklı sayı tipi olduğu ve “x” ve “y” değişkenlerimiz tamsayı tiplerinde oldukları onları açık biçimde ondalıklı sayı tipine çevirdik ( explicitly cast ) ve bu şekilde işlem yaptık.

Yukarıdaki kod parçasında bir de kalan (remainder % ) işlecinin kullanılışına dair örnek verdik. Bu işleç, iki sayının bölümününden kalan sayıyı sonuç olarak döndürür.

Son olarak yazdığımız ifadede yeralan atama işleci de (+=) C/C++ ve C# programcılarının sıklıkla kullandıkları bir atama ve işlem yapma türüdür. Bu ifade aslında şu ifadenin kısa yoludur : “result = result + x”.

Şimdiye kadar burada sıkça gördüğünüz diğer veri tipi ise string ( karakter dizisi veya karakter katarı)’dir. String veri tipi Unicode karakter tiplerinin bir listesini içerirler ve tek çift tırnak işaretleri arasında yazılırlar.

 

 

 

 

 

 

C# Kontrol yapıları ve seçme işlemleri

 

Bu derste C# dilindeki ifadeler,tipler ve değişkenler anlatılacaktır.  C# dilinde kullanılan seçme veya kontrol ifadelerini öğreneceksiniz.

Dersimizin hedefleri :

  • “İf” (eğer) ifadesinin kullanımı “
  • “switch” (çoktan-seç) ifadesini kullanımı “
  • “break” ifadesinin “switch” ifadesi içerisinde nasıl kullanıldığı
  • ” “goto” ifadesinin yerinde ve etkili kullanılması

Önceki derslerimizde, her program belirli ifadeleri sırasıyla çalıştırıp bitiyordu. Program içinde inputlara veya program içinde yapılan hesaplara göre değişik işlemler yapılmıyordu. Bu derste öğrendiklerimiz de programlarımızın belirli şartlara göre değişik şekillerde çalışmasını sağlayacaktır. İlk seçme ifademiz “if”. “if” kontrol yapısının 3 temel formu vardır.

Kod 1 : IF yapısının değişik formlarda kullanımı : IfSelection.cs

 using System;

class IfSelect

{
   public static void Main()
    {
       string myInput;
       int myInt;

       Console.Write(“Please enter a number: “);
       myInput = Console.ReadLine();
       myInt = Int32.Parse(myInput);

        // Single Decision and Action with brackets
        if (myInt > 0)
           {
               Console.WriteLine(“Your number {0} is greater than zero.”, myInt);
           }

        // Single Decision and Action without brackets
        if (myInt < 0)
          Console.WriteLine(“Your number {0} is less than zero.”, myInt);

       // Either/Or Decision
        if (myInt != 0)
           {
              Console.WriteLine(“Your number {0} is not equal to zero.”, myInt);
           }
       else
          {
              Console.WriteLine(“Your number {0} is equal to zero.”, myInt);
           }

         // Multiple Case Decision
       if (myInt < 0 || myInt == 0)
            {
                Console.WriteLine(“Your number {0} is less than or equal to zero.”, myInt);
            }

       else if (myInt > 0 && myInt < = 10)
          {
              Console.WriteLine(“Your number {0} is between 1 and 10.”, myInt);
          }

      else if (myInt > 10 && myInt < = 20)
           {
               Console.WriteLine(“Your number {0} is between 11 and 20.”, myInt);
           }

     else if (myInt > 20 && myInt < = 30)
           {
               Console.WriteLine(“Your number {0} is between 21 and 30.”, myInt);
           }

    else
          {
              Console.WriteLine(“Your number {0} is greater than 30.”, myInt);
          }

    }

}

Kod 1′de tüm program boyunca tek bir değişkeni kullanıyoruz, “myInt”. Kullanıcıdan etkileşimli olarak veri almak için önce “Lütfen bir sayı giriniz :” iletisini konsula yazdırıyoruz. “Console.Readline()” ifadesi ile program kullanıcıdan bir değer girmesini bekler. Bir rakam yazılınca ve enter tuşuna basılınca program yazılan değeri önce string tipinde olan myInput değişkenine atanıyor. String olarak alınan veriyi program tamsayı tipinde bir değişken olarak kullanmak istediği için “myInput” tamsayı tipine dönüştürülmeli. Bu dönüşüm için “Int32.Parse(myInput)” komutunu kullandık ( tip dönüşümleri ve Int32 gibi veri tipleri ileriki derslerde incelenecektir.) Daha sonra, dönüşümün sonucu “myInt” isimli değişkene aktarılıyor.

Artık istediğimiz tipte bir veriye sahibiz ve bunu “if” ifadesi içinde işleyebiliriz. “if” ifade bloğunun ilk formu şu şekildedir : if(mantıksal ifade) { “mantıksal ifade”nin doğru olası durumunda yapılması gerekenler }. Öncelikle “if” anahtar kelimesi ile başlamalıyız. Sonrası parantezler arasındaki mantıksal ifade. Bu mantıksal ifadenin doğru veya yanlış olması bulunur. Biz programımızda kullanıcıdan aldığımız sayının sıfırdan büyük olup olmadığını kontrol ediyoruz”>0″ ile. Eğer sayı sıfırdan büyükse, mantıksal ifadenin sonucu doğrudur ve { } parantezleri arasındaki kod bloğu çalıştırılır. Eğer mantıksal ifade yanlış bir sonuç üretirse { } arasındaki kon bloğu çalıştırılmadan bloktan sonraki ifadelere geçer.

İkinci “if” ifadesi aslında birincisi ile aynıdır, ikincisi sadece blok içinde değildir. Eğer boolean ifade doğru sonuç üretirse, bu ifadeden hemen sonraki çalışır. Boolena ifadenin yanlış olması durumunda ise bu ifadeden hemen sonraki ifade çalıştırılmadan bir sonraki ifadeye geçilir ve o ifade çalıştırılır. Bu şekildeki “if” yapısını, boolean ifadenin doğru olmasında sadece bir tane ifade çalıştırılacaksa yeterlidir. Buna karşın “if” ifadesinin sonucuna göre birden fazla ifade işleme konulacaksa blok olarak { } parentezleri arasında yazılır. Benim kişisel önerim “if” den sonra çalıştırılacak ifade sayısına bakmadan, bu ifade(leri) her durumda blok olarak yazmaktır. İleride yeni programın okunmasında ve yeni işlevler eklenmesinde size hatalardan kaçmanıza yardım eder.

Birçok zaman size eğer/değilse türünde çalışacak bir “if” yapısı gerekebilir. Üçüncü tip “if” ifadesi eğer doğru değer üretirse şunları yap, doğru değilse “else” anahtar sözcüğünden sonraki kodları çalıştır türünde bir yapısı olarak yazılmalıdır.

Birden fazla mantıksal ifadeyi işlememiz gerektiğinde ise, if/else if/else tipinde bir “if” yapısını kullanmak gerekir. Dördüncü örneğimizde bu tip bir if yapısını görebilirsiniz. Bu tip yapı yine “if” ve boolean ifadesi ile başlar. Boolean ifade doğru ise hemen alttaki bloktaki kodlar çalıştırılır. Bunun yanında, boolean ifadenin değişik durumlarına göre “else if” iç yapısı kullanılır. “else if” de aynı if gibi bir boolean ifadeyi alır ve sonucu doğru hemen sonraki bloktaki kodları çalıştırır.

Boolean ifadenin alabileceği tüm ihtimallere göre bu şekilde “else if” ifadeleri sıralanabilir fakat en sonda bir “else” ile yukarıdaki tüm şartların yanlış olması durumunda çalıştırılacak kodları belirleriz. Bu dördüncü “if” yapısında da yine sadece bir tane if/else blok yapısı çalıştırılır.

“switch” yapısı da “if/else if/else” yapısına çok benzer.

Kod 2 : Switch ifadeleri : SwitchSelection.cs

using System;

class SwitchSelect
{
    public static void Main()
      {
          tring myInput;
          int myInt;
          
      begin:        

         Console.Write(“Please enter a number between 1 and 3: “);
           myInput = Console.ReadLine();
         myInt = Int32.Parse(myInput);

           // switch with integer type
          switch (myInt)
          {
             case 1:
                   Console.WriteLine(“Your number is {0}.”, myInt);
                   break;
             case 2:
                   Console.WriteLine(“Your number is {0}.”, myInt);
                   break;
             case 3:
                   Console.WriteLine(“Your number is {0}.”, myInt);
                   break;
            default:
                   Console.WriteLine(“Your number {0} is not between 1 and 3.”, myInt);
            break;
          }

       decide:

        Console.Write(“Type \”continue\” to go on or \”quit\” to stop: “);
        myInput = Console.ReadLine();

        // switch with string type
       switch (myInput)
       {
          case “continue”:
                   goto begin;
          case “quit”: Console.WriteLine(“Bye.”); break;
        
         default:
                 Console.WriteLine(“Your input {0} is incorrect.”, myInput);
                 goto decide;
       }

   }

}

Kod 2′de birkaç tane “switch” yapısı örneğimiz var. “switch” yapısı yine “switch” anahtar kelimesi ile başlar ve sınanacak değişkeni parantez içinde belirtiriz. Switch yapısının çalışması için şu veri tiplerinden bir tanesini kullanmak gerekir : sbyte,short,ushort,int, long, ulong, char, string, or enum ( enum daha sonraki bir derste işlenecektir.)

Birinci örneğimizdeki “switch” yapısı int tipinde bir değer almaktadır. Tamsayı değişkenimizin alabileceği değerlere göre değişik işlemler yapabiliriz. “myInt” değişkenimizin herbir ihtimalini değerlendirirken “case” anahtar kelimesini, muhtemel değerini ve iki nokta üst üste “:” yapısında bir sınama yapıyoruz. Örneğimizde, “case 1 :”, “case 2: “, ve “case 3:” şeklinde yazdık. Sınama sonuçlarından uygun olanın hemen altında kod bloku yer alır. Bu kod blokundan sonra ise “break” veya “goto” ifadelerini kullanmamız gerekir.

İsterseniz “default” seçeneğini de “switch” ifadesi ile birlikte kullanabilirsiniz. “default” ifadesinin altındaki kod bloku, “defult”‘tan önceki “case”‘lerin hiçbiri sınamayı geçemediği zaman çalışır ve tüm “case”‘lerden sonra gelir.

Her “case” ‘den sonra “break” ifadesinin zorunlu olduğunu tekrar hatırlatalım. “break” ifadesi “switch” yapısından dışarı çıkmayı ve alttaki kodlara geçmemizi sağlar. “default” anahtar kelimesinin kod blokundan hemen sonra “break” koymak programcının isteğine kalmıştır. Switch ifadesinde iki tane dikkat edilmesi gereken husus vardır.

Birincisi, farklı durumları (case’leri) ard arda aralarına hiç kod yazmadan sıralamaktır. Aslında burada yapılan iş, değişkenimizin birden fazla değeri için tek bir “case” kod bloku oluşturmaktır. Bir case ve hemen arkasına başka bir case yazdığımızda program otomatik olarak bir sonraki “case” ‘e geçer. Aşağıdaki kodu incelediğimizde, “myInt” değişkeni 1,2, veya 3 değerlerinden herhangi birini alırsa kendi değerini ekrana yazdırıyoruz. Diğer durumda ise değişkenimizin değerinin 1 ve 3 arasında olmadığını ekrana yazdırıyoruz.

switch (myInt)
{
    case 1:
    case 2:
    case 3:
           Console.WriteLine(“Your number is {0}.”, myInt);
           break;
   default:
           Console.WriteLine(“Your number {0} is not between 1 and 3.”, myInt);
           break;
}

Kod 2′de yer alan ikinci “switch” yapısı ise “goto” ifadesinin nasıl kullanılacağını göstermek amacıyla yazılmıştır. “goto” , programın belirli bir kısmında yer alan, özel etiket (label) ile belirtilmiş kısmına atlamasına ve oradan itibaren çalışmaya devam etmesine yarar. Programımızda kullanıcı “continue” yazarsa “begin” olarak belirlenmiş etikete gider  ve oradan çalışmaya devam eder. Aslında bu şekilde “goto” kullanmak etkili bir döngü olur. Eğer kullanıcı “end” yazarsa program “bye” yazar ve döngüden programımız çıkar.

Açıkça görülüyor  ki “goto” kelimesini kullanmak bize programda belirli şartlar altında güç kazandırır. Yine de “goto” ifadesini programda sık bir şekilde kullanmak “sipagetti” kod olarak adlandırılan programlamaya yol açabilir ki, bu tür kodlama programı hem okurken hem de hataları ayıklarken büyük sorunlara sebep olabilir.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

C# ile Temel Windows Formları Oluşturma

Bu yazımızda Windows programlamanın temel elemanlarından olan windows formlarının nasıl oluşturulduğunu ve nasıl kullanıldığını göreceğiz, windows formlarını açıklarken basit bir dört işlem yapan hesap makinası oluşturacağız.Windows formları derken neyi kastediyoruz? Textbox, label, button gibi önemli elemanların hepsi birer windows formudur. Bu windows formlarına ulaşmak için System.Windows.Forms isimalanını kullanıyoruz. Ve tabi ki programımızın aktif bir windows uygulaması olarak çalışması için de aşağıdaki isimalanlarını projemize ekliyoruz.

using System.Drawing;
using System.Collections;
using System.ComponentModel;

Programımızı yazmaya başlamadan önce programımızın kodlarını içerecek bir isim alanı oluşturalım. Ben buna CsHesapMakinasi adi verdim.(Makaleyi okurken kaynak kodu incelemenizi tavsiye ederim) Siz istediğiniz başka bir isim kullanabilirsiniz.

Daha önceki makalelerimizde belirttiğimiz gibi programımızın çalışması için derleyiciye programın başlangıç noktasını bildirmemiz gerekirdi.Bu başlangıç noktası da genelde main() fonksiyonu oluyordu. Kodumuzu öyle ayarlayacağız ki main() fonksiyonu icra edildiğinde çalıştırmak istediğimiz windows formu ekranda görünsün. Bunun için main içine aşağıdaki kodu yazıyoruz.

Application.Run(new Form1()); // Yeni bir Form1 nesnesi oluşturularak uygulama olarak başlatılıyor.

Şu an için Form1 hakkında en ufak bir bilgiye sahip değiliz.Peki bu Form1 nasıl oluşturulacak. Yukarıda da bahsettiğimiz gibi Form1 sınıfından bir nesne oluşturmak için System.Windows.Forms isimalanını kullanmalıyız. Bu yüzden bu isim alanının altında bulunan Form sınıfından yeni bir Form1 sınıfı türetmemiz gerekecek, bu türetme işlemi aşağıdaki gibidir. Form1 sınıfını türettikten sonra Form1′ içinde bulunacak elemanları tanımlıyoruz.4 işlemi yapmak için 4 buton, işleme giren değerler için 2 textbox ve 2 tane de label formu tanımlıyoruz.Tanımlama işlemi aşağıdaki gibidir.

    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        private System.Windows.Forms.Button button3;
        private System.Windows.Forms.Button button4;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.TextBox deger1;
        private System.Windows.Forms.TextBox deger2;
        private System.Windows.Forms.TextBox sonuc;
        private System.Windows.Forms.Label isaret;
   }

Şimdi bu windows formunun ekrana nasıl basıldığını inceleyelim.Main() işlevi içinde yeni bir Form1 nesnesi yaratıldığında Form1 nesnesine ait kurucu işlev olan Form1() işlevi çağrılır.(Kaynak kodu inceleyin). Form1() kurucu işlevinde ise InitializeComponent(); adlı bir fonksiyon çağırılarak Form1 nesnesine ait olan üye elemanlarla (button,label,textbox vs) ilgili ilk işlemler yapılır.From1 açıldığı zaman Form1 içinde bulunan elemanlarla iligili yapmak istediğimiz ilk özellikleri InitializeComponent() fonksiyonu içinde yapıyoruz.

        private void InitializeComponent()
        {           
            // form1 içinde yer alacak elemanlar yaratılıyor(kaynak kodu inceleyin)
            
            this.deger2 = new System.Windows.Forms.TextBox();
            this.sonuc = new System.Windows.Forms.TextBox();
            this.button2 = new System.Windows.Forms.Button();
            this.isaret = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            //
            // elemanlarla ilgili başlangıç özellikleri veriliyor.
            //
            this.deger1.Location = new System.Drawing.Point(16, 8); //deger1 adlı textbox için yer bildirimi
            this.deger1.Name = “deger1″;
            this.deger1.TabIndex = 0;
            this.deger1.Text = “0″;

            this.name=”Form1″; //Form1 nesnesinin kendisi için this anahtar sözcüğünü kullanıyoruz
            this.text = “Hesap Makinası “;
            this.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)(128)), ((System.Byte)(0)));
            this.ClientSize = new System.Drawing.Size(400, 149);

        }
Şimdi sıra elemanlarla ilgili olayların birbirleri ile ilişkisine.Mesela bir buton formunun click olayının form tarafından yakalanabilmesi için aşağıdaki satırları yazmalıyız.

        this.button4.Click += new System.EventHandler(this.button4_Click);
        private void button4_Click(object sender, System.EventArgs e)
        {
            isaret.Text=“/”;
            sonuc.Text=System.Convert.ToString(System.Convert.ToInt32(deger1.Text)/ System.Convert.ToInt32(deger2.Text));
        }

buton4_Click() işlevinde, çalışma zamanında bir nesnenin özelliklerinin nasıl değiştirildiğini görüyoruz.button4 bölme işlemi yaptığından isaret.Text=”/”; yazdık. sonuc adlı textbox formunun Text özelliği bir string ifadesi olduğu için işlemlerimizi yaptıktan sonra sonuc.text ifadesine atama yapabilmek için System.Convert isimalanında bulunan ToString işlevini kullanarak ifadeyi String türüne dönüştürüyoruz. Aynı şekilde String olarak aldığımız türler için aritmetik işlem yapabilmek için yine aynı isimalanında bulunan ToInt32 işlevi ile String türünü int32 formatına dönüştürüyoruz. Bütün bu işlemleri 4 butonumuz için yaptığımızda dört işlem yapabilen basit ve bol bol bug içeren (unutmayın amacımız sadece formların kullanımını öğrenmek) bir hesap makinamız olacak.

 

 

 

 

 

 

 

 

.NET Teknolojilerine Giriş

 

Günümüzde bilgisayar dünyasında internet olmazsa olmaz derecede önemli bir yer edinmeye başladı. Artık insanlar ev ve işyerlerinde kullandıkları uygulamalarına da internet üzerinden erişip kullanmak istiyorlar. Bu internetin getirdiği özgürlüğün kaçınılmaz bir sonucudur.Peki yazılım dünyası buna hazırmıydı? Geliştirilen her programı kolayca internet ormanında da çalıştırabilirmiydik? Bu soruların cevapları bir sene öncesine kadar hayır, olamaz veya şu andaki sistemler bu denli özgürlüğü bize sağlamıyor türündendi.

Microsoft’un ASP’si ile veya PHP ile yapılan uygulamalar tam olarak insanların isteklerine cevap veremiyordu. Her ne kadar iyi ve gelişmiş web uygulamalarını bir yere kadar yapabiliyorduksa da belirli bir noktadan sonra C++,Delphi veya VB ile geliştirdiğimiz modülleri web uygulamamıza ekleyerek sorunlarımızı halletmeye çalışyorduk. Tabi bu tür yöntemler programın gelişme süresini uzatıyordu. Zamanın giderek önem kazandığı bir devirde haliyle programlarımızı da hızlı bir şekilde geliştirmemiz gerekiyor(du). Hızlı uygulama geliştirme(Rapid Application Development- RAD) geleneksel programlama araçlarıyla ve prgramcının yetenekleriyle çözüm bulunacak bir mesele değil. Artık programlama dilleri, dille birlikte gelen kütüphaneler ve bunlar hakkındaki dokümantasyonları ile birlikte değerlendiriliyor.

.NET ile birlikte programcının hizmetine sunulan 3400′den fazla sınıf, modern anlamda çok güzel bir geliştirme ortamı sunuyor. Bu sayede programlamları daha hızlı bir şekilde geliştirme imkanına sahip bulunuyoruz. .NET kullanarak yazdığımız ASP.NET, Windows Forms veya mobil cihazlar için geliştirdiğimiz bir uygulamayı birinden diğerine dönüştürmek işi çok kolay bir şekilde yapılabiliniyor. Bu sayede aynı anda hem windows hem de web uygulamaları geliştirmek çok hoşunuza gidecektir :-).

.NET framework’unun bize sunduğu diğer güzel bir özellik ise platform bağımsızlığıdır. Artık yazdığınız Windows uygulamaları sadece Windows yüklü sistemlerde değil, .NET framework’unun kurulu olduğu tüm platformlarda çalışabilecektir. Her ne kadar şimdilik bu alt yapının sadece Windows versiyonuna sahip olsak da Linux grupları tarafından bu alt yapının Linux versiyonunu çıkartma yönündeki çabalar uzun bir süredir devam etmektedir.

Peki bunca hoş özellikleri bize sağlayan .NET alt yapısında program yazarken hangi dili veya dilleri kullanmak zorundayız? Bu konuda Microsoft çok radikal bir karar alarak gelecek için hazırlanmış yeni alt yapıda Common Language Runtime (CLR) ile uyumlu her .NET dilini kullanmamıza olanak sağlıyor. .NET ile gelen SDK’da C#,VB.NET ve Js.NET kullanarak program yazabiliyoruz. Diğer taraftan 30′un üzerinde programlama diliyle .NET uygulaması geliştirebilirsiniz.

CLR denen şey tam olarak nedir? .NET altyapısında programların çalışmasını kontrol eden ve işletim sistemi ile programımız arasında yer alan arabirimdir. Normalde yazdığımız programlar derlenirken makine diline çevrilirdi ve program bu şekilde işletim sistemi ile direkt bağlantı kurarak çalışırdı. Fakat platform bağımsız bir geliştirme ve yürütme ortamı istiyorsanız ne olacak? İşte tam bu anda CLR devreye girer ve .NET programlarını farklı platformlarda makineye ve işletim sistemine göre programımızı çalıştırır. Normalde bir Windows, Linux veya MACOS kurulu sistemler aynı programın kodunu çalıştıramazlar. Bu platformlar için programın ayrı ayrı yazılıp, onlara göre hazırlanmış derleyicilerde derlenmesi gerekir. Dünyada çok sayıda yaygın platform olduğunu düşünürsek, bunların herbiri için ayrı ayrı derleme işlemini tek bir işletim sisteminde yapmamız imkansız gibidir. Bu durumda çözüm , ortak bir aradil kullanmak ve herbir platform için bu aradile çevrilmiş programın kodunu çalıştıracak  altyapıları hazırlamaktır.

Şimdi şu soruya sıra geldi: “İyi de .NET hangi aradili kullanıyor?” Sorumuzun cevabı MSIL(Microsoft intermediate Language) .NET platfomunda hangi dili kullanırsak kullanalım yazdığımız programın kodu direkt olarak makine diline değil de MSIL’e çevrilir. Bu sadece programı çalıştırdığımız sistemde kurulu olan CLR çalışma anında MSIL kodlarını çevirerek programımızı çalıştırır, çalışma anında derleme işlemini ise JIT derleyicileri (Just in Time compilers) üstlenir.

Gelecek makalemizde JIT’ler, MSIL language, CTS (Common Type System) gibi daha teknik konuları detaylı olarak ele almayı düşünüyorum. Sizlere kolaylıklar dilerim.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.NET’in CLR, CTS ve JIT derleyicileri

 

Önceki yazımızda “dot NET” platformu konusuna giriş yapmıştık.(Yazıyı okumak için tıklayın) Burada ise daha detaylı olarak .NET kavramlarını inceleyeceğiz ve .NET’le Java’nın karşılaştırıldığı bir testin sonuçlarına yer vereceğiz.

.NET platformunda istediğimiz programlama dili ile program yazabileceğimizi önceki yazımızda söylemiştik. Bunun için tek şart, kullandığımız dilin .NET için yazılmış olan bir derleyicisine ihtiyacımız olduğudur. .NET uyumlu programlama dili oluştururken belirli standartlara uyulması gerekir. Bu standartlar CLS (Common Language Specifications – Dillerin ortak özellikleri) ile belirlenmiştir. CTS(Common Type System) ise veri tipleri, nesneler, arayüzler ve programlama dillerine ait özellikleri tanımlar ve CLS’in bir parçası olarak karşımıza çıkar. CLS’de tanımlanmış kurallara uymak şartı ile istersek kendi programlama dilimizi dahi geliştirebiliriz veya herhangi bir dili .NET platformunda uygulama geliştirmek üzere değiştirebiliriz.

CLR ,programlarımızı değişik şekilde derleyebilir. Varsayılan derleme türü JIT(Just IN TIME- çalışam anında derleme) ‘dır. Program çalışırken daha önce derlenmemiş bir parçasına gelince hemen o kısmı da derler ve bunu hafızda chach’e koyar. Tekrar aynı program parçasını çalıştırmak gerekirse burayı hafızadan çalıştırır. Eğer RAM ‘imizi yeteri kadar büyükse, programın tamamı derlenmiş ve hafızada depolanmış durumda olabilir. Bu durumda programımız çok hızlı çalışır.

Hafızamızın yeteri kadar büyük olmadığı durumlarda EconoJIT (Ekonomik JIT) derleyicisini kullanabiliriz. Bu derleyici ile programın derlenmiş kısımları hafızada depolanmaz ve her seferinde aynı program parçası derlenir. Tabi ki bu derleyici normal JIT’e göre programlarımızı daha yavaş çalıştırır. Ama RAM ‘imizi çok daha az kullanır.

CLR ile gelen üçüncü derleyicimiz PreJIT(ön JIT derleyicisi) ise derleme işini program çalışmadan önce yapar ve tüm makine kodlarını bir yerde saklar. Çalışma anında çok hızlı olan programımız diğer JIT derleyicileriyle derlenmiş olanlara nazaran çok hızlı çalışır.

Kolayca görebileceğimiz birkaç noktaya da parmak basmak istiyorum. .NET ile yazdığınız programlar diğerlerine göre yavaş çalışır. Çünkü iki defa derleme aşamasından geçerler, program kodu MSIL’ye, MSIL ise makine koduna çevrilir. Diğer taraftan .NET ile programlarımız platform bağımsız olacak, .NET uyumlu herhangi bir dil ile program geliştirebileceğiz ve programımız CLR altında daha güvenli bir şekilde çalışacaktır.

.NET perfromans testi linkindeki sonuçlara göre : Genelde C# Java’dan 3.30 kat daha hızlı. C# Visual C++ 6.0′dan ise 3.11 kat daha hızlı çalışıyor. Hatta VB.NET kodu VB 6.0′a nazaran 46.45 kat daha hızlı çalışıyor. :-)

 

 

 

 

 

 

 

 

 

 

 

Visual C# ile Programlamaya Giriş

Visual C#, Visual Studio ailesinin yeni üyesidir, bu yeni dil c ve c++ temelleri üzerine kurulmasına rağmen komponent temelli programlama tekniğini geliştirmek için birtakım yeni özellikler eklenmiştir. C# dilinin sentaksı C ve C++ programcılarına çok tanıdık gelecektir. Bundan şüpheniz olmasın.

Genel Açıklamalar

Bu yazıda göreceğimiz basit uygulamada QuickSort algoritmasını kullanarak nasıl basit bir C# projesinin oluşturulduğunu göreceğiz. Bu uygulamada bir c# programında en sık kullanılan yapılardan olan dosyaya ve console ekranına okuma/yazma, fonksiyon oluşturma ve basit dizilerin kullanımı açıklanacaktır.

Bu yazı kesinlikle C# dilinin tüm özelliklerinin anlatıldığı yazı değildir. Bu yazı C# dilini öğrenmek için sizlere bir başlangıç noktası sunar.

Önerilen Kaynaklar

Visual Studio.NET (Beta 2 veya sonrası) örnek kaynak kodu derlemeniz için gereklidir. C/C++ bilgisi size bu yazıyı anlamanızda yardımcı olabilir ama gerekli değildir.

Adım 1. Projeye Başlama

Visual Studio ile program geliştirme organizasyonu solution(çözüm) çalışma alanları üzerindendir. Solution dediğimiz ortam bir veya daha fazla projeyi içerebilir. Bu makale için tek bir C# projesi içeren bir solution oluşturacağız.

Yeni bir proje oluşturmak

  1. Visual Studio.NET ortamından, File | New | Project menülerini seçin.

 

  1. Soldan(Project Types) Visual C#, sağdan(Templates) ise Console Application butonlarını seçin.

 

  1. Projenizin adını belirleyin ve projenizin hangi klasörde saklanacağını belirleyin.Bu klasör Visual Studio tarafından otomatik oluşturulur.Proje adı olarak ben quicksort yazıyorum.Siz istediğiniz adı verebilirsiniz.

 

  1. OK tuşuna basalım ve yola koyulalım.

“Visual C# Solution” ortamımız

Visual Studio.NET içinde bir Visual C# projesi bulunan bir solution oluşturdu. Proje assemblyinfo.cs ve class1.cs adlı iki tane dosya içermektedir.

Bundan sonraki adımlarda projemizi nasıl derleyeceğimizi ve bu iki dosya hakkında detaylı bilgiyi öğreneceğiz.

Adım 2. Hello, World!

Kusura bakmayın ama geleneği bozmadan ilk defa C programlama dili ile yazılmış olan “Hello, World!” programını c# ile yazacağız. Bu bir gelenektir ve her yeni bir dili öğrenmeye başladığınızda bunu siz de göreceksiniz.

Kaynak Kodu Değiştirme

  1. Solution Explorer ‘da bulunan ‘class1.cs’dosyasına çift tıklayın. Solution Explorer ‘ı göremiyorsanız, view menüsünü kullanarak görünür hale getirebilirsiniz.
  2. Şablonla oluşturulmuş koda aşağıda kırmızı ile yazılmış kısmı ekleyin (class1.cs).

using System;

namespace quicksort
{
    ///
    /// Summary description for Class1.
    ///
    class Class1
    {
        static void Main(string[] args)
        {
            //
            // TODO: Add code to start application here
            //
            Console.WriteLine (“Hello, C#.NET World!”);
        }
    }
}

  1. Dikkat edin siz kodunuzu yazdıkça Visual Studio size sınıflar ve fonksiyon adları hakkında bilgi verir, çünkü .NET Framework tip bilgisini yayınlamaktadır.

 

 

Uygulamamızı Derleyelim

  1. Programımızda değişiklik yaptığımıza göre artık Build menüsünden Build ‘ı seçerek programımızı derleyebiliriz.

 

  1. Hata ve mesajlar en altta bulunan “Output Window” denilen pencerede görünür. Eğer herhangi bir hata yoksa uygulamamızı Debug menüsü altında bulunan ‘Start without Debugging’ menüsüne tıklayarak çalıştırabiliriz.

 

Programımızın Çıktısı

Aşağıda programımızın Visual C# içinden çalıştırılarak oluşturulmuş çıktısının ekran görüntüsü mevcuttur.

 

Değişiklikleri Anlamak

System.Console sınıfına ait WriteLine() fonksiyonu kendisine argüman olarak gönderilen dizgeyi sonuna satır sonu karakteri de ekleyerek ekrana yazar.
Bu fonksiyon integer ve floating-point gibi diğer veri tiplerini de argüman olarak alabilir.

Program belleğe yüklendiğinde programın kontrolu Main() fonksiyonuna gelir.WriteLine() fonksiyonunu oraya yazmamızın sebebi budur.

Adım 3. Programın Yapısı

Şimdi basit bir Hello World uygulaması geliştirmiş olduk, şimdi de bir Visual C# uygulamasının basit componentlerini inceleyelim.

Kaynak Kod Yorumları

// karakterlerinden sonra gelen ve satırın sonuna kadar olan sözcükler yorum satırlarıdır ve C# derleyicisi tarafından görünmezler. Aynı zamanda birden fazla satıra yorum eklemek istiyorsak /* */ karakterleri arasına yorum yazarız.

// Bu satır derleyici tarafından görülmez
/* Aynı zamanda bu blok da
derleyici tarafından görünmez*/

Using Komutu

.NET Framework geliştiricilere yüzlerce yararlı sınıflar sunar. Mesela, Console sınıfı, console ekranına ait girdi ve çıktıları işler. Bu sınıflar hiyerarşik bir ağaç içinde organize edilmiştir. Aslında Console sınıfının tam ismi System.Console ‘ dur. Diğer sınıflar ise System.IO.FileStream ve System.Collections.Queue. içindedirler.

using komutu bize sınıfın ismini namespace(isim alanı) kullanmadan kullanabilmemizi sağlar.
Aşağıda kırmızı ile yazılan yazılar using komutunun uygulamasının sonucudur.

using System;
class Class1
{
    static void Main(string[] args)
    {
        System.Console.WriteLine (“Hello, C#.NET World!”);
        Console.WriteLine (“Hello, C#.NET World!”);
    }
}

Sınıf Bildirimi

C++ ve Visual Basic ‘den farklı olarak C# ‘da bütün fonksiyonlar bir sınıf içerisinde olmalıdır. C# ‘da bir sınıf tanımlamak için class anahtar sözcüğü kullanılır.Bu durumda bizim uygulamamızda, Class1 sınıfı Main() adında bir fonksiyon içerir. Eğer sınıf bildirimini bir isim alanı blokları içine alırsak sınıflarımızı CSharp.QuickSortApp şeklinde bir hiyerarşi içine alabiliriz.

Sınıflar hakkında çok derin bir bilgi vermeyi düşünmüyorum.Fakat bizim örneğimizin neden bir parçası olduğunu açıklamakta fayda gördüm.

Main() Fonksiyonu

Program belleğe yüklendiğinde Main() fonksiyonu programın kontrolünü eline alır, bu yüzden başlangıç kodlarımızı daima Main() fonksiyonu içinde yazmalıyız. Komut satırı argümanları ise bir string dizisi olan args dizisine aktarılır.(mesela: delete x ) Burada programımızın adı delete ise x bir komut satırı argümanıdır.

Adım 4. Console Girişi

Şimdi işlemlerimize bir QuickSrot uygulaması geliştirerek devam edelim. İlk yapmamız gereken kullanıcya hedef ve kaynak dosyasının isimlerini sormak olacaktır.

Source Code Modifications

  1. class1.cs dosyasına aşağıda kırmızı ile yazılanları yazın. Burada sınıf ismi ve isimalanı ismi bizim için çok önemli değildir.

// namespaces ekleme
using System;

// namespace tanımlama
namespace MsdnAA
{
    // uygulama sınıfı tanımlama
    class QuickSortApp
    {
        // uygulama oluşturma
        static void Main (string[] szArgs)
        {
            // Programın hakkında
            Console.WriteLine (“QuickSort C#.NET Sample Application\n”);

            // kullanıcıdan bilgi alma
            Console.Write (“Source: “);
            string szSrcFile = Console.ReadLine ();
            Console.Write (“Output: “);
            string szDestFile = Console.ReadLine ();
        }
    }
}

Console’dan Okuma

Console sınıfının ReadLine() metodu kullanıcıya bir giriş ekranı sunar ve geriye kullanıcının girdiği dizgeyi(string) geri döndürür.Bu metod bellek tahsisatını otomatik olarak kendi içinde yapmaktadır ve .NET garbage collector mekanizması sayesinde iade etmeniz gereken herhangi bir alan yoktur.

Program Çıktısı

Programı Debug | Start Without Debugging menülerini kullanarak çalıştırın.
Aşağıda programımızın son halinin çıktısını görüyorsunuz.

Adım 5. Dizilerin Kullanımı

Programımız sıralama yapmadan önce girişten satırları alarak bir dizi içinde saklaması gerekir. Şimdi .NET temel sınıflarından olan ArrayList sınıfını inceleyeceğiz.

Kaynak Kod Değişikliği

  1. class1.cs dosyası içinde aşağıda kırmızı ile gösterilen yerleri ekleyin.

// isim alanı ekleme
using System;
using System.Collections;

// isimalanı tanımlama
namespace c#nedircom
{
    // uygulama sınıfı tanımlama
    class QuickSortApp
    {
        // uygulama başlangıcı
        static void Main (string[] szArgs)
        {
           
            Console.WriteLine (“QuickSort C#.NET Sample Application\n”);

            // Dosya isimlerini almak için komut yaz
            Console.Write (“Source: “);
            string szSrcFile = Console.ReadLine ();
            Console.Write (“Output: “);
            string szDestFile = Console.ReadLine ();

            // TODO: Read contents of source file
            ArrayList szContents = new ArrayList ();
        }
    }
}

ArrayList sınıfının kullanımı

ArrayList sınıfına direkt ulaşabilmek için System.Collections isimalanını projemize using komutuyla ekliyoruz. Bu sınıf dinamik olarak büyüyüp küçülebilen nesne dizileri için kullanılır. Yeni bir eleman eklemek için basit bir şekilde Add() metodunu kullanabilirsiniz. Bu diziye eklenen yeni eleman orijinal nesne için referans olarak kullanılır, ve garbage collector alan iadesi için hazır olacaktır.

string szElement = “insert-me”;
ArrayList szArray = new ArrayList ();
szArray.Add (szElement);

Dizinin var olan bir elemanına ulaşabilmek için, diziye ait Item() metoduna ulaşmak istediğimiz elemanın sıra(index) numarasını geçebiliriz.Kısaca [] operatörlerini kullanarak da istediğimiz elemana Item() metodunu kullanmadan da ulaşabiliriz.

Console.WriteLine (szArray[2]);
Console.WriteLine (szArray.Item (2));

ArrayList sınıfının daha birçok metodu vardır, ancak biz bu uygulamada sadece ekleme ve okuma yapacağız. ArrayList sınıfına ait tüm metod ve özellikleri öğrenmek için MSDN kitaplığına başvurabilirsiniz.

Adım 6. File Girdi/Çıktı(Input/Output)

Şimdi isterseniz dosyadan okuma ve dosyaya yazma işlemlerini gerçekleştirelim. Dosyadaki her satırı okuyup, bir string dizisinin her elemanını bir satır gelecek şekilde ekleyeceğiz.Sonraki aşamada ise QuickSort algoritmasını kullanarak diziyi sıralı bir şekilde yazacağız.

Kaynak Kod Değişikliği

  1. class1.cs dosyasına aşağıda kırmızı ile yazılanları yazın. Burada sınıf ismi ve isimalanı ismi bizim için çok önemli değildir.

// isimalanı ekleme
using System;
using System.Collections;
using System.IO;

namespace MsdnAA
{

    class QuickSortApp
    {

        static void Main (string[] szArgs)
        {
            string szSrcLine;
            ArrayList szContents = new ArrayList ();
            FileStream fsInput = new FileStream (szSrcFile, FileMode.Open,FileAccess.Read);
            StreamReader srInput = new StreamReader (fsInput);
            while ((szSrcLine = srInput.ReadLine ()) != null)
            {
                // dizinin sonuna ekleme 
                szContents.Add (szSrcLine);
            }
            srInput.Close ();
            fsInput.Close ();

            // TODO: Buraya QuickSort fonksiyonu gelecek

            // sıraları satırları yazma
            FileStream fsOutput = new FileStream (szDestFile,FileMode.Create, FileAccess.Write);
            StreamWriter srOutput = new StreamWriter (fsOutput);
            for (int nIndex = 0; nIndex < szContents.Count; nIndex++)
            {
                // hedef dosyaya satır yazma
                srOutput.WriteLine (szContents[nIndex]);
            }
            srOutput.Close ();
            fsOutput.Close ();

            // başarıyı kullanıcıya bildirme
            Console.WriteLine (“\nThe sorted lines have been written.\n\n”);
        }
    }
}

Kaynak Dosyadan Okuma

Kaynak dosyayı açmak için FileStream sınıfını ve StreamReader sınıfını kullanarak ReadLine() metodu ile dosyayı okuyoruz. ReadLine() metodunu dosyanın sonunu ifade eden NULL değerine geri dönene kadar çağırıyoruz.Döngü içinde okunan satırları dizinin içine ekliyoruz ve sonrada tüm nesneleri kapatıyoruz.

 

Hedef Dosyaya Yazma

Dosyaya yazarken dizinin sıralanmış olduğunu varsaydık ve öyle devam ettik. Aynı şeklide FileStream nesnesini ve StreamWriter sınıfını kullanarak hedef dosyaya yazma işlemini yaptık.

Adım 7. Fonksiyon Yaratma

Son aşamada diziyi QuickSort algoritması ile sıralayan fonksiyonu yazmaya geldi. Bu fonksiyonu uygulamamızın ana sınıfının içine koyacağız.

Kaynak Kod Değişikliği

  1. class1.cs dosyasına aşağıda kırmızı ile yazılanları yazın. Burada sınıf ismi ve isimalanı ismi bizim için çok önemli değildir.

// isim alanı ekleme
using System;
using System.Collections;
using System.IO;

namespace c#nedircom
{

    class QuickSortApp
    {

        static void Main (string[] szArgs)
        {
            … … …

            // QuickSort fonksiyonuna parametrelerin geçişi
            QuickSort (szContents, 0, szContents.Count – 1);

            … … …
        }

        // QuickSort fonksiyonu
        static void QuickSort (ArrayList szArray, int nLower, int nUpper)
        {

            if (nLower < nUpper)
            {
                // Ayırma ve sıralama işlemi
                int nSplit = Partition (szArray, nLower, nUpper);
                QuickSort (szArray, nLower, nSplit – 1);
                QuickSort (szArray, nSplit + 1, nUpper);
            }
        }

        // QuickSort bölmelere ayırma
        static int Partition (ArrayList szArray, int nLower, int nUpper)
        {
            // İlk elemanı bulma
            int nLeft = nLower + 1;
            string szPivot = (string) szArray[nLower];
            int nRight = nUpper;

            // Dizi elemanlarını bölme
            string szSwap;
            while (nLeft <= nRight)
            {
               
                while (nLeft <= nRight)
                {
                    if (((string) szArray[nLeft]).CompareTo (szPivot) > 0)
                        break;
                    nLeft = nLeft + 1;
                }
                while (nLeft <= nRight)
                {
                    if (((string) szArray[nRight]).CompareTo (szPivot) <= 0)
                        break;
                    nRight = nRight – 1;
                }

                // Eğer uygunsa yer değiştirme işlemi yap
                if (nLeft < nRight)
                {
                    szSwap = (string) szArray[nLeft];
                    szArray[nLeft] = szArray[nRight];
                    szArray[nRight] = szSwap;
                    nLeft = nLeft + 1;
                    nRight = nRight – 1;
                }
            }

            szSwap = (string) szArray[nLower];
            szArray[nLower] = szArray[nRight];
            szArray[nRight] = szSwap;
            return nRight;
        }
    }
}

QuickSort() Fonksiyonu

Bu fonksiyon alt sınır, üst sınır ve bir dizi olmak üzere 3 tane parametre almaktadır. QuickSort fonksiyonu Partition() fonksiyonunu çağırarak diziyi iki parçaya ayırır. Bu parçaların birinde belirlenen bir diziden önceki ,diğer parçasında ise sonraki elemanlar bulunur. Sonra fonksiyon tekrar kendini çağırarak bu iki parçanın sıralanmasını sağlar.

Yukarıdaki kodlarda yeni gördüğümüz metod CompareTo() metodudur. Bu metod iki string ifadesini karşılaştırır.

QuickSort Uygulamasını Çalıştırma

Bu adım uygulamamızın son adımı olacaktır.Şimdi programımızı derleyip çalıştırabiliriz. Programımızın çalışması için bir text dosyası oluşturmamız sıralama yapabilmek için gerekecek. Exe dosyasının bulunduğu dizini text dosyasını oluşturup programı çalıştıralım.

 

Programın Çıktısı

Aşağıda programımızı çalıştırdıktan sonraki ekran çıktısı mevcuttur. Yukarıdaki ekranda ise output.txt dosyasında meydana gelen değişiklikleri görebilirsiniz.

 

Adım 8. Debugger Kullanmak

Debugger aracı programımızın problemlerini çözmek için önemli ve gerekli bir araçtır. İyi bir başlangıç yaptığımıza göre son aşamada programımız içinde nasıl dolaşacağımıza ve QuickWatch’ ı nasıl kullanacağımıza bakalım.

Breakpoint’ leri Ayarlama

Program Debugger içinde çalışırken eğer breakpoint olan bir noktaya gelinirse program sonlandırılır ve debugger control ‘ü bizim elimize geçer. Herhangi bir satıra breakpoint koymak için ilgili satıra sağ tıklayıp aşağıdaki gibi Insert BreakPoint menüsüne tıklayın.

 

BreakPoint bulunan satırlar kırmızı ile gösterilir. BreakPoint ‘ i kaldırmak için ilgili satıra sağ tıklayıp Remove BreakPoint menüsünü seçin.

Program içinde Adım Adım ilerlemek

Aşağıdaki şekilde görüldüğü gibi bir breakpoint oluşturduktan sonra debugger ile programımızı çalıştıralım. Debug menüsünden daha önceden de yaptığımızı gibi Start Without Debugging yerine Start menüsüne tıklayın. Bu şekilde programı çalıştırdığımızda program debugger ile çalışmaya başlayacaktır, ve breakpoint ‘ler aktif olmaya başlayacaktır.

Program breakpoint ‘in olduğu noktaya geldiğinde, debugger programın kontrolünü alır. Aşağıdaki şekilde görüldüğü gibi sarı okla programın geldiği nokta gösterilir.

 

Kod içinde adım adım ilerlemek için menü çubuğundan Debug | Step Over ‘ ı seçerek sarı okun hareketini izleyin. Debug | Step Into komutu gitmek istediğimiz fonksiyona gitmemizi sağlar. Aşağıda iki defa Step Over menüsünü seçtikten sonra kaynak kodumuzun görüntüsü mevcuttur.

 

Eğer programımızın diğer bir sonlandırıcı nedene (yeni bir breakpoint, exception , exit, debug) gelene kadar devam etmesini istiyorsanız Debug | Continue menülerini seçin.

Değişken Değerlerini Takip Etme

Debugger ‘ın kontrolü bizde iken farenin imlecini kaynak kodda istediğimiz değişken üzerine götürerek değişkenin o anki değerini öğrenebiliriz.

 

Aynı zamanda bir değişkene sağ tıklayarak QuickWatch menüsünü açabilirsiniz. QuickWatch ile değişken hakkında daha detaylı bilgiler elde edebilirsiniz. Mesela diziler hakkında aşağıdaki şekilde görüldüğü gibi bilgiler elde edilebilir.

 

Diğer Debugger Araçları

Visual Studio yukarıda bahsettiğimiz araçları dışında farklı araçlarda barındırır. Mesela Call Stack Wiever aracı ile o an hangi fonksiyonun çağrıldığı ile ilgili bilgiyi elde edebilirsiniz. Bellekteki değerleri ve bir prosesteki thread ‘leri de aynı anda görebileceğimiz araçlar mevcuttur.

 

Son Söz & Sonuç

Bu yazının amacı sizlere Visual Studio ile nasıl basit bir uygulamanın yapılacağını adım adım göstermekti. Diğer .NET ve C# kaynaklarını araştırmak için sizi cesaretlendirebildiysek ne mutlu bize. Bu yazıyı buraya kadar okuduğunuza göre en azından şu aşamada çalışan bir projeniz var, istediğiniz gibi üzerinde değişiklikler yapıp sonucu görebilirsiniz.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

C# ile Client/Server ve Socket programlamaya giriş

 

Bu makalemizde TCP protokolüyle basit bir Client/Server programı yapacağız, C# ile socket programlama yapabilmek için System.Net.Sockets isimalanı altında bulunan sınıfları kullanacağız. Yapacağımız programda server  bir console uygulaması, client ise windows formlarını kullanarak yapacağımız windows uygulaması olacak.Amacımız basit bir Client/Server çatisi kurmak olduğu için uygulamamız çok basit olacaktır. Siz yazının tamamını dikkatlice incelediğinizde ve yaratıcılığınızı kullandığınızda çok daha gelişmiş uygulamalar yapabilirsiniz. Belki bir sunucu tabanlı script dili bile geliştirebilirsiniz :).

şimdi yazacağımız programda kullanıcı Windows uygulaması vasıtası ile server olan programımıza bağlanacak. Form üzerinde bulunan butona tıkladığımızda yine form üzerinde bulunan textbox girişindeki yazıyı server programımız alacak ve yazıda kaç karakter olduğunu client programına gönderecek.Client program ise bir mesaj kutusu ile kullanıcıya bildirecek.Öncelikle client olan kullanıcıdan mesajın geldiğini düşünürek Server programımızı yazalım. Server programımızı yazmaya başlamadan önce programda Soket programlama için kullandığımız sınıflara ve onların üye fonksiyonlarına kullandığımız kadarıyla bir göz atalım.

:::: TcpListener Sınıfı(System.Net.Sockets) ::::

TcpListener sınıfı TCP protokolü ile çalışan servislere bağlanmamızı sağlar. Mesela HTTP ve FTP protokolleri TCP servislerini kullanırlar. TcpListener sınıfının kurucu fonksiyonunu 3 değişik şekilde çağırabiliriz.

1- )IPEndPoint sınıfını kullanarak IP numarası ve port numarası içeren bir bilgiyi kullanma yolu ile
2- )IP adresi ve port numarasını geçerek çağırma
3- )Sadece Port numarası ile çağırma.Bu durumda varsayılan ağ arayüzünüz TCP servislerini sağlayacaktır.

Biz bu programda 3. şıktaki gibi bir kullanımı tercih ettik.

public void Start();

TcpListener sınıfına ait bu metod network servislerinden ilgili port’u dinleyerek verileri almaya başlamamızı sağlar.

public Socket AcceptSocket();

TcpListener sınıfına ait bu metod veri transferi için geri dönüş değeri olarak bir Socket nesnesi döndürür.Bu geri dönen socket ilgili makinanın IP adresi ve port numarası ile kurulur.(kurucu işlev ile)

:::: Socket Sınıfı(System.Net.Sockets) ::::

Socket Sınıfı ile ilgili aşağıdaki örneği inceleyelim

Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream,ProtocolType.Tcp );

Socket sınıfının bu kurucu işlevi parametre olarak AdressFamily dedigimiz adresleme semasi Soket tipi ve kullanacagimiz protokol tipini alir. Bu 3 paremtere de .NET Framework class kütüphanesinde Enum sabitleri olarak tanimlanmistir.

Programimizda yazdigimiz “Socket IstemciSoketi = TcpDinleyicisi.AcceptSocket();” satiri ile geri dönen soket nesnesinde bu 3 parametrede tanimlanmistir.

public bool Connected();

Bu metod ile Soketin baglanip baglanmadigini geri dönen bool degeri ile anliyoruz.Eger soket hedef kaynaga bagliysa true degilse false degerine geri döner.


:::: NetworkStream Sinifi(System.Net.Sockets) ::::

NetworkStream sinifi kurucularindan olan “void NetworkStream(Socket x);” fonksiyonu ilgili kendisine gönderilen soket nesnesine ait datalari NetworkStream türünden nesnede tutar.bu programda kullandigimiz soket tipi stream oldugu için bu sinifi kullaniyoruz. NetworkStream sinifi içinde islem yapabilmemeiz için ise System.IO isiamalaninda bulunan StreamReader ve StreamWriter siniflarini kullanacagiz.

Ön bilgileri aldığımıza göre server programımızı yazalım. Aşağıdaki ilk kaynak kod server.cs dir. Satır aralarına size yardımcı olabilecek yorumlar ekledim.Kaynak dosyayı özellikle makaleme dosya olarak eklemiyorumki siz aşağıdaki kodları tek tek yazıp daha iyi öğrenin.

:::: TcpClient Sinifi(System.Net.Sockets) ::::

Tcp servislerine bağlantı sağlamak için TcPClient sınıfı kullanılır. Istemci programımızda TcpClient sınıfının <public TcpClient(string, int);> kurucu işlevini kullanıyoruz. İlk parametre bilgisayar adı ikincisi ise port numarasıdır.

public NetworkStream GetStream();

Bu metod ile belirtilen port tan gelen veriler bir NetworkStream nesnesine aktarılır. GetStream metodunun geri dönüş değeri NetworkStream olduğu için atama işlemini NetworkStream türünden bir nesneye yapmamız gerekir.

Not: Yeşil ile yazılan satırlar yorum satırlarıdır.Html formatında bir alt satıra inmiş olan yorum satırlarını copy&paste ile programınıza aktarırken o satırları tekrar tek satır haline getirmeyi unutmayın, aksi halde programınız derlenemez.
//Server.cs

using System; // bunu her zaman eklememiz lazim
using System.IO ; //StreamReader ve StreamWriter siniflari için
using System.Net.Sockets; // Socket, TcpListener ve NetworkStrem siniflari için

public class Server
{

    public static void Main()
    {

     //Bilgi alisverisi için bilgi almak istedigimiz port numarasini TcpListener sinifi ile gerçeklestiriyoruz

     TcpListener TcpDinleyicisi = new TcpListener(1234);
     TcpDinleyicisi.Start();

     Console.WriteLine(“Sunucu baslatildi…”) ;

     //Soket baglantimizi yapiyoruz.Bunu TcpListener sinifinin AcceptSocket metodu ile yaptigimiza dikkat edin
     Socket IstemciSoketi = TcpDinleyicisi.AcceptSocket();
     // Baglantının olup olmadığını kontrol ediyoruz
     if (!IstemciSoketi.Connected)
     {
         Console.WriteLine(“Sunucu baslatilamiyor…”) ;
     }
     else
     {
         //Sonsuz döngü sayesinde AgAkimini sürekli okuyoruz
         while(true)
         {
         Console.WriteLine(“Istemci baglantisi saglandi…”);

         //IstemciSoketi verilerini NetworkStream sinifi türünden nesneye aktariyoruz.
         NetworkStream AgAkimi = new NetworkStream(IstemciSoketi);

         //Soketteki bilgilerle islem yapabilmek için StreamReader ve StreamWriter siniflarini kullaniyoruz
         StreamWriter AkimYazici = new StreamWriter(AgAkimi);
         StreamReader AkimOkuyucu = new StreamReader(AgAkimi);
         //StreamReader ile String veri tipine aktarma islemi önceden bir hata olursa bunu handle etmek gerek
         try
         {
            string IstemciString = AkimOkuyucu.ReadLine();

            Console.WriteLine(“Gelen Bilgi:” + IstemciString);

            //Istemciden gelen bilginin uzunlugu hesaplaniyor
            int uzunluk = IstemciString.Length;

            //AgAkimina, AkimYazını ile IstemciString inin uzunluğunu yazıyoruz
            AkimYazici.WriteLine(uzunluk.ToString());

            AkimYazici.Flush() ;
          }
         
          catch
          {
             Console.WriteLine(“Sunucu kapatiliyor…”);
             return ;
          }
        }
      }

    IstemciSoketi.Close();
    Console.WriteLine(“Sunucu Kapatiliyor…”);
   }
}

İşte buda Istemci programımız. Öncelikle şunu belirtiyimki aşağıdaki kodların çoğunu Visual C# kendiliğinden hazırladı, o yüzden size Tavsiyem Visual C# kullanmanız. Öncelikle aşağıdaki şekilde gördüğünüz form yapısını benzer bir form hazırlayın.Sonra da buton_click metodunu form_kapatma metodunu ve using ifadelerini ekleyin. Yada zamanınız çoksa aşağıdaki kodları teker teker yazın. (İsteyene kaynak kodu da gönderebilirim)

//client.cs

using System;
using System.Net.Sockets;
using System.IO ;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

public class Form1 : System.Windows.Forms.Form
{
//Burda server da tanımladıklarımızdan farklı olarak TcpClient sınıfı ile serverdan gelen bilgileri alıyoruz
public TcpClient Istemci;
private NetworkStream AgAkimi;
private StreamReader AkimOkuyucu;
private StreamWriter AkimYazici;

private System.Windows.Forms.Button buton;
private System.Windows.Forms.TextBox textbox;

private System.ComponentModel.Container components = null;

public Form1()
{
   InitializeComponent();
}
protected override void Dispose( bool disposing )
{
   if( disposing )
   {
      if (components != null)
     {
      components.Dispose();
     }
   }
   base.Dispose( disposing );
}
private void InitializeComponent()
{
//Bu satırları Visual C# oluşturdu.
this.buton = new System.Windows.Forms.Button();
this.textbox = new System.Windows.Forms.TextBox();
this.SuspendLayout();

this.buton.Location = new System.Drawing.Point(8, 40);
this.buton.Name = “buton”;
this.buton.Size = new System.Drawing.Size(248, 23);
this.buton.TabIndex = 0;
this.buton.Text = “Sunucuya Baglan”;
this.buton.Click += new System.EventHandler(this.buton_Click);

this.textbox.Location = new System.Drawing.Point(8, 8);
this.textbox.Name = “textbox”;
this.textbox.Size = new System.Drawing.Size(248, 20);
this.textbox.TabIndex = 1;
this.textbox.Text = “Buraya Sunucuya göndereceginiz yaziyi yazin”;

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(264, 69);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.textbox,
this.buton});
this.MaximizeBox = false;
this.Name = “Form1″;
this.Text = “C#nedir?com”;
this.Closing += new System.ComponentModel.CancelEventHandler(this.form1_kapatma);
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}

//giriş noktamız olan mainde yeni bir form1 nesnesini çalıştırıyoruz
static void Main()
{
    Application.Run(new Form1());
}

//From1 yüklendiğinde TcpClient nesnesi oluşturup AgAkımından(NetworkStream) verileri okuyoruz
private void Form1_Load(object sender, System.EventArgs e)
{
    try
    {
        Istemci = new TcpClient(“localhost”, 1234);
    }
    catch
    {
        Console.WriteLine(“Baglanamadi”);
        return;
    }
//Server programında yaptıklarımızı burda da yapıyoruz.
    AgAkimi = Istemci.GetStream();
    AkimOkuyucu = new StreamReader(AgAkimi);
    AkimYazici = new StreamWriter(AgAkimi);
    }
}

private void buton_Click(object sender, System.EventArgs e)
{

//Kullanıcı butona her tıkladığında textbox’ta yazı yoksa uyarı veriyoruz
//Sonra AkimYazici vasıtası ile AgAkımına veriyi gönderip sunucudan gelen
//cevabı AkimOkuyucu ile alıp Mesaj la kullanıcıya gösteriyoruz
//Tabi olası hatalara karşı, Sunucuya bağlanmada hata oluştu mesajı veriyoruz.
   try
   {
       if (textbox.Text==””)
      {
         MessageBox.Show(“Lütfen bir yazi giriniz”,”Uyari”);
         textbox.Focus();
         return ;
      }

       string yazi;
       AkimYazici.WriteLine(textbox.Text);
       AkimYazici.Flush();
       yazi = AkimOkuyucu.ReadLine();
       MessageBox.Show(yazi,”Sunucudan Mesaj var”);
    }

    catch
    {
       MessageBox.Show(“Sunucuya baglanmada hata oldu…”);
    }
}

//TVe bütün oluşturduğumuz nesneleri form kapatıldığında kapatıyoruz.
public void form1_kapatma(object o , CancelEventArgs ec)
{
     try
     {
       AkimYazici.Close();
       AkimOkuyucu.Close();
       AgAkimi.Close();
      }

     catch
     {
       MessageBox.Show(“Düzgün kapatilamiyor”);
     }
}

Aşağıdaki server ve client programlarımızın aynı anda çalıştıkları sırada alınmış ekran görüntüleri mevcuttur.

Yazı hakkında sorularınızı bana sorabilirsiniz. Kaynak kodları özel bir istek geldiğinde buraya koyabilirim.

Yazar Hakkında

Hakkında: editor
Kimlik kartı

2 Cevaplar - “C#-CSharp Programlama Dili”

  1. cem yılmazın da dediği gibi içimizde.

    bilindiğiniz üzere c++ ve c# kod yazılışı aynıdır.

  2. c# komutları nerede acaba?

Bir Cevap Yaz

kendi isteğimle kurallara uygun yazıyorum. (Lütfen yandaki kutuyu işaretleyin.)

Otomatik robotlara karşı soru.