Oca102009

İncelemeler bölümü hakkında

Yazan : Zafer    10.01.2009 | İncelemeler

Merhaba,

Sitemde incelemeler adı altında açmış olduğum kategori hakkında açıklayıcı, kısa bir yazı yazmayı uygun gördüm. Öncelikle bu kategoriyle amacım; malum biz programcılar daha iyisini bulmak adına sürekli yazdığımız kodların daha iyisi nasıl olur diye merak ederiz. Bu sorunun cevabı basit değildir. Kaliteli kod yazmak zaman ve tecrübe gerektirir, uzun çalışmalar gerektirir. Tüm bunların yanında başka programcılar tarafından yazılmış kodların incelenmesi ve analiz edilmesini gerektirir.

Ben C/C++ dillerinde çok iyi değilim. Sitemde de zaten bir uzman olarak değil, bu işi öğrenen ve öğrendiği noktaları sizlerle paylaşmaya çalışan birisi olarak yazıyorum. Ben mümkün olduğunca iyi yazılmış kodları incelemeye çalışıyorum. Siteme açtığım bu bölüm sayesinde bu kodları ilgilenen diğer insanlarla irdelemek istedim. Hani ne derler "Bir elin nesi var, iki elin sesi var." misali bende olurya okuyupta ilgilenen arkadaşlara bir kaynak olur düşüncesiyle bu bölümü siteme eklemiş oldum.

Bu bölümde kod incelememiz hususunda kimse yanlış düşüncelere kapılmasın, amacım kesinlikle kimseyi yermek veya kırmak değil aksine kendimce uygun görmediğim noktaları belirterek bu örnek üzerinden belki ileride yanlışa düşecek arkadaşlara yardımcı olmak. Sonuçta hepimiz hata yaparız ama hatamızı görür ve nasıl düzeltildiğini öğrenmezsek hep aynı hatayı yapmaya mahkum kalırız. Umuyorum sizlerinde katkılarıyla bu bölüm çok güzel olacak. Hepinize sağlıklı ve mutlu günler dilerim.

Etiketler:

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Yorum

Oca102009

Stringi ters çeviren program incelemesi

Yazan : Zafer    10.01.2009 | İncelemeler

Lütfen okuyun : incelemeler bölümü hakkında

Merhaba,

Bu inceleme yazımızda programlama.com sitesinin C/C++ bölümüne Esra Kızılay tarafından eklenmiş olan "Bir Stringin ilk karakterinin adresini parametre olarak alan ve Stringi ters çeviren program" konulu programın örnek kodlarını incelemeye çalışacağız. Program konusundan da anlaşıldığı gibi kullanıcı tarafından girilen kelime katarını tersten yazdırıyor. Şimdi hep birlikte kodların içine dalıp, incelemeye başlayalım.

Genel olarak kodlamaya baktığımda ilk gözüme çarpan main() fonksiyonunun en sonda kullanıldığı kodlama stilinin benimsenmiş olduğu, bu stil geçerli olmakla birlikte ben tasvip etmiyorum, nedenine gelince bu kullanım tarzı fonksiyon prototiplerinin tanımlanma gereksinimini ortadan kaldırıyor. Ben fonksiyon prototiplerinin tanımlanması gerektiği görüşündeyim, sebebine gelince bu prototip bloğu aslında programda ne yapılmak istemiş hangi işleri hangi fonksiyonlar üstlenmiş gibi bilgileri bir çırpıda görüp incelememizi ve programı daha çabuk kavrayabilmemizi sağlıyor diye düşünüyorum.

char* dizi_olustur(char buffer[]){
     return (char*)malloc (sizeof(char)*strlen(buffer));
}

Yukarıdaki fonksiyondan başlarsak, char tipinde işaretçi döndüren bir fonksiyon tanımı görüyoruz. parametre olarak char tipinde bir parametre almakta. Parametre tanımına dikkat ederseniz, geçerli ve kullanılabilen bir yapı ama benim daha çok beğendiğim ve bence gözede hoş gelen "char buffer[]" yerine "char *buffer" yapısı kullanılabilirdi. Benimde tercihim bu yönde olurdu. Bunun dışında bildiğiniz üzere malloc() fonksiyonunun  dönüş değeri void* yani tipsiz bir işaretçidir. Biz bu işaretçiyi yapımıza uygun tipe çevirerek kullanırız.

(char*)malloc (sizeof(char)*strlen(buffer));

Kullanıma baktığımız zaman, malloc() fonksiyonundan dönen degerin bir char* olduğu özellikle belirtilmiş bence bu çevrimede dikkat etmeli ve uygulamalarımızda bunu kullanmaya dikkat etmeliyiz diye düşünüyorum.

void ters_cevir(char* dizi){

     printf("\n Dizinin Boyu=%d \n \n ",strlen(dizi));
     char temp;
     int length=strlen(dizi);

     for(int i=0;i<length/2;i++){
         temp=dizi[i];
         dizi[i]=dizi[length-1-i];
         dizi[length-1-i]=temp;
     }
     printf("\n %s \n",dizi);
}

ters_cevir() fonksiyonunda ilk dikkatimi çeken değişken tanımlarının üstünde yer alan printf() fonksiyonu oldu. Değişkenleri etki alanın en başında tanımlamak yani bir fonksiyon içinde kullanılacaksa fonksiyona girer girmez değişken tanımlamalarını yapıp ardından işlemlere geçmek hem daha okunaklı hemde daha hoş bir görüntü sağlıyor düşüncesindeyim. İkinci bir konu değişkenlere ilk değer atama, burada temp için bir değer ataması yapılmamış. length değişkeni için değer atanmış ama bir satır aşağıdaki for döngüsünün karar yapısına bakarsanız length değişkeni her defasında ikiye bölünüp kullanılmış bunun yerine atama sırasında bu bölme işlemi yapılabilirdi.

     for(int i=0;i<length/2;i++){
         temp=dizi[i];
         dizi[i]=dizi[length-1-i];
         dizi[length-1-i]=temp;
     }

Algoritmaya bakacak olursak bence basit ve güzel bir algoritma, Baştaki herbir degerin karşılığı olan sondaki deger ile yerleri değiştiririyor. N boyutlu bir dizi için işlem N/2 defa tekrarlanarak sonuca ulaşılmakta, algoritma hoş ve başarılı bir şekilde kodlanmış zaten.

int main(){
           char buffer [250];
           char* dizi;

           printf(" \n Bir String giriniz...\n \n");

           gets(buffer);

           dizi=dizi_olustur(buffer);

           strcpy(dizi,buffer);

           ters_cevir(dizi);

           getch();
           return 0;
}

main() fonksiyonu genel olarak iyi görünüyor. İçinde çok karışık işlemlere yer verilmemiş ve işleri gerçekleştiren fonksiyonlara çağrıları içerecek şekilde yapılandırılmış bence güzel görünüyor.

Böylece yazımızın sonuna geldik. Bu tür incelemelere ilerleyen yazılarımda da yer vermeyi düşünüyorum. Sizlerinde incelenmesini istediğiniz ve çok büyük boyutlu olmayan kodlarınız varsa ve göndermek isterseniz memnuniyetle kabul ederim. Hepinize iyi çalışmalar.

Etiketler: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 1 Yorum