18
Oca

Aşağıdaki kodu derleyip çalıştırdığınızda çıktı ne olur?

#include <stdio.h>

#define f(x) x*3

int main() {
    int y = f(1 + 2);

    printf("y = %d\n", y);

    return 0;
}

y = 9 diyenler yanılıyor. f bir makro olduğu için kod derlenmeden önce aşağıdaki hale getiriliyor pre-processor tarafından:

...

int main() {
    int y = 1 + 2 * 3;

    printf("y = %d\n", y);

    return 0;
}

Çarpma işlemi, toplamaya göre öncelikli olduğundan (2 * 3) + 1 işlemi 7 sonucunu veriyor:

$ gcc -o test test.c
$ ./test
y = 7

Makroları bilerek kullanmak gerekiyor, ezberlemeden.

7
Haz

 Arama algoritmalarımıza yatay arama (bfs) ile devam ediyoruz.

Yatay arama derinlemesine aramadan farklı çalışır. Bir düğüme girdiğinde en uç noktaya varıncaya kadar gitmektense aynı dereceli diğer terimlere bakar. Bu işlemi nasıl yaptığını merak etmiştim. Meğerse kuyruk kullanılıyormuş. Kuyruk dediğimiz şey bir tür veri dizisi. Bu veri dizisine veriler en sona eklenir, veriler alınırken ilk baştaki veriden itibaren alınır. bfs algoritmasında her düğümün bağlı olduğu diğer düğümler kuyruğa eklenir ve kuyruktan alınan verilerde bfs tekrarlanır. Koda gelecek olursak:


//bfs.c 

#include <stdio.h>
int tablo[10][10];
int kuyruk[10];
int iz[10];
int aranan=6; //aranan düğüm
int bulundu=0;

// kuyruğa veri ekle
void ekle(int n)
{
    iz[n]=1;
    static int son=0;   //kuyruğun en sonu
    kuyruk[son]=n;
    son++;
    printf("%d Arama kuyruğuna eklendi!\n",n);
}

//kuyruktan veri al
int al()
{
    static int bas=0;   //kuyruğun en başı
    return kuyruk[bas++];
}

void bfs(int gel)
{
     printf("Giriliyor: %d\n",gel);
     int i;
     for(i=0;i<10;i++){
         if(!iz[i] && tablo[gel][i])
         {
             if(i==aranan)
             {
                 printf("Aranan %d bulundu!\n",i);
                 bulundu=1;
                 break;
             }
             else ekle(i);
         }
     }
}
int main()
{
    tablo[0][1]=tablo[1][0]=tablo[0][2]=tablo[2][0]=tablo[1][3]=tablo[3][1]=tablo[3][2]=tablo[2][3]=tablo[3][4]=tablo[4][3]=1;
    tablo[3][5]=tablo[5][3]=tablo[5][6]=tablo[6][5]=1;
    int i;
    while(!bulundu){
        iz[0]=1;
        bfs(al());

        }
     
    getch();
    return 0;
 
}

Programda her düğüme girerken neden “Giriliyor…” yazdırdığımı merak ediyorsanız, çok önemli bir sebebi yok. Sebebi hata korkusu. Ben de yeni başladığım için yanlış yazmış olabilirim. Bu şekilde hangi düğümlere girdiğini biliyorum ve programın doğru çalıştığından emin olabiliyorum.


19
May

Bu aralar python yerine C’ye çalışmayı düşündüm. Sonra Halil’e “Bana C öğretsene, Python çok yavaş” dedim tabii o da kabul etti. İlk olarak bazı algoritmaları öğretti. Bunlar arama algoritmaları. Ben de ilk olarak dfs’i yazdım.

Dfs’in ne olduğuna gelince: “Derinlemesine arama” demek oluyor. Yani düğümlerden birine girdiğinizde aramaya ona bağlı düğümlerden devam ediyorsunuz. Eğer düğümler çıkmaza girerse o zaman geri dönüp hemen yanındaki düğüme geçiyorsunuz. Kod şöyle:

#include<stdio.h>

int tablo[1000][1000];
int n=7;
int aranan=6;
int iz[1000];

