10 - Struct ve Union’lar
2024
struct
(structure), C dilinde farklı veri tiplerini bir arada tutan bir veri yapısıdır.
Bu sayede, birbiriyle ilişkili verileri daha organize ve anlamlı bir şekilde yönetebiliriz.
Öğ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 struct
türünden değişkenler oluşturabiliriz.typedef
kullanarak struct türüne yeni bir isim verebiliriz:typedef
ile kod daha okunabilir hale gelir:.
) ile erişiriz.->
) kullanırız.#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;
}
enum
(enumeration), C dilinde birbiriyle ilişkili sabit değerler kümesi oluşturmak için kullanılan bir veri türüdür. Bu sabit değerler, sayısal değerlere sahip adlandırılmış öğelerdir. Enum’lar, kodunuzu daha anlaşılır ve okunabilir hale getirmek, sabit değerlerin yönetimini kolaylaştırmak ve hata yapma riskini azaltmak için kullanılır.
Enum Tanımlama Sözdizimi:
Bu kodda, Renk
adında bir enum
türü tanımladık. KIRMIZI
, SARI
ve YESIL
, varsayılan olarak sırasıyla 0, 1 ve 2 değerlerini alır.
Sayısal değerleri elle de belirleyebilirsiniz.
Veya kısmi olarak:
#include <stdio.h>
typedef enum { KIRMIZI, YESIL, MAVI } Renk;
int main() {
int renkSecimi;
printf("Bir renk seçin (0-KIRMIZI, 1-YESIL, 2-MAVI): ");
scanf("%d", &renkSecimi);
// Kullanıcının girdiği değeri enum türüne cast ediyoruz
Renk renk = (Renk)renkSecimi;
// Şimdi renk değişkenini switch-case içinde kullanabiliriz
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 seçimi!\n");
}
return 0;
}
Açıklama:
enum
değerlerinin sayısal karşılıklarını (0, 1, 2 gibi) gösteren bir mesaj yazdırılır ve scanf
fonksiyonu ile tam sayı olarak girdi alınır.enum
türüne cast et: Alınan tam sayı değeri, (Renk)renkSecimi
ifadesi ile Renk
enum
türüne dönüştürülür (cast edilir). Bu işlem, derleyiciye değişkenin Renk
türünde olduğunu ve enum
sabitleriyle karşılaştırılabileceğini söyler.switch-case
içinde kullan: Cast edilmiş renk
değişkeni, switch-case
yapısı içinde kullanılabilir. case
etiketlerinde, enum
sabitleri (KIRMIZI, YESIL, MAVI) kullanılır.Bu şekilde, kullanıcıdan alınan sayısal girdi, enum
türüne dönüştürülerek switch-case
yapısı içinde kullanılabilir.
union
, tüm üyelerinin aynı bellek alanını paylaştığı bir veri yapısıdır. Herhangi bir anda sadece bir üyesinin değeri saklanabilir. Union’lar, farklı türden verileri aynı bellek alanında saklamak ve bellek kullanımını optimize etmek istediğimiz durumlarda kullanışlıdır.
Union Tanımlama Sözdizimi:
int main() {
Sayi birlesikDegisken;
birlesikDegisken.tamSayi = 10;
printf("tamSayi: %d\n", birlesikDegisken.tamSayi);
birlesikDegisken.ondalikSayi = 3.14f; // float değer ataması
printf("ondalikSayi: %.2f\n", birlesikDegisken.ondalikSayi); // Dikkat! tamSayi'nin değeri artık geçerli değil.
printf("tamSayi: %d\n", birlesikDegisken.tamSayi); // Beklenmedik bir değer yazdırabilir.
birlesikDegisken.karakter = 'A'; // char değer ataması
printf("karakter: %c\n", birlesikDegisken.karakter);
printf("Union'ın boyutu: %zu bayt\n", sizeof(birlesikDegisken));
return 0;
}
Union kullanırken, hangi üyenin aktif olduğunu (yani hangi tür verinin saklandığını) takip etmek önemlidir. Aksi takdirde, yanlış üyeye erişirseniz beklenmedik sonuçlar alabilirsiniz. Bu genellikle ayrı bir değişken veya enum ile yapılır.
int main() {
SayiBilgisi sayi;
// Tamsayı değeri atama
sayi.tip = TAMSAYI;
sayi.deger.tamSayi = 10;
printf("Tam Sayı: %d\n", sayi.deger.tamSayi);
// Ondalıklı sayı değeri atama
sayi.tip = ONDALIKLI;
sayi.deger.ondalikSayi = 3.14;
printf("Ondalık Sayı: %.2f\n", sayi.deger.ondalikSayi);
// Karakter değeri atama
sayi.tip = KARAKTER;
sayi.deger.karakter = 'A';
printf("Karakter: %c\n", sayi.deger.karakter);
if (sayi.tip == TAMSAYI) {
printf("Aktif değer: %d\n", sayi.deger.tamSayi);
} else if (sayi.tip == ONDALIKLI) {
printf("Aktif değer: %.2f\n", sayi.deger.ondalikSayi);
} else if (sayi.tip == KARAKTER) {
printf("Aktif değer: %c\n", sayi.deger.karakter);
}
return 0;
}
Aşağıdaki alıştırmaları yapın.
Araba
struct’ı oluşturun. Araba
struct’ı, arabanın markasını, modelini, üretim yılını ve rengini içersin. 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. (İki nokta arasındaki mesafe formülü: √((x2-x1)² + (y2-y1)²))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.for
veya while
döngülerini kullanabilirsiniz..
operatörü: Struct üyelerine erişim.->
operatörü: Struct işaretçisi ile üyelere erişim.