Polito C: Array, Matrix, String ve Struct ile Veri Modeli Seçimi

Polito Programming Techniques için array, matrix, string ve struct seçimini üç özgün C17 problemiyle çalışın: veri modeli, kapasite, invariant ve sınır testleri.

📅Yayın:
Harun BüyükçolakHarun Büyükçolak, Full Stack Developer
Polito C: Array, Matrix, String ve Struct ile Veri Modeli Seçimi

Yazı içeriği

Polito C / Programming Techniques çalışırken aynı yerde takılıyor olabilirsiniz: döngüyü yazabiliyorsunuz ama veriyi array, matrix, string veya struct olarak nasıl tutacağınız netleşmiyor. Sonra çözüm büyüdükçe indeksler karışıyor, etiket kesiliyor veya bir kaydın alanları birbirinden kopuyor. İlk düzeltilecek şey çoğu zaman döngü değil, problemin veri modelidir.

Bu rehberde üç özgün problemi çözeceğiz: oda doluluğunu matrix'ten bir özet array'ine dönüştürmek, kapasiteyi aşmadan doğrulanmış bir etiket saklamak ve rezervasyonları struct kayıtlarıyla seçmek. Örnekler bağımsız C17 pratiği için hazırlanmıştır; resmî sınav soruları veya değerlendirilecek öğrenci teslimleri değildir. Her programı tek başına derleyebilirsiniz.

Ders bağlamı: 'da kontrol edilen 02OJP Programming Techniques 2026/27 kılavuzu, array, matrix, string ve struct kullanımını; uygun veri yapısı seçimi ve C ile problem çözmeyle birlikte ele alır. Ders kimliği ve grup ayrıntıları için güncel Polito Programming Techniques rehberine bakın. Bu yazı bir çalışma önerisidir, sınav formatı duyurusu değildir.

1. Veri modeli seçimini dört soruyla yapın

Önce her elemanın neyi temsil ettiğini bir cümleyle yazın. Ardından dört soru sorun: kaç bağımsız boyut var, elemanlar aynı türden mi, hangi alanlar aynı kayda ait ve hangi işlemler yapılacak? Cevabı “buraya array koyarım” diye değil, “her indeks bir odayı temsil eder” diye kurun. Temsilin anlamı belirginleşmeden bildirim yazmak, yanlış düzeni kodla telafi etmeye çalışmanıza yol açar.

  • Array: aynı türden bir koleksiyon; her odanın yoğun oturum sayısı.
  • Matrix: iki ekseni olan veri; oda ve oturum başına kişi sayısı.
  • String: metin sözleşmesi olan karakter dizisi; bir oda etiketi.
  • Struct: tek varlığa ait farklı anlamdaki alanlar; odası, zamanı ve durumu olan rezervasyon.

Bunlar rakip seçenekler değildir: struct içinde string, struct dizisinde çok sayıda kayıt bulunabilir. Seçtiğiniz modelin yanında kapasiteyi, kullanılan eleman sayısını ve korunacak kuralı da yazın. Kural, yani invariant, işlem ilerlerken doğru kalması gereken ifadedir. Örneğin “her kayıt için oda etiketi ile zaman bilgisi birlikte kalır” bir veri modeli kuralıdır.

2. Problem bir: oda ve oturum bilgisini matrix'te tutun

Bir atölyenin üç odasında, dört farklı oturumdaki kişi sayıları kaydediliyor. En az altı kişinin bulunduğu oturum “yoğun” kabul ediliyor. Her oda için yoğun oturum sayısını istiyoruz; toplam katılımcı sayısını değil. Girdi iki eksenli olduğu için matrix, çıktı oda başına tek değer taşıdığı için array seçiyoruz. Satırı oda, sütunu oturum olarak sabitliyoruz.

İlk oda 8, 2, 6, 5 değerlerini taşıyor ve iki yoğun oturuma sahip. Eşiğe eşit 6 sayılıyor. Diğer odaların sonuçları üç ve iki. Koddan önce kâğıda 2, 3, 2 yazın. “Yoğun” kelimesinin anlamını değiştirirseniz karşılaştırma ve beklenen sonuç birlikte değişmelidir.

