C dilinde fonksiyon tanımı ve kullanımı

Merhaba arkadaşlar,

Ben uzun zamandır C dilini öğrenmeye çalışıyorum ama henüz temelini bile anlayamadım. Aslında bir çoğunu anladım da fonksiyonlar birazcık zorluyor şuan. Şuan iki farklı kaynaktan fonksiyonları okudum ama ikisi de farklı şeyler söylemişler nasıl tanımlanır nasıl çağrılır filan. Bir tarafta fonksiyonun veri tipi ne ise onunla tanımlanmalı diyor diğer tarafta ise “void” ile tanımlanmalı diyor. Anlamadım ki ne ile yapmak istediklerini.

C bilmiyorum ama C# tan bildiğim kadarıyla anlatayım.
void fonksiyonun hiçbir değer döndürmeyeceği anlamına geliyor yani return kullanamassın. Başka herhangi bir veri tipinde ise (string, int, v.b) return kullanmak zorundasın. Mesela:

string kullanici_adi()
{
    return "StaticSploit";
}

string yazdığım için return de string bir değer kullanmak zorundaydım yani:

string kullanici_adi()
{
    return 5;
}

hata verirdi.
Kısacası en başa yazdığın string, int gibi kelimeler return de dönecek verinin türünü belirler kullanici_adi kısmı ise fonksiyonun adı ve fonksiyonu istediğim bir yerde kullanici_adi() diyerek çağırabilirim.
Hemde fonksiyonların içine parametreler koyabilir ve fonksiyonda kullanabiliriz. Mesela:

string kullanici_adi(string kullaniciadi)
{
    return kullaniciadi;
}

ayrıca string kullaniciadi yazdığımız için kullaniciadi na bir değer atarken string bir değer girmemiz lazım. Bu fonksiyonu ise şöyle çağırabiliriz:

kullanici_adi("StaticSploit");

Umarım açıklayıcı olmuştur. C yi bilen birinin anlatması daha iyi olur ama C# tan bildiğim kadarıyla anlatmaya çalıştım, C de daha farklı olduğunu sanmıyorum.
Ayrıca “Functions in C” yazınca bir çok kaynak çıktı. Belki farklı yerlerden de araştırmak işine yarayabilir.

Merhaba,

Yanlışınız var kullanabilirsiniz. Hatta bir fonksiyonda birtakım işleri çalıştırmadan önce ön kontrol yapmak adına kullanmaktayım. Tabi başka amaçlar için de kullanılabilir.

#include <stdio.h>

void foo(int x)
{
    if (x == 0)
        return;

    printf("%d", x);
}

int main()
{
    foo(1);
}

Kaynakları buraya atabilirsen kafandaki karışıklıkları daha iyi giderebiliriz diye düşünüyorum. Onun dışında yukarıdaki cevap fonksiyonların mantığını genel olarak anlatmış diye düşünüyorum.

1 Beğeni

Programlamanın temelleri, aslında öğrenmenin temelleri;

Ne işine yarayacağını bilmediğinde öğrenmekte isteksizlik ve anlamakta zorlanma doğal bir durum.

C zor bir dildir. Yanlış. C çok kolay bir dildir.

Bunun için farklı özellikte bir kaç dille çalışır bazı sorunları çözmüş olursan, C nin aslında neden böyle tasarlandığını kolaylıkla anlayabilirsin.

Aralıkları bol, sana özel bir yazı olarak bunları kaleme alayım. Dilleri sınfılandırmak vs gibi konuları bolca internette kaynak olarak bulabilirsin.

Ama kendimce sana bir kaç dil ve özelliklerinden bahsedeyim, arada da bu fonksiyon nedir ne değildir açıklamaya çalışayım. İşin teknik tarafını kitaplardan okurken daha iyi anlarsın.

Öncelikle, bilgisayarın tek bildiği dil, 10110110 (Özellikle 8 bit yazıdım, ilk zamanları 8 bit olması nedeniyle) dir.

Yani diller sadece bir yanılsama yada insanın düşünme yapısını bilgisayarla örtüştürme çabasıdır.

Mesela Pascal gibi bir dil ile çalışıyor olsaydın, iki tür yapıyla karşılaşırdın. Procedure ve function. Yaptığı işin sonucunda oluşan bir değer yoksa yada bir değere ihtiyacın yoksa procedure olarak oluşturursun, bir değer döndürmek istediğinde ise function olarak tanımlarsın.