void dfs(int gel){
    int i;
    iz[gel]=1;
    for(i=0;i<n;i++)
    {
        if(!iz[i] && tablo[gel][i])
        {
            printf("Giriliyor: %d \n",i);
            if(i==aranan)
            {
                printf("Aranan %d Bulundu\n",i);
                break;
            }
            else dfs(i);
        }
    }
    printf("Çıkılıyor: %d\n",gel);
}

int main(){
    tablo[0][1]=tablo[1][0]=tablo[0][2]=tablo[2][0]=tablo[1][3]=tablo[3][1]=tablo[3][2]=tablo[2][3]=tablo[3][4]=tablo[4][3]=1;
    tablo[3][5]=tablo[5][3]=tablo[5][6]=tablo[6][5]=1;
    dfs(0);
    printf("Arayan Bulur!\n");
    return 0;
}


Düğümleri oluştururken bir tablo oluşturup eğer düğümler arasında bağ varsa tablonun o sayıların kesişimine gelen elemanını (yani eğer 4, 2′ye bağlıysa tablo[4][2]=tablo[2][4]=1) 1 yapıyorsunuz. Tablo simetrik olmalı, çünkü mesela 4 2′ye bağlıysa 2 de 4′e bağlıdır. Bu değerleri bir girdi dosyasından da okuyabilirsiniz ama ben basit olması için programda elle girmiş oldum. Bunu yazdıktan sonra Halil “Bir de şey yaz sen: iki düğüm alsın kullanıcıdan, birinden diğerine gidilip gidilemeyeceğini göstersin.” Ama ben uğraşmadım. Bu algoritmadan sonra da bfs yazmaya çalışacağım. Yazdığım zaman onu da buraya korum. Hepinize iyi günler.


4
Nis

C programlama dili ile en basit programımızı ornek.c adı ile “Merhaba Dunya” yı yazalım:

 #include 

int main() {printf("Merhaba Dunya") ;return 0;}

Bu program konsola “Merhaba Dunya” yazdırır. Linux’ta bunu nasıl yacağınıza ve nasıl derleyeceğinize bakalım. Ubuntu veya Pardus’ta bunu deneyebilirsiniz. Derleme komutları genel linux komutları içerisine girdiği için her ikisinde de çalışacaktır.

Ubuntu’da Uygulamalar menüsünden Metin Düzenleyici ile kodları bir metin belgesine yazabilirsiniz. Ben Metin Düzenleyici’yi çok beğeniyorum. Bunun Windows’daki karşılığı Notepad++ programı oluyor. Ya da Sistem menüsünden Yönetim’e gelin ve açılan menüdeki Synaptic programı ile Kate yükleyebilirsiniz. Kate de gayet hoş bir program editleme yazılımı. Sadece C değil, bir çok programlama dilini algılayabiliyor ve o programın özelliklerine göre renklendirme yapıyor.

Siz C programlama dili ile yazdığımız kodları kaydederken uzantısı .c olsun, ayrıca Türkçe karakter kullanmamaya özen gösterin. Örneğin ornek.c gibi. Bu yazdığımız kodları, daha sonra açtığımız Uçbirin (=Konsol=Teminal) ile derleyeceğiz.

Ya da hem kod yazalım hem de bunları derleyen bir program kullanmak istersek NetBeans tam bize göre. Ubuntu’da programlar geç güncellendiği için ben Netbeans’i internetten indirmeyi tercih ediyorum. http://netbeans.org/ sitesini ziyaret etmenizi öneririm.

Bu yazıyı yazdığım sırada en güncel Netbeans sürümü 6.8 olduğu için onu indirdim. İndireceğiniz Netbeans’ı şu sayfadan seçeceksiniz. Eğer pratik olsun, hemen insin isterseniz sadece C/C++ derleyicisi olarak kullanılan sürümü (30 MB olarak görünüyor) indirin. Download yazısına tıkladığınızda açılan pencereden dosyayı kaydet diyeceksiniz. Dosyanın adı netbeans-6.8-ml-cpp-linux.sh gibi bir şey olacak. Ben 6.8′i indirdiğim için dosyanın adında 6.8 diyor. Bu sh uzantılı dosyayı masaüstünüze kaydedin.

