İçeriğe geç

Menü

Berk Akademi
Yorumlar Google yorumları Özel Ders Başvuru Ücretsiz ön görüşme Ana Sayfa

C Dilinde struct Nasıl Tanımlanır ve Kullanılır? Örnekli Anlatım

c-dilinde-struct-nasil-tanimlanir-ve-kullanilir
Bu yazıda neler var?
  1. C dilinde struct ilişkili alanları tek yapıda toplar
  2. Struct değişkeni nasıl oluşturulur ve alanlara nasıl erişilir?
  3. typedef ile kısa tür adı ve struct dizisi nasıl kullanılır?
  4. Struct pointer ile fonksiyona nasıl aktarılır?
  5. En yüksek ortalamayı bulan çalışan C örneği

C dilinde struct, farklı türlerdeki ilişkili verileri tek bir yapı altında toplamak için tanımlanır. Örneğin bir öğrencinin adı karakter dizisi, numarası tam sayı, not ortalaması ondalıklı sayı olarak tutulabilir; bu alanlar birlikte bir öğrenci kaydını oluşturur. Yapıyı tanımladıktan sonra değişken oluşturabilir, ilk değerlerini verebilir ve alanlarına nokta operatörüyle erişebilirsin.

C dilinde struct ilişkili alanları tek yapıda toplar

Bir struct tanımı, birbiriyle ilişkili alanların adlarını ve türlerini belirtir. Alan, yapının içindeki adlandırılmış veri öğesidir. Aşağıdaki tanımda ad, numara ve ortalama birer alandır:

struct Ogrenci {
    char ad[40];
    int numara;
    float ortalama;
};

Ogrenci, bu yapının etiketidir. Etiketle tanımlanan tür, değişken oluştururken struct Ogrenci biçiminde kullanılır. Tanımın kapanışındaki noktalı virgül zorunludur; eksik bırakılırsa derleyici sonraki kodu doğru yorumlayamaz.

Bellek düzeni, yapının alanlarının bellekte nasıl yerleştiğini anlatır. Alanlar tanımdaki sırayla yer alır, ancak derleyici hizalama amacıyla alanların arasına veya yapının sonuna dolgu baytları ekleyebilir. Bu nedenle yapının toplam boyutu her zaman alanların boyutlarının basit toplamına eşit olmayabilir.

Struct değişkeni nasıl oluşturulur ve alanlara nasıl erişilir?

Struct değişkeni nasıl oluşturulur ve alanlara nasıl erişilir?

struct Ogrenci türünden bir değişken oluşturup alanlarına nokta operatörüyle erişebilirsin. Tanım sırasında ilk değerleri süslü ayraçlar içinde alan sırasına göre verebilir, daha sonra tek tek alanları güncelleyebilirsin.

struct Ogrenci ogrenci = {"Ada", 1042, 87.5f};

ogrenci.numara = 1043;
printf("%s, %d, %.1fn",
       ogrenci.ad, ogrenci.numara, ogrenci.ortalama);

Burada ogrenci.ad karakter dizisine, ogrenci.numara tam sayıya, ogrenci.ortalama ise kayan noktalı sayıya erişir. Karakter dizisine ilk değer tanımlama sırasında {"Ada", ...} gibi verilebilir. Ancak dizi tanımlandıktan sonra ogrenci.ad = "Ada"; biçiminde metin atanamaz, çünkü C dilinde diziler bu şekilde atama hedefi olamaz. Metni kopyalamak için hedef dizinin kapasitesini gözeten bir işlev kullanmalısın.

Tampon taşması, hedef diziye kapasitesini aşan miktarda veri yazılmasıdır. snprintf, hedef dizinin boyutunu alarak yazılacak karakter sayısını sınırlar. Dönüş değeri negatifse yazma işlemi başarısız olmuştur; değer hedefin kapasitesine eşit veya ondan büyükse metin kesilmiştir.

#include <stdio.h>
#include <stddef.h>

struct Ogrenci {
    char ad[12];
    int numara;
    float ortalama;
};

int main(void) {
    struct Ogrenci ogrenci = {"Ada", 1042, 87.5f};
    const char yeni_ad[] = "Alexandria Johnson";

    int sonuc = snprintf(ogrenci.ad, sizeof ogrenci.ad, "%s", yeni_ad);

    if (sonuc < 0) {
        puts("Metin yazilamadi.");
        return 1;
    }

    if ((size_t)sonuc >= sizeof ogrenci.ad) {
        puts("Ad kesildi.");
    }

    printf("Ad: %snNumara: %dnOrtalama: %.1fn",
           ogrenci.ad, ogrenci.numara, ogrenci.ortalama);

    return 0;
}

sizeof ogrenci.ad, hedef dizinin kapasitesini verir ve snprintf bu sınırı aşacak karakterleri yazmaz. Bu örnekte uzun ad kesilerek diziye sığdırılır.

Ad kesildi.
Ad: Alexandria
Numara: 1042
Ortalama: 87.5

typedef ile kısa tür adı ve struct dizisi nasıl kullanılır?

typedef ile kısa tür adı ve struct dizisi nasıl kullanılır?