room_occupancy.cC
#include <stddef.h>#include <stdio.h>enum { ROOMS = 3, SLOTS = 4 };void count_busy_slots(const int occupied[][SLOTS], size_t rows,                      int threshold, size_t busy[]){    for (size_t room = 0; room < rows; ++room) {        busy[room] = 0;        for (size_t slot = 0; slot < SLOTS; ++slot) {            if (occupied[room][slot] >= threshold) {                ++busy[room];            }        }    }}int main(void){    const int occupied[ROOMS][SLOTS] = {        {8, 2, 6, 5},        {1, 6, 7, 9},        {6, 6, 0, 3}    };    size_t busy[ROOMS];    count_busy_slots(occupied, ROOMS, 6, busy);    for (size_t room = 0; room < ROOMS; ++room) {        printf("%zu%s", busy[room], room + 1 == ROOMS ? "\n" : " ");    }    return 0;}

Programın çıktısı 2 3 2'dir. Dış döngünün her adımı bir çıktıyı tamamlar. İç döngü başında busy[room], o odada daha önce incelenmiş oturumların yoğun olanlarını sayar. Yeni satıra geçerken sayacın sıfırlanması bu anlamı korur; sıfırlamayı iki döngünün dışına taşırsanız odaları birbirine katarsınız.

3. Matrix boyutlarını ve sınırlarını ayrı test edin

Bu örnekte sütun sayısı SLOTS ile sabittir. Fonksiyona verilen her satır tam dört int elemanı taşır; rows işlenecek satır sayısını belirtir. Çağıran, en az o kadar geçerli satır ve aynı sayıda yazılabilir çıktı elemanı sağlamalıdır. Sütun sayısını başka bir değerle varsayan fonksiyona aynı nesneyi vermek, yalnız yanlış sonuç riski değildir; erişim sözleşmesini de bozar.

Gerçek iki boyutlu C array'i, satır array'lerinden oluşur. occupied[room][slot] yazarken iki indeksin sınırını ayrı koruyun. Toplam on iki eleman bulunması, occupied[0][4] erişimini geçerli yapmaz: ilk satırda yalnız 0 ile 3 arası indeksler vardır. Matrix'i int ** olarak etiketlemek de aynı veri düzenini sağlamaz.

Özet array, girdi matrix'iyle çakışmayan ayrı bir nesnedir. Bu örnekte matrix yalnız okunur; sonuçları girdinin üstüne yazarak aynı anda hem tarama hem dönüştürme yapmayı amaçlamıyoruz.

Eşiğin hemen altını, eşitini ve üstünü aynı satırda test edin. Bütün hücrelerin sıfır olduğu girdide sonuçlar sıfırdır; bütün hücreler altı olduğunda her sonuç dörttür. Fonksiyonu yalnız ilk satır için çağırıp çıktının sonraki elemanlarını başlangıçtaki test değerlerinde bırakmasını kontrol edin. Sıfır satırla çağırdığınızda hiçbir çıktı elemanı değişmemelidir.

4. Problem iki: string kapasitesini iş kuralıyla birlikte tasarlayın

Oda etiketini en fazla yedi karakter olarak saklayalım. İzin verilen karakterler büyük Latin harfleri, rakamlar ve tire olsun; boş etiket reddedilsin. Hedef kapasite sekiz char elemanıdır: yedi veri elemanı ve sonlandırıcı. Bu, kullanıcı arayüzünde görünen karakter sayısını her dilde byte sayısıyla eşitleyen bir Unicode çözümü değildir; sınırlı etiket alfabesi kullanıyoruz.

Girdiyi uzunluğu bilinen bir karakter tamponu olarak alıyoruz. Kaynakta sonlandırıcı bulunması şart değil; çağıran belirtilen uzunluk kadar okunabilir eleman sağlamalıdır. Hedef kapasitesi kadar yazılabilir alan bulunmalı ve kaynakla hedef çakışmamalıdır. Başarıda yeni string saklanacak, reddedilen girdide eski etiket korunacak. Önce bütün karakterleri denetlememizin nedeni bu son kuraldır.

