Veri tipleri I: primitive, string, enum ve dizi adresleme
Primitive tipler, string tasarımı, enumeration, dizi kategorileri, row-major ve column-major adres formülleri ve associative array. Adres hesabı vizede garanti puan.
Veri tipi, bir değer kümesi ve bu değerler üzerinde tanımlı işlemler kümesidir. Bu sayfa tiplerin “tek başına” olanlarını ve dizileri kapsar. Vizede en garanti soru: iki boyutlu dizinin adresini hesapla. Formülü bilen ve alt sınırları unutmayan herkes alır.
Altın kurallar:
- Row-major’da satır indeksi sütun sayısıyla çarpılır, column-major’da sütun indeksi satır sayısıyla.
- Alt sınır 0 değilse önce çıkar.
- Emin değilsen önde kaç eleman olduğunu say. Formül zaten bunu yapar.
- Floating-point yaklaşıktır, int taşar.
Primitive tipler
Başka tiplerle tanımlanmayan tiplerdir. Çoğu doğrudan donanıma karşılık gelir.
| Tip | Not |
|---|---|
| Integer | Java’da byte, short, int, long (8/16/32/64 bit, işaretli). C/C++‘ta ayrıca unsigned. Negatifler ikiye tümleyen (two’s complement) ile tutulur |
| Floating-point | Gerçel sayıların yaklaşık modeli. IEEE 754: float 32 bit, double 64 bit |
| Decimal | Ondalık tabanda tam temsil (iş uygulamaları, para). COBOL, C# decimal. Bellek israfı ve sınırlı aralık |
| Boolean | true/false. Okunabilirliği artırır. C89’da yok, int kullanılır (0 false) |
| Character | Sayısal kod olarak tutulur. ASCII 8 bit; Java ve C# Unicode (UTF-16) kullanır |
System.out.println('A' + 1); // char int'e yükselir
char c = 'A'; c++;
System.out.println(c);
System.out.println(0.1 + 0.2 == 0.3);
System.out.println(0.1 + 0.2);
int x = Integer.MAX_VALUE; x++;
System.out.println(x);
byte b = (byte) 130;
System.out.println(b);
66
B
false
0.30000000000000004
-2147483648
-126
130, byte aralığına (-128..127) sığmaz; 256 çıkarılır: -126. Taşma ve yaklaşıklık iki ayrı tuzak: int sessizce sarar, double sessizce yuvarlar.
String tipleri
Tasarım soruları: (1) string primitive mi, karakter dizisi mi? (2) uzunluğu statik mi, dinamik mi?
| Uzunluk seçeneği | Örnek |
|---|---|
| Static length | Java String (nesne yaratılınca sabit), COBOL |
| Limited dynamic length | C’de char s[10]: en fazla 9 karakter, sonu '\0' ile işaretli |
| Dynamic length | Perl, JavaScript, C++ std::string |
C’de string ayrı bir tip değildir, '\0' ile biten char dizisidir. strcpy(dest, src) hedefin boyutunu kontrol etmez; taşma güvenlik açığıdır (buffer overflow). Java’da String immutable:
String s = "ab"; String t = s; s = s + "c";
System.out.println(t + " " + s);
StringBuilder sb = new StringBuilder("ab"); StringBuilder sb2 = sb;
sb.append("c");
System.out.println(sb2);
System.out.println(new String("hi") == "hi");
System.out.println(new String("hi").equals("hi"));
ab abc
abc
false
true
Enumeration ve subrange
Enumeration tipi tüm olası değerleri isimli sabitler olarak listeler. Readability artar (Day.MON, 0’dan iyidir) ve reliability artar (Java ve C#‘ta enum’a aritmetik yapılamaz, aralık dışı değer atanamaz).
enum Day { MON, TUE, WED, THU }
System.out.println(Day.WED.ordinal() + " " + Day.valueOf("THU"));
2 THU
C’de enum değerleri int’tir: MON + 1 geçerlidir, herhangi bir int bir enum değişkenine atanabilir. Güvenlik kaybı.
Subrange tipi (Ada, Pascal) bir sıralı tipin ardışık alt kümesidir: type Weekdays is range Mon..Fri;. Aralık dışına çıkışı derleyici/çalışma zamanı yakalar.
Diziler
Dizi, homojen elemanların, ilk elemana göre konumlarıyla (indis, subscript) erişilen topluluğudur. Tasarım soruları: indis tipleri neler? İndis aralığı kontrol ediliyor mu? Ne zaman bellek ayrılıyor? Jagged mı rectangular mı? Dilimleme (slice) var mı?
Dizi kategorileri
| Kategori | Boyut ne zaman? | Yer ne zaman / nerede? | Örnek |
|---|---|---|---|
| Static | Derleme | Çalışmadan önce | C static int a[10]; |
| Fixed stack-dynamic | Derleme | Bildirim işlenince, stack | C fonksiyonunda int a[10]; |
| Stack-dynamic | Çalışma (sonra sabit) | Bildirim işlenince, stack | Ada Get(N); declare A: array (1..N) ... |
| Fixed heap-dynamic | Çalışma (sonra sabit) | Heap, istek üzerine | Java new int[n], C malloc |
| Heap-dynamic | Değişebilir | Heap | Java ArrayList, JavaScript dizileri |
Java ve C# her erişimde indis aralığını kontrol eder; C ve C++ etmez.
int[] a = new int[3];
try { a[3] = 1; } catch (Exception e) { System.out.println(e.getClass().getSimpleName()); }
ArrayIndexOutOfBoundsException
Rectangular dizide her satırın uzunluğu aynı (Fortran, C# int[,]). Jagged dizi dizilerin dizisidir, satır uzunlukları farklı olabilir (Java int[][]).
Dizi adres hesabı
Derleyici bir elemanın adresini bir access function ile hesaplar. Tek boyut, alt sınır lb, eleman boyu size:
İki boyutlu dizi iki şekilde belleğe yerleşir:
- Row-major (C, C++, Java, çoğu dil): satır satır. Önce satır 0’ın tüm elemanları, sonra satır 1…
- Column-major (Fortran): sütun sütun.
m satır, n sütunlu dizi için:
Çözümlü örnek
int A[6][9], base 3000, int 4 byte, A[4][7].
row-major: önde 4 tam satır × 9 = 36, + bu satırda 7 → 43 eleman
3000 + 43 × 4 = 3172
col-major: önde 7 tam sütun × 6 = 42, + bu sütunda 4 → 46 eleman
3000 + 46 × 4 = 3184
Alt sınırı 1 olan Fortran dizisi B(1:5, 1:10), 8 byte, base 500, B(3, 4):
alt sınırları çıkar: satır 3-1 = 2, sütun 4-1 = 3
col-major, m = 5: 3 × 5 + 2 = 17 eleman önde
500 + 17 × 8 = 636
TUZAK · n mi m mi? Row-major’da bir satırı atlamak için o satırdaki tüm sütunları atlarsın, yani n (sütun sayısı) ile çarparsın. Column-major’da bir sütunu atlamak için o sütundaki tüm satırları atlarsın, m ile çarparsın. Karıştırırsan sonuç başka bir elemanın adresi olur ve sınavda kontrol edemezsin.
Slice
Slice, bir dizinin alt yapısıdır; yeni bir veri tipi değil, var olan dizinin bir parçasına erişim yoludur. Python a[1:4], Fortran A(2:4). JavaScript’te slice yeni bir dizi kopyalar:
console.log([10, 20, 30, 40, 50].slice(1, 4));
[ 20, 30, 40 ]
Başlangıç dahil, bitiş hariç.
Associative array
Elemanları sırasız ve anahtarla (key) erişilen topluluk. Perl hash (%h), Python dict, JavaScript Map ve nesneleri, Java HashMap.
const m = new Map([["ali", 70], ["ayse", 85]]);
m.set("ali", 90); m.delete("ayse"); m.set("can", 60);
console.log([...m.keys()].join(","), m.get("ali"), m.size);
ali,can 90 2
Var olan anahtara atama değeri günceller, yeni anahtar eleman ekler. Arama hash ile yapıldığı için sıralı aramadan hızlıdır; ama “i’nci eleman” kavramı yoktur.
Sık yapılan hatalar
| Yanlış | Doğrusu |
|---|---|
| Row-major’da i · m | i · n (sütun sayısı) |
| Alt sınırı 1 olan dizide çıkarma yapmamak | Önce (i - 1), (j - 1) |
0.1 + 0.2 == 0.3 true | false, floating-point yaklaşık |
| int taşınca hata verir | Sessizce sarar: MIN_VALUE |
t = s; s = s + "c"; → t de değişir | String immutable, t eski nesneyi gösterir |
== ile String içeriği karşılaştırmak | equals kullan |
Java new int[n] stack-dynamic | Fixed heap-dynamic |
| C dizi sınırını kontrol eder | Etmez; Java ve C# eder |
Kendini test et
Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.
int A[6][9] is stored in row-major order, indices start at 0, base address 3000, 4-byte integers. What is the address of A[4][7]?
Cevabı göster
Row-major: önce 4 tam satır (4 · 9 = 36 eleman), sonra o satırda 7 eleman: 43 eleman önde. . Formül: base + (i · n + j) · size, n = sütun sayısı.
Same array int A[6][9], base 3000, 4 bytes, but stored in column-major order. Address of A[4][7]?
Cevabı göster
Column-major: önce 7 tam sütun (7 · 6 = 42 eleman), sonra o sütunda 4 eleman: 46 eleman önde. . Column-major'da sütun indeksi satır sayısıyla (m = 6) çarpılır.
A Fortran array B(1:5, 1:10) (column-major, lower bounds 1) has 8-byte elements and base address 500. What is the address of B(3, 4)?
Cevabı göster
Alt sınırları çıkar: satır 3 - 1 = 2, sütun 4 - 1 = 3. Column-major, m = 5 satır: önde 3 · 5 + 2 = 17 eleman. . Alt sınırı çıkarmayı unutmak en yaygın hata.
An array is declared with subscripts -3..7, element size 2 bytes, base address 100. What is the address of the element with subscript 2?
Cevabı göster
Tek boyut: base + (k - lb) · size = 100 + (2 - (-3)) · 2 = 100 + 10 = 110. Alt sınır negatif olunca çıkarma toplamaya döner.
What is printed in Java?
System.out.println('A' + 1);
char c = 'A';
c++;
System.out.println(c);Cevabı göster
char sayısal bir tiptir. 'A' + 1 ifadesinde char int'e yükseltilir: 65 + 1 = 66 (int basılır). c++ ise değişkenin tipini korur: c char kalır, 'B' basılır.
What is printed in Java?
System.out.println(0.1 + 0.2 == 0.3);Cevabı göster
0.1 ve 0.2 ikili tabanda tam temsil edilemez; toplam 0.30000000000000004. Floating-point tipler gerçel sayıların yaklaşık modelidir. Ondalık para hesapları için decimal tipler (C# decimal, Java BigDecimal) vardır.
What is printed in Java?
int x = Integer.MAX_VALUE;
x++;
System.out.println(x);Cevabı göster
int 32-bit ikiye tümleyen (two's complement). En büyük değer ; bir artınca taşar ve en küçük değere döner: . Java taşmayı hata olarak bildirmez.
What is printed in Java?
String s = "ab";
String t = s;
s = s + "c";
System.out.println(t + " " + s);Cevabı göster
Java String nesneleri immutable (değişmez). s + "c" yeni bir nesne yaratır ve s onu gösterir; t hâlâ eski "ab"'yi gösterir. StringBuilder ile aynı kod (append) iki değişkende de "abc" gösterirdi, çünkü o nesne değişebilir (mutable).
What is printed in Java?
System.out.println(new String("hi") == "hi");
System.out.println(new String("hi").equals("hi"));Cevabı göster
== referansları (adresleri) karşılaştırır: new her zaman yeni nesne yaratır, adres farklı. equals içerikleri karşılaştırır. String tasarımında "string primitive mi, nesne mi?" sorusunun sonucu bu.
Given enum Day { MON, TUE, WED, THU } in Java, what does Day.WED.ordinal() return? Can you write Day.MON + 1 in Java?
Cevabı göster
ordinal sıfırdan başlar: MON 0, TUE 1, WED 2. Java ve C#'ta enum ayrı bir tiptir, aritmetik yapılamaz ve int'e otomatik dönüşmez (reliability). C'de enum değerleri int'e coercion edilir, MON + 1 geçerlidir.
Classify each array by category: (a) a local int a[10]; in a C function; (b) int[] a = new int[n]; in Java; (c) a Java ArrayList; (d) static int a[10]; in C.
Cevabı göster
Fixed stack-dynamic: boyut derlemede sabit, yer çağrıda stack'te. Fixed heap-dynamic: boyut çalışmada belirlenir ama sonra değişmez, heap'te. Heap-dynamic: boyut çalışma boyunca büyüyüp küçülebilir. Static: boyut ve yer çalışmadan önce sabit.
What is printed in Java?
int[] a = new int[3];
try { a[3] = 1; }
catch (Exception e) { System.out.println(e.getClass().getSimpleName()); }Cevabı göster
Java her dizi erişiminde indis aralığını kontrol eder (range checking). Geçerli indisler 0..2. C ve C++ kontrol etmez: a[3] başka bir belleğe yazar, tanımsız davranış. Kontrol reliability kazandırır, çalışma maliyeti getirir.
Doğrulama: Java çıktıları JDK ile çalıştırıldı (java verify/SEN2001/W05.java). Adres cevapları node ile formülden hesaplandı ve ayrıca diziyi bellekte gerçekten satır satır / sütun sütun yerleştirip elemanın sırasını sayarak kontrol edildi (verify/SEN2001/05.mjs); associative array ve slice örnekleri JavaScript Map ve slice ile çalıştırıldı.