Açtığınız Uçbirimde önce masaüstüne gelmeniz grekiyor. Konsola cd Masaüstü/ yazdığınızda artık çalıştığınız dizin masaüstü olacaktır. Sonra şu komutu verdiğinizde sizden kullanıcı şifrenizi istecek ve siz şifrenizi girdikten sonra Netbeans kurulumu başlayacak:

sudo sh netbeans-6.8-ml-cpp-linux.sh

Adım adım Netbeans kurumu yapacaksınız ve daha sonra Netbeans’ı açtığınızda, orda New Project gibi seçenekler seçerek, kodları yazacağınız dosyayı yaratacaksınız. Size bir sürü seçenek sunacak. Bir C Konsole Aplication yazdığınızı düşünebilirsiniz.

C kodlarının derlenmesi için bilgisayarınızda gcc ve gdb‘nin kurulu olması gerekiyor. Synaptic’ten yüklü olup olmadığına bakabilirsiniz. Yüklü ise, hangi sürümünün yüklü olduğunu öğrenmek için açtığınız uçbirim ekranına aşağıdaki komutları vermeniz yeterli.

GNU Debugger‘ın kısatması olan GDB‘yi kontrol etmek için:

gdb -v

komutunu vererek şu çıktıya benzer bir çıktı almanız gerekiyor:

GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type “show copying”
and “show warranty” for details.
This GDB was configured as “i486-linux-gnu”.

GNU C Compiler‘ın kısatması olan GCC‘yi kontrol etmek için ise:

gcc -v

komutunu vereceksiniz. Mesela benim bilgisayarımda son satırda, gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4) yazısı çıkıyor. Bu komutları vermek ve sonuçlarını almak için konsolda Root olmanıza gerek yoktur.

Derlerken kodların bulunduğu dizine cd komutları ile geçtim. Masaüstümde bulunan ornek adındaki klasörümde ornek.c adında bir C dili ile yazılmış programım var. Bunu önce gcc ile derliyorum. gcc -o  ornek ornek.c komutu yazdığım ornek.c’yi derlememe yarar. Bu komut genelde işe yarar, eğer bir compile hatası yok ise ekrana hiç bir şey basmaz.

İkinci komut -gdb3 parametresi alıyor. Bu komutu vererek derlediğim programda debug sonucu bir sürü hata ekrana basılıyor. Onu kullanmadan da kodları çalıştırmak mümkün.

seval@seval-laptop:~/Masaüstü/ornek$ gcc -o  ornek ornek.c
seval@seval-laptop:~/Masaüstü/ornek$ gcc -o -gdb3  ornek ornek.c

Bu komutlarda hata verilmez ise, çalıştığınız dizinde C programınızla aynı isimde ve uzantısız bir dosya oluştuğunu göreceksiniz. Bu aslında derlenmiş kodların çalıştırılmasını sağlayan dosyadır. İngilizcede executable denilen, aslında çalıştırılabilir dosyadır. Programı derlerken -o ornek parametresi eklemezsek, ornek yerine a.out adında yeni bir dosya oluştuğunu görürüz. Mesela şu şekilde derlersek:

seval@seval-laptop:~/Masaüstü/ornek$ gcc ornek.c

Bu şekilde de program derlenebilir, fakat oluşturulan executable dosyaların adlarının birbirinden farklı olması ve anlaşılır olması olması için -o parametresini kullanmanızı öneririm.

Programı çalıştırmak için executable dosyayı çağırıyoruz:

seval@seval-laptop:~/Masaüstü/ornek$ ./ornek

Yani ./ornek komutunu veriyorum. Böylece konsolda programın çalıştığını görüyorum.

Share and Enjoy: Twitter Facebook FriendFeed Tumblr Google Bookmarks del.icio.us LinkedIn email Identi.ca MySpace StumbleUpon Technorati Posterous RSS Reddit Digg Yahoo! Buzz Yahoo! Bookmarks blogmarks Suggest to Techmeme via Twitter Netvibes Live