typedef, tanımladığın struct türüne Ogrenci gibi kısa bir ad vermeni sağlar. Böylece her değişken tanımında struct anahtar sözcüğünü tekrar etmeden aynı türden değişkenler ve diziler oluşturabilirsin. Aşağıdaki örnekte üç öğrencinin adı ve notu bir dizide tutuluyor; for döngüsü her elemanın alanlarına sırayla erişiyor.

#include <stdio.h>

typedef struct {
    char ad[20];
    int notu;
} Ogrenci;

int main(void) {
    Ogrenci ogrenciler[3] = {
        {"Ada", 90},
        {"Deniz", 85},
        {"Ece", 95}
    };

    for (int i = 0; i < 3; i++) {
        printf("%s: %dn", ogrenciler[i].ad, ogrenciler[i].notu);
    }

    return 0;
}

ogrenciler[i] dizinin o sıradaki struct elemanını belirtir; nokta operatörünün ardından alan adı yazılır. Bu örnekte döngü sırasıyla üç öğrencinin adını ve notunu ekrana yazdırır.

Ada: 90
Deniz: 85
Ece: 95

Struct pointer ile fonksiyona nasıl aktarılır?

Bir struct değişkeninin adresini fonksiyona göndererek, parametre olarak o struct türüne işaret eden bir pointer kullanabilirsin. Pointer üzerinden alana erişirken -> operatörü kullanılır. Aynı alan için struct değişkeninde nokta, pointer’da ok operatörü yazılır.

#include <stdio.h>

typedef struct {
    char ad[20];
    int notu;
} Ogrenci;

void notuGoster(const Ogrenci *ogrenci) {
    printf("Fonksiyondaki not: %dn", ogrenci->notu);
}

int main(void) {
    Ogrenci ogrenci = {"Ada", 90};

    printf("Nokta ile erişim: %dn", ogrenci.notu);
    notuGoster(&ogrenci);

    return 0;
}

ogrenci.notu ifadesinde ogrenci struct değişkenidir. Fonksiyona &ogrenci ile adresi gönderildiğinden, parametre içindeki ogrenci ise pointer’dır ve alanına ogrenci->notu biçiminde erişilir. Bu iki kullanımın karıştırılması derleme hatasına yol açabilir.

Nokta ile erişim: 90
Fonksiyondaki not: 90

En yüksek ortalamayı bulan çalışan C örneği

Aşağıdaki program, üç öğrenciyi bir Ogrenci dizisinde tutar ve ortalaması en yüksek öğrenciyi bulan fonksiyona diziyi aktarır. Ad alanına metin kopyalanırken snprintf dönüş değeri kontrol edilir; sonuç hedef tamponun boyutuna eşit ya da büyükse metin kesilmiş demektir.

#include <stddef.h>
#include <stdio.h>

typedef struct {
    char ad[40];
    double ortalama;
} Ogrenci;

int ogrenciAdiAta(Ogrenci *ogrenci, const char *ad)
{
    if (ogrenci == NULL || ad == NULL) {
        return 0;
    }

    int uzunluk = snprintf(ogrenci->ad, sizeof ogrenci->ad, "%s", ad);
    if (uzunluk < 0 || (size_t)uzunluk >= sizeof ogrenci->ad) {
        return 0;
    }

    return 1;
}

const Ogrenci *enYuksekOrtalamali(const Ogrenci *ogrenciler, size_t adet)
{
    if (ogrenciler == NULL || adet == 0) {
        return NULL;
    }

    const Ogrenci *enYuksek = &ogrenciler[0];

    for (size_t i = 1; i < adet; i++) {
        if (ogrenciler[i].ortalama > enYuksek->ortalama) {
            enYuksek = &ogrenciler[i];
        }
    }

    return enYuksek;
}

int main(void)
{
    Ogrenci ogrenciler[3];

    if (!ogrenciAdiAta(&ogrenciler[0], "Ayşe") ||
        !ogrenciAdiAta(&ogrenciler[1], "Ece") ||
        !ogrenciAdiAta(&ogrenciler[2], "Mert")) {
        fprintf(stderr, "Öğrenci adı hedef alana sığmadı.\n");
        return 1;
    }

    ogrenciler[0].ortalama = 84.5;
    ogrenciler[1].ortalama = 91.5;
    ogrenciler[2].ortalama = 88.0;

    size_t adet = sizeof ogrenciler / sizeof ogrenciler[0];
    const Ogrenci *sonuc = enYuksekOrtalamali(ogrenciler, adet);

    if (sonuc == NULL) {
        puts("Öğrenci listesi boş.");
        return 1;
    }

    printf("En yüksek ortalama: %s (%.2f)\n",
           sonuc->ad, sonuc->ortalama);

    return 0;
}

Derlemek için gcc -std=c99 -Wall -Wextra -pedantic program.c -o program komutunu kullanabilirsin. Örnek çıktı şöyledir:

En yüksek ortalama: Ece (91.50)

Fonksiyon, boş dizi veya geçersiz dizi adresi verildiğinde NULL döndürür; çağıran kod da bunu kontrol eder. Sonuç bir struct pointer’ı olduğu için alanlarına sonuc->ad ve sonuc->ortalama biçiminde erişilir. Ece’nin 91.5 ortalaması diğer iki değerden yüksek olduğundan program onu seçer.

Bu örnekte dizideki struct’lar öğrenci bilgilerini bir arada tutarken fonksiyon, en yüksek değere sahip öğenin adresini döndürür.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara