Const Doğruluğu
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 8 / 61.
Metot olarak işlev gören fonksiyonlar yazarken, bazıları nesneyi değiştirmelidir (player_take_damage gibi), diğerleri ise hiçbir şeyi değiştirmeden sadece veriyi okumalıdır. const anahtar kelimesi, bu ayrımı derleyici düzeyinde uygulamanıza olanak tanır.
Bir işaretçi parametresini const olarak işaretleyerek, fonksiyonun işaret ettiği veriyi değiştirmeyeceğine dair söz vermiş olursunuz. Yanlışlıkla bir üyeyi değiştirmeye çalışırsanız, derleyici bir hata üretecektir:
typedef struct {
int x;
int y;
} Point;
// Bu fonksiyon noktayı sadece OKUYABİLİR
void point_print(const Point *self) {
printf("(%d, %d)\n", self->x, self->y);
// self->x = 10; // HATA: const işaretçi üzerinden değiştirilemez
}
// Bu fonksiyon noktayı DEĞİŞTİREBİLİR
void point_move(Point *self, int dx, int dy) {
self->x += dx;
self->y += dy;
}
const Point *self parametresi, hem derleyiciye hem de diğer programcılara point_print fonksiyonunun bir "getter" veya salt okunur bir işlem olduğunu bildirir. Buna const doğruluğu (const correctness) denir; değişikliğin gerekmediği her yerde const kullanılmasıdır.
Bu uygulama hataları erkenden yakalar. Bir display fonksiyonu yazar ve yanlışlıkla bir alanı değiştirirseniz, derleyici hatanın programınıza sızmasına izin vermek yerine sizi hemen durdurur.
Görev
KolayBir sıcaklık değerini saklayan ve hem salt okunur hem de değiştirme işlemleri sağlayan bir Temperature modülü oluşturalım. Bu, verileri yalnızca okuyan işlevler ile verileri değiştiren işlevler arasında net bir ayrım yapmak için const işaretçilerini kullanma pratiği yapmanıza yardımcı olacaktır.
Üç dosya oluşturacaksınız:
temperature.h: Tek birdouble celsiusüyesine sahip birTemperatureyapısı (struct) bildirin. Ayrıca üç işlev bildirin:temp_display— Temperature yapısına birconstişaretçisi alır ve mevcut sıcaklığı yazdırır (salt okunur)temp_adjust— Temperature yapısına normal bir işaretçi ve bir double miktar alır, ardından bu miktarı celsius değerine ekler (değiştirme)temp_to_fahrenheit— Temperature yapısına birconstişaretçisi alır ve Fahrenheit'a dönüştürülmüş değeri döndürür (salt okunur)
TEMPERATURE_Hsembolü ile include guard kullanın.temperature.c: Her üç işlevi de uygulayın.temp_displayişleviCurrent: {celsius}Cformatında yazdırmalıdır.temp_to_fahrenheitişlevicelsius * 9.0 / 5.0 + 32.0değerini döndürmelidir.constişaretçileri kullanan işlevlerin yapının verilerini değiştiremeyeceğini unutmayın.main.c: Bir Temperature oluşturun, işlemleri gerçekleştirin ve sonuçları görüntüleyin.
İki girdi alacaksınız: başlangıç celsius değeri (double olarak) ve ayarlama miktarı (double olarak).
Ana dosyanızda (main file):
- Başlangıç celsius değeri ile bir
Temperaturebaşlatın - Başlangıç sıcaklığını göstermek için
temp_displayişlevini çağırın - Sıcaklığı ayarlama miktarı kadar değiştirmek için
temp_adjustişlevini çağırın - Güncellenmiş sıcaklığı göstermek için
temp_displayişlevini tekrar çağırın temp_to_fahrenheitkullanarak Fahrenheit dönüşümünü yazdırın
Sonuçları şu formatta yazdırın:
Current: {celsius}C
Current: {celsius}C
Fahrenheit: {fahrenheit}FTüm sıcaklık değerlerini bir ondalık basamakla göstermek için %.1f kullanın.
Örneğin, 20.0 başlangıç değeri ve 5.0 ayarlama miktarı ile çıktı şöyle olacaktır:
Current: 20.0C
Current: 25.0C
Fahrenheit: 77.0FKopya kağıdı
const anahtar kelimesi, bir fonksiyonun işaret edilen veriyi değiştirmeyeceğini belirtmek için işaretçi parametreleriyle birlikte kullanılabilir. Buna const doğruluğu (const correctness) denir.
Bir işaretçi parametresi const olarak işaretlendiğinde, derleyici bu işaretçi aracılığıyla veride yapılacak herhangi bir değişikliği engelleyecektir:
typedef struct {
int x;
int y;
} Point;
// Salt okunur fonksiyon - noktayı değiştiremez
void point_print(const Point *self) {
printf("(%d, %d)\n", self->x, self->y);
// self->x = 10; // HATA: const işaretçi üzerinden değiştirilemez
}
// Değiştiren fonksiyon - noktayı değiştirebilir
void point_move(Point *self, int dx, int dy) {
self->x += dx;
self->y += dy;
}
const Point *self kullanmak, hem derleyiciye hem de diğer programcılara fonksiyonun salt okunur bir işlem olduğunu bildirir. Bu, hataları erkenden yakalamaya yardımcı olur; eğer yanlışlıkla hiçbir şeyi değiştirmemesi gereken bir fonksiyonda veriyi değiştirmeye çalışırsanız, derleyici anında bir hata verecektir.
En iyi uygulama: Fonksiyonun veriyi değiştirmesi gerekmediği her durumda işaretçi parametreleri için const kullanın. Bu, kodunuzun amacını daha net hale getirir ve kazara yapılan değişiklikleri önler.
Kendin dene
#include <stdio.h>
#include "temperature.h"
int main() {
double initial_celsius, adjustment;
scanf("%lf", &initial_celsius);
scanf("%lf", &adjustment);
// TODO: Bir Temperature struct'ı oluşturun ve bunu initial_celsius ile başlatın
// TODO: Başlangıç sıcaklığını göstermek için temp_display fonksiyonunu çağırın
// TODO: Sıcaklığı adjustment miktarı kadar değiştirmek için temp_adjust fonksiyonunu çağırın
// TODO: Güncellenmiş sıcaklığı göstermek için temp_display fonksiyonunu tekrar çağırın
// TODO: temp_to_fahrenheit kullanarak Fahrenheit dönüşümünü yazdırın
// Format: "Fahrenheit: %.1fF\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