Yapıların Dinamik Tahsisi
Coddy'nin C Journey'sinin Mantık & Akış bölümünün bir parçası. Ders 48 / 63.
Şimdiye kadar stack üzerinde struct'lar oluşturmayı öğrendin - bunlar bildirildikleri kapsam içinde var olur ve bu kapsam sona erdiğinde otomatik olarak temizlenir. Peki bir struct'ın özgün kapsamının ötesinde varlığını sürdürmesine ihtiyaç duyarsan veya derleme zamanında kaç struct'a ihtiyaç duyacağını bilmiyorsan ne olacak?
Dinamik ayırma işte burada devreye girer. Tıpkı diğer veri türlerinde olduğu gibi, yığın üzerinde yapı nesneleri oluşturmak için malloc() kullanabilirsin. Temel fark, dinamik olarak ayrılan yapı nesnelerinin free() ile onları açıkça serbest bırakana kadar bellekte kalmasıdır.
Bir struct'ı dinamik olarak ayırmanın söz dizimi şöyledir:
struct Point *ptr = malloc(sizeof(struct Point));Bu, yığında bir Point yapısını tutmaya yetecek kadar bellek ayırır ve bu belleğe bir işaretçi döndürür. Ardından yapı üyelerine erişmek ve onları değiştirmek için ok operatörünü kullanabilirsin:
ptr->x = 10;
ptr->y = 20;Bellek sızıntılarını önlemek için her zaman malloc() fonksiyonunun başarılı olup olmadığını (NULL olmayan bir değer döndürdüğünü) kontrol etmeyi ve struct ile işiniz bittiğinde free(ptr) fonksiyonunu çağırmayı unutmayın. Bu teknik, çalışma zamanında veri yapıları oluşturabilen ve yönetebilen esnek programlar oluşturmak için gereklidir.
Görev
Kolaymalloc() kullanarak yapıların dinamik olarak tahsis edilmesini gösteren bir C programı oluşturun. Programınız şunları yapmalıdır:
- Aşağıdaki üyelerle
structadlı birCartanımlayın:- Üretim yılını saklamak için bir tamsayı
year - Aracın markasını saklamak için boyutu 20 olan bir karakter dizisi
brand - Aracın modelini saklamak için boyutu 25 olan bir karakter dizisi
model - Aracın fiyatını saklamak için bir kayan noktalı sayı
price - Aracın kilometresini saklamak için bir tamsayı
mileage
- Üretim yılını saklamak için bir tamsayı
- main işlevinde
Carstruct'ına işaret eden ve adıcarPtrolan bir işaretçi tanımlayın - Bir
malloc()struct'ı için belleği dinamik olarak tahsis etmek üzereCarkullanın ve döndürülen adresicarPtr'a atayın - Bellek tahsisinin başarılı olup olmadığını kontrol edin:
carPtrdeğeriNULLiseMemory allocation failedyazdırın ve programdan çıkın- Tahsis başarılı olduysa
Memory allocation successfulyazdırın
- Aşağıdaki giriş değerlerini okuyun ve ok operatörünü kullanarak bunları struct üyelerine atayın:
- Yıl için bir tamsayı okuyun ve
carPtr->yearkullanarak atayın - Marka için bir dize okuyun ve
carPtr->brandkullanarak atayın - Model için bir dize okuyun ve
carPtr->modelkullanarak atayın - Fiyat için bir kayan noktalı sayı okuyun ve
carPtr->pricekullanarak atayın - Kilometre için bir tamsayı okuyun ve
carPtr->mileagekullanarak atayın
- Yıl için bir tamsayı okuyun ve
- Tüm değerleri okuduktan sonra, ok operatörünü kullanarak aşağıdaki hesaplamaları gerçekleştirin:
- Yıldan 2024'ü çıkararak aracın yaşını hesaplayın:
int age = 2024 - carPtr->year; - Yaşa göre değer kaybı oranını hesaplayın: yaş 10'dan büyükse değer kaybını 0.6 olarak ayarlayın, aksi takdirde 0.8 olarak ayarlayın
- Güncel değeri hesaplayın:
carPtr->price * depreciation
- Yıldan 2024'ü çıkararak aracın yaşını hesaplayın:
- Aracın bilgilerini, ok operatörünü kullanarak tam olarak şu biçimde yazdırın:
Car Information:Year: [year]Brand: [brand]Model: [model]Original Price: [price]Mileage: [mileage]Age: [age] yearsCurrent Value: [current_value]
- Dinamik olarak tahsis edilen belleği
free(carPtr)kullanarak serbest bırakın Memory freed successfullyyazdırın
Bu alıştırma, malloc() kullanarak dinamik struct tahsisini, tahsis hatasını kontrol etmeyi, ok operatörünü kullanarak işaretçiler üzerinden struct üyelerine erişmeyi ve tahsis edilen belleği free() ile doğru şekilde serbest bırakmayı anladığınızı test eder. Struct'larla dinamik bellek yönetiminin tüm yaşam döngüsünü uygulayacaksınız.
Kendin dene
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// YAPILACAK: Car yapısını (struct) burada tanımlayın
int main() {
// YAPILACAK: carPtr adında Car yapısına (struct) bir işaretçi (pointer) bildirin
// YAPILACAK: Bir Car yapısı için bellek ayırmak üzere malloc() kullanın
// YAPILACAK: Bellek tahsisinin başarılı olup olmadığını kontrol edin
// Giriş değerlerini oku
int year, mileage;
char brand[20], model[25];
float price;
scanf("%d", &year);
scanf("%s", brand);
scanf("%s", model);
scanf("%f", &price);
scanf("%d", &mileage);
// YAPILACAK: Ok operatörünü kullanarak giriş değerlerini yapı üyelerine atayın
// YAPILACAK: Yaşı, amortismanı ve mevcut değeri hesaplayın
// YAPILACAK: Araç bilgilerini istenen formatta yazdırın
// YAPILACAK: Ayrılan belleği serbest bırakın ve başarı mesajını yazdırın
return 0;
}Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Mantık & Akış bölümündeki tüm dersler
1Pointer Temelleri
Pointer Nedir?Pointer TanımlamaAdres Operatörü (&)Dereference Operatörü (*)NULL Pointer'larÖzet: Pointer Temelleri4Proje: Basit Metin Aracı
Projeye Genel BakışKarakter Sayma2İşaretçiler ve Diziler
İşaretçi Olarak Dizi İsimleriDizi Elemanları - İşaretçilerİşaretçi Aritmetiğiİşaretçilerin KarşılaştırılmasıÖzet: İşaretçi ile Dizi Gezinme5İşaretçiler ve Fonksiyonlar
Değer ile GeçmeFonksiyonlara İşaretçi Göndermeİşaretçiler ile Değişkenleri DeğiştirmeKlasik Bir Örnek: SwapFonksiyonlara Dizi GöndermeÖzet: Fonksiyon İşaretçi Argümanları8Yapılar ve İşaretçiler
Yapılara İşaretçilerOk Operatörü (->)Yapıları Değer ile AktarmaYapı İşaretçilerini AktarmaYapıların Dinamik TahsisiÖzet: Yapıyı Değiştirme - Ptr11Son Tekrar Görevleri
Tekrar: Dinamik String BirleştirmeTekrar: Struct DizisiTekrar: Kelime Frekans Sayacı3Karakter Dizileri ve Stringler
char Dizisi Olarak StringlerNull Sonlandırıcıscanf ile String Girişistrlen() Kullanımıstrcpy() Kullanımıstrcat() Kullanımıstrcmp() KullanımıÖzet: Temel String FonksiyonlarıKendi başına pratik yap: Online C derleyicisi