MERHABA! CodeGym'de ilerledikçe birçok kez ilkel türlerle karşılaştınız. İşte onlar hakkında bildiklerimizin kısa bir listesi:
- Nesne değildirler ve bellekte saklanan bir değeri temsil ederler.
- birkaç çeşit var
- Tam sayılar: bayt , kısa , int , uzun
- Kayan noktalı (kesirli) sayılar: kayan nokta ve çift
- Mantıksal değerler: boole
- Sembolik değerler (harfleri ve sayıları temsil etmek için): char
-
Her türün kendi değer aralığı vardır:
ilkel tip |
Bellekteki boyut |
Değer aralığı |
bayt |
8 bit |
-128 ila 127 |
kısa |
16 bit |
-32768 ila 32767 |
karakter |
16 bit |
0 ila 65536 |
int |
32 bit |
-2147483648 ila 2147483647 |
uzun |
64 bit |
-9223372036854775808 ila 9223372036854775807 |
batmadan yüzmek |
32 bit |
(2 üzeri -149) ila ((2 - (2 üzeri -23)) * 2 üzeri 127) |
çift |
64 bit |
(-2 üzeri 63) ila ((2 üzeri 63) - 1) |
mantıksal |
8 (dizilerde kullanıldığında), 32 (dizilerde kullanılmadığında) |
doğru ya da yanlış |
Ancak farklı değerlere sahip olmanın yanı sıra, bellekte ne kadar yer kapladıkları konusunda da farklılık gösterirler. Bir
int, bir bayttan daha fazlasını alır. Ve
uzun , kısadan daha büyüktür. İlkellerin kapladığı bellek miktarı, Rus oyuncak bebekleriyle karşılaştırılabilir:
Her yuvalama bebeğinin içinde kullanılabilir alan vardır. Yuvalama bebeği ne kadar büyükse, o kadar fazla alan vardır. Büyük bir yuvalama bebeği (
uzun ), daha küçük bir int'yi kolayca barındırır . Kolayca sığar ve başka bir şey yapmanıza gerek yoktur. Java'da, ilkellerle çalışırken buna örtük dönüştürme denir. Ya da başka bir deyişle, buna genişleme denir.
Java'da Genişletme
İşte genişleyen bir dönüştürmenin basit bir örneği:
public class Main {
public static void main(String[] args) {
int bigNumber = 10000000;
byte littleNumber = 16;
bigNumber = littleNumber;
System.out.println(bigNumber);
}
}
Burada bir int değişkenine bir bayt değeri atadık . Atama sorunsuz bir şekilde başarılı olur: bir baytta depolanan değer, bir
int'nin barındırabileceğinden daha az bellek kaplar. Küçük yuvalama bebeği (bayt değeri), büyük yuvalama bebeğinin (
int değişkeni) içine kolayca sığar. Tersini yapmaya çalışırsanız, yani aralığı bu kadar büyük bir veri tipini barındıramayan bir değişkene büyük bir değer koymaya çalışırsanız, bu farklı bir konudur. Gerçek yuvalama bebekleriyle, sayı uymazdı. Java ile yapabilir, ancak nüanslarla.
Kısa bir değişkene bir
int koymayı deneyelim :
public static void main(String[] args) {
int bigNumber = 10000000;
short littleNumber = 1000;
littleNumber = bigNumber;
System.out.println(bigNumber);
}
Hata!
Derleyici, büyük bir yuvalama bebeğini ( int ) küçük bir bebeğin (
kısa ) içine sokarak anormal bir şey yapmaya çalıştığınızı anlar . Bu durumda, derleme hatası derleyiciden gelen bir uyarıdır: "Hey, bunu yapmak istediğinizden
kesinlikle emin misiniz?" Eminseniz derleyiciye
"Her şey yolunda. Ne yaptığımı biliyorum!" Bu işleme, açık tip dönüştürme veya daraltma denir.
Java'da daraltma
Daraltma dönüştürmesi gerçekleştirmek için, değerinizi dönüştürmek istediğiniz türü açıkça belirtmeniz gerekir. Başka bir deyişle, derleyicinin sorusuna cevap vermeniz gerekir:
"Peki, bu büyük yuvalama bebeğini bu küçük yuvalama bebeklerinden hangisine koymak istersiniz?" Bizim durumumuzda, şöyle görünür:
public static void main(String[] args) {
int bigNumber = 10000000;
short littleNumber = 1000;
littleNumber = (short) bigNumber;
System.out.println(littleNumber);
}
Kısa bir değişkene
int koymak istediğimizi ve sorumluluğu üstleneceğimizi açıkça belirtiyoruz. Daha dar bir türün açıkça belirtildiğini gören derleyici dönüştürmeyi gerçekleştirir. Sonuç ne? Konsol çıktısı:
-27008 Bu biraz beklenmedikti. Bunu tam olarak neden aldık? Aslında, her şey çok basit. Başlangıçta, değer 10000000 idi . 32 bitlik bir
int değişkeninde saklanıyordu . Bu onun ikili temsilidir:
Bu değeri sadece 16 bit saklayabilen
kısa bir değişkene yazıyoruz ! Buna göre numaramızın sadece ilk 16 biti oraya taşınacaktır. Gerisi atılacak. Sonuç olarak, kısa değişken aşağıdaki değeri alır
ondalık biçimde -27008'e eşittir Bu nedenle derleyici, belirli bir türe açık bir daraltma dönüştürmesini belirterek "onaylamanızı" ister. İlk olarak, bu sonuç için sorumluluk aldığınızı gösterir. İkincisi, derleyiciye dönüştürme sırasında ne kadar alan ayrılacağını söyler.
Sonuçta, son örnekte, bir byte değişkenine short yerine bir int değeri atasaydık , elimizde 16 değil, yalnızca 8 bit olurdu ve sonuç farklı olurdu. Kesirli tipler (
float ve
double ), dönüşümleri daraltmak için kendi süreçlerine sahiptir. Kesirli bir sayıyı tamsayı türüne dönüştürmeye çalışırsanız, kesirli kısım atılacaktır.
public static void main(String[] args) {
double d = 2.7;
long x = (int) d;
System.out.println(x);
}
Konsol çıkışı:
2
karakter
char'ın tek tek karakterleri görüntülemek için kullanıldığını zaten biliyorsunuz .
public static void main(String[] args) {
char c = '!';
char z = 'z';
char i = '8';
}
Ancak bu veri türünün anlaşılması önemli olan birkaç özelliği vardır. Değer aralıkları tablosuna tekrar bakalım:
ilkel tip |
Bellekteki boyut |
Değer aralığı |
bayt |
8 bit |
-128 ila 127 |
kısa |
16 bit |
-32768 ila 32767 |
karakter |
16 bit |
0 ila 65536 |
int |
32 bit |
-2147483648 ila 2147483647 |
uzun |
64 bit |
-9223372036854775808 ila 9223372036854775807 |
batmadan yüzmek |
32 bit |
(2 üzeri -149) ila ((2 - (2 üzeri -23)) * 2 üzeri 127) |
çift |
64 bit |
(-2 üzeri 63) ila ((2 üzeri 63) - 1) |
mantıksal |
8 (dizilerde kullanıldığında), 32 (dizilerde kullanılmadığında) |
doğru ya da yanlış |
Karakter türü için 0 ila 65536 aralığı belirtilir . Ama bu ne anlama geliyor? Sonuçta, bir
karakter sadece sayıları değil, aynı zamanda harfleri, noktalama işaretlerini de temsil eder… Mesele şu ki, Java'da
char değerleri Unicode formatında saklanır. Önceki derslerden birinde Unicode ile zaten karşılaştık. Unicode'un dünyadaki hemen hemen tüm yazılı dillerin sembollerini içeren bir karakter kodlama standardı olduğunu muhtemelen hatırlıyorsunuzdur. Başka bir deyişle, herhangi bir dildeki hemen hemen her karakteri temsil eden özel kodların bir listesidir. Unicode tablosunun tamamı çok büyük ve elbette ezberlemeye gerek yok. İşte küçük bir kısmı:
Ana şey, karakterlerin nasıl saklandığını anlamak ve belirli bir karakterin kodunu biliyorsanız, o karakteri programınızda her zaman üretebileceğinizi hatırlamaktır. Rastgele bir sayı ile deneyelim:
public static void main(String[] args) {
int x = 32816;
char c = (char) x ;
System.out.println(c);
}
Konsol çıktısı: 耰 Bu, Java'da
char s depolamak için kullanılan biçimdir . Her sembol bir sayıya karşılık gelir: 16 bitlik (iki baytlık) bir sayısal kod. Unicode'da 32816, Çince 耰 karakterine karşılık gelir. Aşağıdaki noktayı not edin. Bu örnekte bir
int değişkeni kullandık. Hafızada 32 bit yer kaplar, bir
char ise 16 bit yer kaplar. Burada bir int seçtik çünkü numaramız (32816) bir
short'a sığmaz .
Bir karakterin boyutu (tıpkı bir
kısa gibi) 16 bit olmasına rağmen, karakter aralığında negatif sayılar yoktur , bu nedenle
karakterin "pozitif" kısmı
aralık iki kat daha geniştir ( kısa tip için 32767 yerine 65536 ).
Kodumuz 65536'nın altında kaldığı sürece int kullanabiliriz. Ancak 65536'dan büyük bir
int değeri oluşturursanız , o zaman 16 bitten fazla yer kaplar. Bu da daraltıcı bir dönüşümle sonuçlanacak
char c = (char) x;
ekstra bitler atılacak (yukarıda tartışıldığı gibi) ve sonuç oldukça beklenmedik olacaktır.
Karakter ve tam sayı eklemenin özel özellikleri
Alışılmadık bir örneğe bakalım:
public class Main {
public static void main(String[] args) {
char c = '1';
int i = 1;
System.out.println(i + c);
}
}
Konsol çıktısı:
50 O_О Bu nasıl mantıklı? 1+1. 50 nerden çıktı
char
Değerlerin bellekte 0 ile 65536 arasında sayılar olarak saklandığını ve bu sayıların bir karakterin Unicode gösterimi olduğunu zaten biliyorsunuz .
Bir char ve bir tür tam sayı
eklediğimizde ,
char karşılık gelen Unicode numarasına dönüştürülür. Kodumuzda 1 ve '1' eklediğimizde '1' sembolü kendi kodu olan 49'a dönüştürüldü (bunu yukarıdaki tablodan doğrulayabilirsiniz). Bu nedenle sonuç 50'dir. Eski dostumuz 耰'yi bir kez daha örnek olarak alalım ve onu bir sayıya eklemeye çalışalım.
public static void main(String[] args) {
char c = '耰';
int x = 200;
System.out.println(c + x);
}
Konsol çıktısı:
33016 耰'nin 32816'ya karşılık geldiğini zaten keşfettik. Ve bu sayı ile 200'ü topladığımızda sonucumuz oluyor: 33016. :) Gördüğünüz gibi buradaki algoritma oldukça basit ama unutmamalısınız. .