İşaretçi vs Değer
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 9 / 61.
Bir struct'ı bir fonksiyona geçirdiğinizde, C size iki seçenek sunar: onu değer ile geçirmek (tüm struct'ı kopyalamak) veya pointer ile geçirmek (yalnızca adresi kopyalamak). Bu seçim, performans açısından önemli ölçüde fark yaratır.
Değer ile geçme, yığında (stack) yapının (struct) tam bir kopyasını oluşturur. Birkaç tamsayı (integer) içeren küçük bir yapı için bu sorun değildir. Ancak yüzlerce baytlık bir yapıyı hayal edin; her fonksiyon çağrısı tüm bu veriyi kopyalar:
typedef struct {
char name[100];
int scores[50];
double average;
} Student;
// Değer ile: her çağrıda ~308 bayt kopyalar
void print_by_value(Student s) {
printf("%s: %.2f\n", s.name, s.average);
}
// İşaretçi ile: sadece 8 bayt (adresi) kopyalar
void print_by_pointer(const Student *s) {
printf("%s: %.2f\n", s->name, s->average);
}
Sözdizimi de farklılık gösterir. Bir değer parametresi ile nokta operatörünü (s.name) kullanırsınız. Bir işaretçi ile ok operatörünü (s->name) kullanırsınız.
Pointer versiyonu daha verimlidir çünkü struct boyutundan bağımsız olarak—genellikle 8 bayt—yalnızca bir bellek adresi iletir.
C programcılarının struct'ları neredeyse her zaman işaretçi (pointer) ile geçirmesinin nedeni budur. Fonksiyonun veriyi değiştirmemesi gerektiğinde const, değiştirmesi gerektiğinde ise normal bir işaretçi kullanın. Böylece hem verimlilik hem de net bir niyet elde edersiniz.
Görev
KolayStruct'ları değerine göre (by value) ve işaretçisine göre (by pointer) geçirme arasındaki farkı gösteren bir Product modülü oluşturalım. İki adet görüntüleme fonksiyonu oluşturacaksınız; biri tüm struct'ı bir kopya olarak alır, diğeri ise sadece ona işaret eden bir işaretçi alır.
Üç dosya oluşturacaksınız:
product.h: Üç üyeye sahip birProductstruct'ı bildirin:char name[50],double priceveint quantity. Ayrıca iki fonksiyon bildirin:display_by_value— birProductyapısını değerine göre alır ve bilgilerini yazdırırdisplay_by_pointer— birconst Product *alır ve aynı bilgileri yazdırır
PRODUCT_Hsembolü ile include guard (ekleme koruması) kullanın.product.c: Her iki fonksiyonu da uygulayın. Sözdizimi farkına dikkat edin: değerine göre olan sürüm nokta operatörünü (p.name) kullanırken, işaretçi sürümü ok operatörünü (p->name) kullanır. Her iki fonksiyon da aynı formatta çıktı vermelidir.main.c: Bir Product oluşturun, ardından farklı parametre stilleri kullanmalarına rağmen aynı çıktıyı ürettiklerini göstermek için her iki görüntüleme fonksiyonunu da çağırın.
Üç girdi alacaksınız: ürün adı (bir string), fiyat (bir double) ve miktar (bir tamsayı).
Ana dosyanızda, bir Product yapısını bu değerlerle başlatın, ardından display_by_value ve sonrasında display_by_pointer fonksiyonlarını çağırın.
Her iki fonksiyon da şu formatta yazdırmalıdır:
Product: {name}, Price: {price}, Qty: {quantity}Fiyatı iki ondalık basamakla göstermek için %.2f kullanın.
Örneğin, Laptop, 999.99 ve 5 girdileriyle çıktı şu şekilde olacaktır:
Product: Laptop, Price: 999.99, Qty: 5
Product: Laptop, Price: 999.99, Qty: 5Kendin dene
#include <stdio.h>
#include <string.h>
#include "product.h"
int main() {
char name[50];
double price;
int quantity;
// Girdileri oku
scanf("%s", name);
scanf("%lf", &price);
scanf("%d", &quantity);
// TODO: Bir Product değişkeni oluşturun ve onu girdi değerleriyle başlatın
// Hint: İsmi struct'ın name alanına kopyalamak için strcpy kullanın
// TODO: Product ile display_by_value fonksiyonunu çağırın
// TODO: Product işaretçisi ile display_by_pointer 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 Kutu2Nesneler 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