Menu
Coddy logo textTech

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.

challenge icon

Görev

Kolay

Bir 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 bir double celsius üyesine sahip bir Temperature yapısı (struct) bildirin. Ayrıca üç işlev bildirin:
    • temp_display — Temperature yapısına bir const iş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 bir const işaretçisi alır ve Fahrenheit'a dönüştürülmüş değeri döndürür (salt okunur)
    TEMPERATURE_H sembolü ile include guard kullanın.
  • temperature.c: Her üç işlevi de uygulayın. temp_display işlevi Current: {celsius}C formatında yazdırmalıdır. temp_to_fahrenheit işlevi celsius * 9.0 / 5.0 + 32.0 değerini döndürmelidir. const iş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):

  1. Başlangıç celsius değeri ile bir Temperature başlatın
  2. Başlangıç sıcaklığını göstermek için temp_display işlevini çağırın
  3. Sıcaklığı ayarlama miktarı kadar değiştirmek için temp_adjust işlevini çağırın
  4. Güncellenmiş sıcaklığı göstermek için temp_display işlevini tekrar çağırın
  5. temp_to_fahrenheit kullanarak Fahrenheit dönüşümünü yazdırın

Sonuçları şu formatta yazdırın:

Current: {celsius}C
Current: {celsius}C
Fahrenheit: {fahrenheit}F

Tü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.0F

Kopya 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;
}
quiz iconKendini test et

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