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.