validated_label.cC
#include <stddef.h>#include <stdio.h>#include <string.h>int set_label(char destination[], size_t capacity,              const char source[], size_t length){    const char allowed[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";    if (length == 0 || capacity == 0 || length >= capacity) {        return 0;    }    for (size_t i = 0; i < length; ++i) {        if (source[i] == '\0' || strchr(allowed, source[i]) == NULL) {            return 0;        }    }    for (size_t i = 0; i < length; ++i) {        destination[i] = source[i];    }    destination[length] = '\0';    return 1;}int main(void){    char label[8] = "OLD";    const char valid[] = {'L', 'A', 'B', '-', '2', '0', '4'};    const char too_long[] = "LAB-2048";    int accepted = set_label(label, sizeof label, valid, sizeof valid);    printf("%d %s\n", accepted, label);    accepted = set_label(label, sizeof label, too_long, sizeof too_long - 1);    printf("%d %s\n", accepted, label);    return 0;}

Çıktı önce 1 LAB-204, sonra 0 LAB-204 olur. İlk girdi tam yedi elemanla sığar; ikinci girdi sekiz eleman olduğundan sonlandırıcıya yer kalmaz ve kopyalama başlamaz. length >= capacity kontrolü, uzunluğa bir ekleyip taşma riski oluşturmadan yer gereksinimini ifade eder. Kapasite ve uzunluk geçerli nesneler hakkında doğru bilgi vermelidir; bu kontrol yanlış bildirilen kapasiteyi keşfetmez.

5. String testinde yalnız görünen metni karşılaştırmayın

Başarı için dönüş değerini, ilk yedi veri elemanını ve doğru yerdeki \0 karakterini kontrol edin. Reddedilen girdide hedefin bütün elemanları önceki hâliyle aynı kalmalıdır. Boş girdi, kapasite sıfır, kapasiteden bir kısa uzunluk, kapasiteye eşit uzunluk, küçük harf, boşluk ve araya yerleşmiş sıfır karakteri ayrı testler olsun.

Kodda sıfır karakterini ayrıca reddediyoruz çünkü strchr, izin listesi string'inin sonlandırıcısını da bulabilir. Bu ayrıntıyı atlamak, etiketin ortasına sonlandırıcı kabul etmek demektir. Ayrıca strlen kullanarak keyfî kaynak tamponunun sınırını bulmaya çalışmıyoruz: bu fonksiyon zaten geçerli, sonlandırılmış bir string ister. Boyutu bilinen ham tampon ile C string'i aynı sözleşme değildir.

Bu alıştırmada uzun girdiyi sessizce kesmek yerine reddediyoruz. Çünkü iki farklı oda etiketi kesilince aynı ada dönüşebilir. Kesme veya reddetme kararı sadece bellek ayrıntısı değil, uygulamanın kimlik politikasıdır. SEI CERT STR31-C, string verisiyle sonlandırıcı için yeterli alan ayrılmasını; STR32-C ise sonlandırılmamış dizilerin string bekleyen fonksiyonlara verilmemesini açıklar.

6. Problem üç: rezervasyon alanlarını struct ile bir arada tutun

Bir rezervasyonun oda etiketi, başlangıç dakikası, bitiş dakikası ve onay durumu var. Süresi en az 45 dakika olan ilk onaylı rezervasyonu arıyoruz. “İlk”, mevcut array sırasındaki ilk eşleşme demektir; en erken başlayan veya en uzun rezervasyon değildir. Bu seçimleri birbirinin yerine kullanmayın.

Saatleri gün başlangıcından itibaren dakika olarak tutuyoruz. Geçerli kayıt için 0 <= begin < end <= 1440 kuralı var; gece yarısını geçen rezervasyon bu modelin dışında. Dört paralel array kurmak mümkündür fakat kayıt taşınırken bir alanı unutmak kolaydır. Struct, aynı rezervasyona ait alanların tek kayıt olarak taşınmasını sağlar; alanların doğruluğunu ise sizin kurallarınız belirler.