Biraz daha farklı bir dile gidelim, BASIC adında bir dil vardı, burada her satır tek tek işletilirdi, yani yorumlanan diller gibi.

Sıralı işlemler yaparken sorun yok, ama programlama yaparken bazı işleri tekrar tekrar yazmak zorunda olduğunu farketmeye başladılar. BASIC bu işi jump komutu ile tekrarlanacak kısma gidip gidip gelerek çözmeye çalışıyordu.

Gelelim, fonksiyon meselesine, aslında bunu matematikteki fonksiyon gibi düşünebilirsin, bir x değeri girersin, fonksiyodaki işlemlere tabi tutar ve bir sonuç üretirsin.

Neden fonksiyonlara ihtiyaç duyarız. Başta belirttiğim gibi, bilgisayarın anladığı tek dil 1 ve 0 lar. Her şeyi bunların tekrarı şeklinde yaparız. Bir çok şeyi ekrana yazdırmak istediğimizde bir fonksiyon çağırırız ekrandan bir şey silmek istediğimizde bir fonksiyon çağırırız. Yani bir şeyleri önceden bir kez tanımlar ve tekrar tekrar kullanırız.

Bu nedenle bazı temel ihtiyaç olan yerleşik fonksiyonlar vardır. Ekran silmek, kare kök almak, string verilerle uğraşmak, sistem tarihini almak gibi ihtiyaç duyabileceğimiz farklı ihtiyaçlar kütüphanelerde fonksiyon olarak durmaktadadır.

Yerleşik olmayan bizim kendi ihtiyaçlarımıza göre tekrar kullanmak istediğimiz kod parçalarını da fonksiyonlarda tanımlar ve gerektikçe çağırarak kullanabiliriz.

Tabi bazı özel fonksiyonlar da vardır.

En belirgini, int main() fonksiyonudur. Bir program ancak ilk nereden başlayacağını bildirildiğinde çalışabilir. C buna int main() ile karşılık vermiştir. Program entry point denilen giriş kısmını neden int olarak tanımlarız?

Çünkü işletim sistemi programı bitirdiğinde, varsa bir hata mesajını veya başarılı bir şekilde bitirildiyse bir değeri (genelde 0) buradan alabilir. Yani C aslında fonksiyon içinde fonksiyonlar şeklinde çalıştırır.

Buna bilgisayar ihtiyaç duymaz, insan aklı ihtiyaç duyar ve anlamlandırabilmesi için bu şekilde tasarlanmıştır. Bir işi daha kolay yönetilebilir küçük iş parçalarına ayırmak için bir yaklaşımdır. ( tek yöntem bu değildir ama.)

Yani fonksiyonlar C de tekrarlanan belirli işlerin ayrı bir isim altında toplanarak, insan beyninin tasnif mantığıyla programı daha iyi anlaması ve kavraması için uygulanan bir yaklaşımdır.

Yani printf() fonksiyonu ile ekrana yazı yazdığını bilmek yeterken, aslında bir çok arka plan tekrarlanan işlemleri görmek gerekmez ve okunurluğu artırır, sayısız tekrarlı komutu yazmak yerine printf() yazar kurtuluruz.

Yine int main() üzerine konuşursak komut satırından program ilk başlarken veriler göndermek isteyebiliriz. Bu durumda main() fonksiyonunda parantez içindeki alan girilecek parametre sayısı ve parametrelerinin tutulacağı bir pointer (İşaretçi/ adres) tanımlar ve kullanırız.

Bunların detaylarıı kitaplarda ve kaynaklarda bulabilirsin.

En başlarda anlattığım üzere değer döndürüp döndürmeme konusuna gelelim.

Pascal procedure tanımlattığında değer döndürmüyordu, yani bir ekran komutu işlettiğinizde bir değer döndürmek istemeyebilirsiniz, ama bir çarpma fonksiyonu yazdığınızda sonucu fonksiyondan geri almanız gerekir. Bunu için iki ayrı yapı sunmuştur. C ise sadece bir dil olma ve basit yapısı nedeniyle bu ayrıma gerek duymaz her şeyi fonksiyon kabulü ile değer döndürüp döndürmemeyi ise tercihe bırakarak çözer.

