3 - Struct, Enum ve Union’lar
2026
struct (structure), C dilinde farklı veri tiplerini bir arada tutan bir veri yapısıdır.Ogrenci ogrenciler[100];Öğrenci bilgilerini (ad, soyad, numara, not ortalaması) saklamak için ayrı ayrı değişkenler tanımlamak yerine, bir struct kullanabiliriz:
struct tanımladıktan sonra, bu türden değişkenler oluşturabiliriz:struct Etiketi ve typedefAynı fikri iki farklı biçimde ifade edebiliriz. Projelerde genellikle tek bir stil seçip tutarlı gitmek daha uygundur.
typedef ile Daha Okunur Kodtypedef ile struct türüne yeni bir isim verebiliriz:typedef ile kod daha okunabilir hale gelir:Struct değişkenleri doğrudan atanabilir. Bu, alan alan kopyalama anlamına gelir.
Ogrenci a = {"Ali", "Veli", 1, 3.20};
Ogrenci b = a; // a'nın alanları b'ye kopyalanır
b.numara = 2;
// a.numara hâlâ 1, b.numara 2Bu bilgi, “fonksiyona değer ile geçiş” davranışını anlamayı da kolaylaştırır: değer ile geçişte çoğu durumda kopya taşınır.
struct’ın bellekte kapladığı alan, üyelerin boyutlarının basit toplamı olmak zorunda değildir.sizeof çıktısıdır (derleyici + mimariye bağlıdır).#include <stdio.h>
typedef struct {
char c1; // 1 bayt
int i; // çoğunlukla 4 bayt
char c2; // 1 bayt
} S1;
typedef struct {
int i;
char c1;
char c2;
} S2;
int main() {
printf("sizeof(S1) = %zu\n", sizeof(S1));
printf("sizeof(S2) = %zu\n", sizeof(S2));
return 0;
}Not: Üyelerin sırası değişince,
sizeofsonucu da değişebilir.
.).) ile erişiriz.->)->) kullanırız.Struct’lar fonksiyonlara:
Fonksiyonlar struct türünde değer döndürebilir.
const)Bu sürüm, “bu fonksiyon veriyi değiştirmeyecek” niyetini açıkça gösterir ve gereksiz kopyayı azaltır.
#include <stdio.h>
#include <string.h>
typedef struct {
char ad[50];
int numara;
} Ogrenci;
void ogrenciDegistir(Ogrenci *ogr) {
strcpy(ogr->ad, "Veli");
ogr->numara = 67890;
}
int main() {
Ogrenci ogrenci1 = {"Ali", 12345};
ogrenciDegistir(&ogrenci1);
printf("Ad: %s, Numara: %d\n", ogrenci1.ad, ogrenci1.numara);
return 0;
}struct, kendi türünden bir işaretçi alanı barındırabilir.Typedef ile daha okunur bir kullanım:
. ile zincirleme yapılır: ogr1.adres.sehir gibi.int main() {
Ogrenci ogr1;
strcpy(ogr1.ad, "Ali");
strcpy(ogr1.soyad, "Veli");
ogr1.numara = 12345;
strcpy(ogr1.adres.cadde, "Çınar Cad.");
strcpy(ogr1.adres.sehir, "Ankara");
ogr1.adres.postaKodu = 06000;
printf("%s %s - %s/%s (%d)\n",
ogr1.ad, ogr1.soyad,
ogr1.adres.cadde, ogr1.adres.sehir,
ogr1.adres.postaKodu);
return 0;
}enum (enumeration), birbiriyle ilişkili sabit değerler kümesi oluşturmak için kullanılır.Enum Tanımlama Sözdizimi:
Bu tanımda, KIRMIZI, SARI, YESIL varsayılan olarak sırasıyla 0, 1, 2 değerlerini alır.
Sayısal değerleri elle de belirleyebilirsiniz.
Kısmi atama örneği:
#include <stdio.h>
typedef enum {
PAZARTESI,
SALI,
CARSAMBA,
PERSEMBE,
CUMA,
CUMARTESI,
PAZAR
} Gunler;
int main() {
Gunler bugun = SALI;
if (bugun == PAZARTESI) {
printf("Haftanın ilk günü.\n");
} else if (bugun == CUMA) {
printf("Haftanın son iş günü.\n");
} else if (bugun == CUMARTESI || bugun == PAZAR) {
printf("Hafta sonu.\n");
} else {
printf("Hafta içi.\n");
}
return 0;
}Standart C’de enum’lar çoğunlukla tamsayı gibi işlendiği için (Renk)secim zorunlu değildir.
Buna rağmen cast:
Renk olarak yorumlanacak” niyetini gösterebilir.Önemli olan: Aralık kontrolü ve default gibi güvenlik kontrolleridir.
#include <stdio.h>
typedef enum { KIRMIZI, YESIL, MAVI } Renk;
int main() {
int secim;
printf("Bir renk seçin (0-KIRMIZI, 1-YESIL, 2-MAVI): ");
scanf("%d", &secim);
if (secim < 0 || secim > 2) {
printf("Geçersiz seçim!\n");
return 0;
}
Renk renk = (Renk)secim;
switch (renk) {
case KIRMIZI: printf("Kırmızı seçildi.\n"); break;
case YESIL: printf("Yeşil seçildi.\n"); break;
case MAVI: printf("Mavi seçildi.\n"); break;
default: printf("Geçersiz renk!\n"); break;
}
return 0;
}union, tüm üyelerinin aynı bellek alanını paylaştığı bir veri yapısıdır.Not: Union’da “başka bir alana yazdıktan sonra önceki alanı okumak” tanımsız davranış üretebilir.
Union Tanımlama Sözdizimi:
#include <stdio.h>
typedef union {
int tamSayi;
float ondalikSayi;
char karakter;
} Sayi;
int main() {
Sayi u;
u.tamSayi = 10;
printf("tamSayi: %d\n", u.tamSayi);
u.ondalikSayi = 3.14f;
printf("ondalikSayi: %.2f\n", u.ondalikSayi);
u.karakter = 'A';
printf("karakter: %c\n", u.karakter);
printf("Union'ın boyutu: %zu bayt\n", sizeof(u));
return 0;
}Union çoğu durumda bir “tür etiketi” ile birlikte anlam kazanır: Hangi alanın geçerli olduğunu ayrıca tutarız.
struct: Üyeler ardışık yerleşir; toplam + padding oluşabilir.union: Tüm üyeler aynı bellek alanını paylaşır; boyut çoğunlukla en büyük üyenin boyutu kadardır.#include <stdio.h>
typedef struct {
int i;
float f;
char c;
} S;
typedef union {
int i;
float f;
char c;
} U;
int main() {
printf("sizeof(S) = %zu\n", sizeof(S));
printf("sizeof(U) = %zu\n", sizeof(U));
return 0;
}Basit şema (kavramsal):
struct S: [ i ][ f ][ c ]union U: [ i / f / c ] (aynı alan, tek “aktif değer”)Araba struct’ı oluşturun. Araba struct’ı, arabanın markasını, modelini, üretim yılını ve rengini içersin. Renk için bir enum tanımlayın. Kullanıcıdan 3 arabanın bilgilerini alıp bu bilgileri Araba struct’ı dizisinde saklayan ve ekrana yazdıran bir program yazın.Nokta struct’ı oluşturun. Nokta struct’ı, noktanın x ve y koordinatlarını içersin. Kullanıcıdan iki noktanın koordinatlarını alıp bu noktalar arasındaki mesafeyi hesaplayan bir program yazın. Mesafe: \(\sqrt{(x_2-x_1)^2 + (y_2-y_1)^2}\)Tarih struct’ı oluşturun. Tarih struct’ı günü, ayı ve yılı içersin. Kullanıcıdan bir tarih alıp ekrana yazdıran bir program yazın.Ogrenci struct’ı ve içinde Adres struct’ı olsun. Ogrenci struct’ında öğrencinin adı, soyadı, numarası, Adres struct’ında ise adres bilgileri (cadde, şehir, posta kodu) olsun. Kullanıcıdan 5 öğrencinin bilgilerini alıp bu bilgileri Ogrenci struct’ı dizisinde saklayan ve ekrana yazdıran bir program yazın. Ek olarak, yazdırma işini void ogrencileriYazdir(const Ogrenci dizi[], int n); benzeri bir fonksiyona taşıyın.sizeof sonucu, üyelerin toplamından büyük olabilir; üye sırası sonucu etkileyebilir.. operatörü: Struct üyelerine erişim.-> operatörü: Struct işaretçisi ile üyelere erişim.