booking_records.cC
#include <stdbool.h>#include <stddef.h>#include <stdio.h>typedef struct {    char room[8];    unsigned begin;    unsigned end;    bool confirmed;} Booking;size_t first_long_booking(const Booking bookings[], size_t n,                          unsigned minimum_minutes){    for (size_t i = 0; i < n; ++i) {        if (bookings[i].confirmed &&            bookings[i].begin < bookings[i].end &&            bookings[i].end <= 1440 &&            bookings[i].end - bookings[i].begin >= minimum_minutes) {            return i;        }    }    return n;}int main(void){    const Booking bookings[] = {        {"LAB-101", 540, 570, true},        {"LAB-204", 600, 690, false},        {"LAB-305", 720, 780, true}    };    size_t n = sizeof bookings / sizeof bookings[0];    size_t found = first_long_booking(bookings, n, 45);    if (found == n) {        puts("uygun kayit yok");    } else {        printf("%s %u\n", bookings[found].room,               bookings[found].end - bookings[found].begin);    }    return 0;}

Program LAB-305 60 yazdırır. İlk kayıt onaylı fakat yalnız 30 dakikadır; ikinci kayıt 90 dakika olmasına rağmen onaysızdır. Üçüncü kayıt iki koşulu birlikte sağlar. Uygun kayıt yoksa fonksiyon n döndürür; çağıran bu değeri indeks olarak kullanmadan önce kontrol eder.

7. Struct içindeki kuralları işlem sırasıyla koruyun

Fonksiyonda zaman aralığı kontrolü, süre çıkarma işleminden önce yapılır. Böylece bitişin başlangıçtan küçük olduğu bozuk kaydı, işaretsiz çıkarma sonucunu büyük bir süre sanarak seçmeyiz. Bu örnek geçersiz aralıklı kayıtları atlar. Gerçek bir uygulamada kullanıcıya hata vermek veya veriyi girişte reddetmek isteyebilirsiniz; hata politikasını açıkça yazın.

Struct bildirimi, başlangıcın bitişten küçük olmasını kendiliğinden zorunlu kılmaz. Benzer şekilde room[8], rastgele doldurulduğunda otomatik geçerli etiket değildir. Örnekte başlatıcılar sonlandırılmış etiketler sağlar; dış girdiyi kullanırken önceki problemin doğrulama sözleşmesi gerekir. Koleksiyondan kayıt seçmekle kaydı oluşturup doğrulamak farklı sorumluluklardır.

Süre tam eşik kadar, eşikten bir kısa ve bir uzun olsun. Onaysız uzun kayıt, ters zaman aralığı, aynı başlangıç ve bitiş, günü aşan bitiş ve sıfır kayıt deneyin. İki uygun kayıt varsa mevcut sıradaki ilki dönmelidir. Sonra bütün kayıtların sırasını değiştirin: sonucu belirleyen politikanın “ilk” olduğunu test ederek görün.

8. Üç problemi tek büyük döngüye sıkıştırmayın

Şimdi bu atölye için küçük bir rapor tasarlayın. Oda doluluk tablosu matrix olarak kalsın; her odanın yoğun oturum sayısı bir özet array'i olsun; oda etiketleri doğrulansın; rezervasyonlar struct koleksiyonunda tutulsun. Bu verilerin aynı odayı nasıl işaretlediğini ayrıca belirleyin: burada öğrendiğimiz etiket doğrulaması, tek başına benzersizlik kontrolü değildir.

Yeni gereksinimi ayrı yazın: örneğin her oda için yoğun oturum sayısını ve ilk uygun rezervasyonu göstermek. Önce küçük fonksiyonları kendi testleriyle koruyun, ardından raporlama katmanını ekleyin. Bir hatada veri modeli mi, seçim koşulu mu, yoksa yazdırma mı yanlış, ayırabilmelisiniz. Girdi okumayı da eklerseniz okuma başarısı ve biçim kontrolü yeni sözleşmeler olacaktır.