void burada devreye girer.

Eğer bir değer döndürmeyecekse fonksiyon, burada void ile tanımlanır. Bunun avantajı şudur, bu değeri tutmak için özel bir çapa harcamaz ve aynı zamanda derleyici ve programdan bir dönüş değeri beklemez.

Ama bir değer döndürmek istediğimizde, bu bir işlemin sonucu, bir kararın sonucu, bir işlemin başarılıp başarılamadığının kontrolü değerlerine ihtiyaç duyarsa bu durumda dönüş değeri tanımlanır.

Fonksiyonların bu tür dönüşünün tanımlanmasına fonksiyon tipinin tanımlanması denir.

Tip tanımlayıcılarla istediğin dönüşü alabilirsin.

Bir adım ilerisinde ise fonksiyonlara direkt değer göndererek hesaplatabileceğin/ işletebileceğin gibi değerlerinin durduğu adresleri fonksiyona göndererek de işlenecek veriyi fonksiyona ulaştırabilirsin.

Buna da, değerle (by value), adresle (by reference) denilen yöntemlerle yapabilirsin.

Uzadı farkındayım.

Özetleyip bırakayım. Tekrarlana tüm işlemlerle, c 'nin kendisi dahil tamamı neredeyse fonksiyon üzerine kurulmuştur. Kodunun tekrarlanan kısımlarını bir araya toparlayıp bu kısmı çağırma işine yarayan şey fonksiyondur, bir sonuç üretmeyeceksen void, bir sonuç üreteceksen tip tanımlamasında o tipi tanımlayıp, return ile bu değeri alabileceğin yapılardır.

Fonksiyonları çağırmak veya fonksiyonlara değişken (parametre) göndermek ikinci de doğrudan değer girmek veya değerlerin adreslerini vermek şeklinde seçeneklerin vardır.

Bunları okumaktan zevk aldığım ktapların linklerini de bırakayım.

C: The Complete Reference (Osborne Complete Reference Series) [Paperback] Schildt, Herbert : Amazon.com.tr: Kitap

Kitaba bu kadar para verme Türkçe baskısı vardı eskiden şimdi var mı bilmiyorum ama ortalıkta pdf leri vardır.

TÜM C SÜRÜMLERİ İÇİN The Complete Reference 1. BASKI - HERBERT SCHİLDT | Nadir Kitap

Bu gibi bir kitabı temin edip, çok kaynak yerine tek kaynaktan tamamlarsan kafan karışmaz.

4 Beğeni

Merhaba,
Aynı kodu https://www.onlinegdb.com/online_c_compiler adresinde yazıp kullandım ancak foo(0); şeklinde kullandığım zaman hiç bir şey yazdırmıyor. Ön kontrol için nasıl kullanıyoruz anlamadım. Ayrıca void’de de return kullanabileceğimi öğrenmiş oldum teşekkürler.

Çok ahım şahım bir şey değil aslında.

#include <stdio.h>

void foo(int x, int y)
{
    // ön_kontrol
    if (y == 0) {
        printf("Tanmsız!");
        return;
    }

    // ön_kontrol_2
    if (y == 17 || x == 17) {
        printf("17 sayısına garezim var.")
        return;
    }
    printf("%d", x / y);
}

int main()
{
    foo(1, 0);
    printf("------------------");
    foo(10, 17);
    printf("------------------");
    foo(17, 6);
    printf("------------------");
    foo(6, 3);
}

Zaten yazdırmayacak, çünkü return ifadesinden önce çalıştırılması gereken bir şey yok. Bunu son attığım kod üzerinde daha rahat görebilirsiniz.

1 Beğeni

Fonksiyondan true ya da false gibi bir değer dönecek ve bunu kodda if te kullanacağız sanmıştım (yani if (foo(17, 17)) gibi) ama neyden bahsettiğinizi şimdi anladım.

Soru Sorarken Sıkça Düşülen Hatalar #8

Sen okudugun halde anlamamissan, okumayan bizlerden ne bekliyorsun? :slight_smile:

sizlerden bana fonksiyonların kullanımı ile ilgili basitçe bir şekilde anlatan bir kaynak istiyorum.

Fonksiyonlar — Yazbel Python Belgeleri

1 Beğeni