Void İşaretçiler Özeti
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 49 / 61.
Bir void*, C'nin "bir şeye işaret eden bir işaretçi, ama ne olduğunu söylemiyorum" deme şeklidir. Herhangi bir veri tipinin adresini tutabilir — bir int, bir float, bir struct veya başka herhangi bir şey. Bu, C'de genel (generic) kod yazmanın temelini oluşturur.
Buradaki püf noktası, bir void* işaretçisini doğrudan dereference edememenizdir (içeriğine erişemezsiniz). Derleyici kaç bayt okunacağını veya bunların nasıl yorumlanacağını bilmez. Veriyi kullanmak için onu doğru tipe geri dönüştürmeniz (cast) gerekir:
void print_int(void* data) {
int* p = (int*)data;
printf("%d\n", *p);
}
int main() {
int x = 42;
print_int(&x);
return 0;
}Bu esneklik beraberinde sorumluluk getirir. Yanlış tipe dönüştürürseniz, derleyici sizi durdurmaz — ancak programınız anlamsız veriler üretir veya çöker. Bu nedenle genel fonksiyonlar, fonksiyonun veriyi doğru şekilde nasıl yorumlayacağını bilmesi için genellikle bir void* ile bir tip göstergesini (bir enum veya bayrak gibi) eşleştirir.
Gelecek derslerde, her türlü veriyi depolayabilen kapsayıcılar (containers) oluşturmak için void* kullanacaksınız; bu da gerçekten yeniden kullanılabilir veri yapılarına olanak tanıyacak.
Görev
KolayVeriye yönelik bir void* işaretçisi ve bir int tip bayrağı (type flag) olmak üzere iki parametre kabul eden print_value adında bir fonksiyon yazın. Fonksiyon, veriyi tip bayrağına göre yorumlamalı ve yazdırmalıdır:
- Eğer tip bayrağı
0ise, işaretçiyiint*türüne dönüştürün ve tam sayı değerini yazdırın - Eğer tip bayrağı
1ise, işaretçiyifloat*türüne dönüştürün ve float değerini virgülden sonra 2 basamak olacak şekilde yazdırın
Programınız iki girdi alacaktır:
- Bir tip bayrağı (tam sayı için
0, float için1) - Sayısal bir değer
Tip bayrağına bağlı olarak, değeri uygun değişken türünde saklayın, ardından bu değişkenin işaretçisi ve tip bayrağı ile print_value fonksiyonunu çağırın.
Girdiler 0 ve 42 olduğunda örnek çıktı:
42Girdiler 1 ve 3.14 olduğunda örnek çıktı:
3.14Girdiler 0 ve -17 olduğunda örnek çıktı:
-17Girdiler 1 ve 99.5 olduğunda örnek çıktı:
99.50Kopya kağıdı
Bir void*, herhangi bir veri tipinin adresini tutabilen genel bir işaretçidir. C'de genel kod yazmak için esneklik sağlar.
Bir void* işaretçisinin değerine doğrudan erişemezsiniz (dereference yapamazsınız) — önce onu doğru tipe dönüştürmeniz (cast etmeniz) gerekir:
void print_int(void* data) {
int* p = (int*)data;
printf("%d\n", *p);
}
int main() {
int x = 42;
print_int(&x);
return 0;
}Genel fonksiyonlar, veriyi doğru şekilde nasıl yorumlayacaklarını bilmek için genellikle bir void* işaretçisini bir tip belirteciyle (enum veya bayrak gibi) eşleştirir. Yanlış tipe dönüştürmek, belirsiz davranışlara (undefined behavior) veya çökmelere neden olabilir.
Kendin dene
#include <stdio.h>
// TODO: print_value fonksiyonunuzu buraya yazın
int main() {
int type_flag;
scanf("%d", &type_flag);
if (type_flag == 0) {
int int_value;
scanf("%d", &int_value);
// TODO: int_value göstericisi ve tip bayrağı ile print_value fonksiyonunu çağırın
} else if (type_flag == 1) {
float float_value;
scanf("%f", &float_value);
// TODO: float_value göstericisi ve tip bayrağı ile print_value fonksiyonunu çağırın
}
return 0;
}Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1Modüler Programlama Temelleri
Başlık DosyalarıInclude Guard'larKaynak DosyalarıStatik FonksiyonlarÖzet: Modüler Hesap Makinesi4Kapsülleme
Opaque Pointer KavramıOpaque Struct TanımlamaGetter ve Setter MetotlarıSetter Metotlarında DoğrulamaÖzet: Gizli Kutu7Fonksiyon İşaretçileri
Fonksiyon İşaretçilerini TanımlamaFonksiyon İşaretçilerini ÇağırmaFonksiyon İşaretçileri için TypedefFonksiyonları Argüman Olarak GeçirmeÖzet: Hesap Makinesi Yönlendirme10Jenerik Kapsayıcılar
Void İşaretçiler ÖzetiJenerik SarmalayıcıJenerik Yer DeğiştirmeJenerik KarşılaştırmaÖzet: Jenerik Dizi2Nesneler ve Metotlar
Nesne Olarak Struct'lar'Self' İşaretçisiConst Doğruluğuİşaretçi vs DeğerYardımcı MetotlarÖzet: Point Manager5Proje: Basit Banka Hesabı
Proje KurulumuHesabın Oluşturulması3Nesne Yaşam Döngüsü
Constructor DeseniDestructor DeseniStack İlklendirmeDerin KopyalamaÖzet: String Wrapper6Kompozisyon Yoluyla Kalıtım
Struct Gömmeİlk Üye KuralıÜst Üyelere ErişimUpcastingÖzet: Şekil Hiyerarşisi