Matrix taraması bütün hücreleri inceler; R oda ve S oturum için işlem sayısı bunların çarpımıyla büyür. Kayıt seçimi ilk eşleşmede durabilir, en kötü durumda bütün kayıtları tarar. Bu çıkarımlar kendi döngülerinizin analizidir; üç oda ve dört oturumluk tek bir süre ölçümünden genel performans sonucu çıkarmayın.

9. Academy Lab'de gözleyin, bağımsız derleyicide doğrulayın

Algorithm Visualizer rehberindeki kaynak satırı, veri durumu ve trace yaklaşımını kullanın: hazır bir tarama veya seçim örneğinde adımı ilerletmeden önce hangi indeksin ve sonucun değişeceğini tahmin edin. Katalogdaki örneğin diliyle kendi C çözümünüzü ayırın; aynı algoritmik fikir, aynı string kapasitesi sözleşmesi anlamına gelmez.

Buradaki üç programın Visualizer'da hazır bulunduğunu veya araca yapıştırılıp çalıştırılabildiğini varsaymıyoruz. Örnekleri ayrı dosyalara kaydedip cc -std=c17 -Wall -Wextra -Wpedantic room_occupancy.c -o room_occupancy gibi bir komutla derleyin; diğer dosyalarda isimleri değiştirin. Derlemenin geçmesi indeks sınırlarını ispatlamaz. Beklenen çıktı, değişmemesi gereken veri ve sınır testleri ayrı kontrol edilmelidir.

Çalışma kaydınızda dört kanıt bulunsun: veri modeli çizimi, döngü kuralı, çalıştırılmış test çıktıları ve yardım almadan yazdığınız küçük değişiklik. Kodu kapatıp eşiği, etiket politikasını veya kayıt seçim koşulunu değiştirin. Hangi eski testlerin geçerliliğini koruduğunu, hangilerinin yeni beklenen sonuç gerektirdiğini açıklayın. Araçların genel giriş noktası Academy Lab sayfasıdır.

10. Polito C hazırlığında sonraki adımı hatanıza göre seçin

Matrix'te oda ve oturumu karıştırdıysanız boyut çizimine; string'de hedefi erken değiştirdiyseniz hata sözleşmesine; struct'ta yanlış kaydı seçtiyseniz seçim politikasına dönün. Daha fazla kod görmekten önce aynı küçük problemi farklı sınır girdilerinde açıklayabilin. Fonksiyon parametresi ve nesne etkisi karışıyorsa Python'dan C'ye geçiş rehberi bu yazının ön koşulunu tamamlar.

Ders kodunuz, hedef tarihiniz ve hata kaydınızla Polito C / Programming Techniques özel ders sürecini inceleyebilirsiniz. Birebir çalışmanın amacı, öğrencinin temsil seçimini ve kendi çözümünü savunabilmesidir. Daha geniş hazırlık düzeni için sekiz haftalık çalışma rotasını kullanın; bütün Polito ders kaynakları üniversite merkezinde yer alır.

C dilinin array alt indisleri için 6.5.2.1, struct türleri için 6.7.2.1 ve string tanımı için 7.1.1 bölümleri WG14 N1570 C11 komite taslağında okunabilir. Bu kamuya açık referans güncel nihai standart olarak sunulmuyor; buradaki bağımsız programların derleme hedefi C17'dir.

Websoftik Academy, Politecnico di Torino'dan bağımsızdır. Resmî kurallar için kendi öğretim grubunuzun güncel duyuruları esas alınır. Bu rehber başarı garantisi vermez; değerlendirilecek ödev veya sınav öğrenci yerine çözülmez.

Sonraki Adım: Bunları da Oku

Bu yazıyı tamamladıysan, bir sonraki seviyeye geçmek için şu içeriklerle devam etmeni öneririz:

Ders kodunuza göre çalışma planı

Müfredatınızı, sınav tarihinizi ve zorlandığınız bir soruyu birlikte inceleyerek birebir ders ve Lab pratiği için uygun sırayı belirleyebiliriz.

Polito Programming Techniques (C) özel ders planı →

Hedefe Uygun Ders Planını Netleştirelim

Sınav, proje ve ders hedefinize göre haftalık çalışma planı ile kontrollü ilerleyelim.

WhatsApp