İfade (expression) adı verilen yapı içinde, program değişken ve sabitlerden oluşan verilere işlemciler yoluyla bir işlem yapar. Artık, ifadeleri oluşturan veri kavramını incelemeye başlayabiliriz.
C++'de aşağıda gösterilen 7 temel veri çeşidi vardır:
Anahtar kelime | Veri türü |
---|---|
bool | İkili |
char | Karakter |
int | Tamsayı |
float | Kayan noktalı sayı |
double | Çift duyarlıklı kayan noktalı sayı |
void | Değersiz |
wchar_t | Geniş karakter |
Sadece char, int ve double veri türlerinin önüne aşağıda gösterilen değiştiricileri koyarak, veri tiplerinin işaret (+/-) durumunu, byte olarak boyutlarını ve sınırlarını değiştirebiliriz. C++'da kullanılan veri türü değiştiricileri ve uygulandıkları veri türleri aşağıda gösterilmektedir:
Değiştirici | Uygulandığı veri türü |
---|---|
signed | char, int |
unsigned | char, int |
long | int, double |
short | int |
Değişken tanımlamalarında signed değiştirici ifadesi kullanıldığında, tanımlanan değişkenin ikili sayı sistem değeri içinde en üst sırada yer alan bit'i işaret bit'i olarak kullanılır. Bu değer 0 olursa sayı pozitif, 1 olursa sayı negatif olur. Ancak, bu durumda bir bit sayının işaretini belirlemek için ayrıldığından tanımlanan değişkene atanacak değer otomatik olarak azalır.
Bilgisayarlarda, bir sayının ikili sayı sisteminde gösteriminde en solda yer alan bit, sayının negatif veya pozitif olduğunu göstermek üzere, işaret bit'i olarak kullanılır.
Pozitif bir sayıyı negatif bir sayıya çevirmek için, sayıdaki bütün bit değerlerinin tersi alınır ve elde edilen sayıya 1 değeri eklenir. Biri signed diğeri unsigned olan iki adet char ve iki adet short int veri türünden değişken tanımlayalım:
signed char cd; // Alabileceği maksimum değer : 127 => 0 1 1 1 1 1 1 1
unsigned char ucd; // Alabileceği maksimum değer : 255 => 1 1 1 1 1 1 1 1
short int sid; // Alabileceği maksimum değer : 32767 => 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
unsigned short int usid; // Alabileceği maksimum değer : 65535 => 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
cd ve sid değişkenleri için el solda yer alan değer işaret bit'i olarak kullanıldığından, değişkenlerin alabileceği maksimum değer sırasıyla 127 ve 32767 olacaktır. ucd ve usid değişkenleri en solda yer alan bit'i sayı değerleri için kullanabileceğinden, değişkenlerin alabileceği maksimum değer sırasıyla 255 ve 65535 olacaktır.
C++'da, unsigned, short veya long int değerlerin bildirimi yapılırken int ifadesinin kullanılması tamamen isteğe bağlıdır. Başka bir ifade ile, bu tip tanımlamalarda int ifadesini kullanmayabiliriz. Örneğin, aşağıdaki işlem satırlarının her ikisi de id adlı unsigned int bir değişken tanımlar:
unsigned int id;
unsigned id;
Şimdi, char veri türünün alabileceği minimum ve maksimum değerler ile bu değerlerin signed ve unsigned olarak ikili sistemde yazılışlarını bir örnek üzerinde incelemeye çalışalım:
#include <iostream>
#include <cstdlib>
using namespace std;
// Parametre olarak verilen int değeri ikili sistemde yazan fonksiyon
template <typename t> void IntToBin(t val);
int main(void)
{
signed char cdmin = -128; // Alabileceği minimum değer : -128 = 10000000
signed char cdmax = 127; // Alabileceği maksimum değer : 127 = 01111111
unsigned char ucdmin = 0; // Alabileceği minimum değer : 0 = 00000000
unsigned char ucdmax = 255; // Alabileceği azami değer : 255 = 11111111
cout << "char veri türünün alabileceği minimum değer: ";
IntToBin(cdmin); // -128 = 10000000
cout << "char veri türünün alabileceği maksimum değer: ";
IntToBin(cdmax); // 127 = 01111111
cout << "\n";
cout << "unsigned char veri türünün alabileceği minimum değer: ";
IntToBin(ucdmin); // 0 = 0000000
cout << "unsigned char veri türünün alabileceği maksimum değer: ";
IntToBin(ucdmax); // 255 = 11111111
cout << "\n";
unsigned char ucd = 235;
// Unsigned int bir değerin ikili sistemdeki yazılışına karşılık gelen negatif değeri bulmak için,
// veri türü (burada char) ile elde edilebilecek maksimum sayı miktarından (0-255 -> 256 adet)
// mevcut değer (235) çıkarılır, elde edilen değerin negatif değeri alınır.
// 256 - 235 = 21 -> -21
// 235 değerinin ikili sistemdeki yazılışına karşılık gelen negatif değer -21'dir.
char cd = -(256-235); // -21
IntToBin(ucd);
IntToBin(cd);
cout << "\n";
ucd = 149;
cd = -(256-149); // -107;
IntToBin(ucd);
IntToBin(cd);
cout << "\n";
return 0;
}
template <typename t> void IntToBin(t val)
{
int bitsayi = sizeof(val) * 8; // Integer değerin bit adet değeri
char *cdizi = (char*) malloc(bitsayi+1); // Dizi sonu '\0' karakteri için
cdizi[bitsayi] = '\0';
// En soldaki bit'in negatif değerler sorununu önlemek için unsigned değişken olarak işlem yapma
unsigned int u = *(unsigned int*)&val;
// 1 sayısını bit genişliğinden bir düşük değer kadar sola kaydırarak 32 bit'in en soldaki bit'ini 1 diğer bitleri 0 yapar.
unsigned int mask = 1 << (bitsayi-1);
int id;
for (id=0; id<bitsayi; id++, mask >>= 1) {
//Döngü değişkeninin her artışında mask değerinin en solundaki 1 değeri bir sağa kayar
cdizi[id] = (u & mask) ? '1' : '0';
}
cout << (int)val << " = " << cdizi << "\n";
free(cdizi);
}
Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:
char veri türünün alabileceği minimum değer: -128 = 10000000 char veri türünün alabileceği maksimum değer: 127 = 01111111 unsigned char veri türünün alabileceği minimum değer: 0 = 00000000 unsigned char veri türünün alabileceği maksimum değer: 255 = 11111111 235 = 11101011 -21 = 11101011 149 = 10010101 -107 = 10010101
Program, cdmin ve cdmax adlı iki adet signed char değişken bildirimi yaparak, bu veri türünün alabileceği en düşük değer olan -128 değerini cdmin değişkenine, en yüksek değer olan 127 değerini ise cdmax değişkenine atar.
Sonra, ucdmin ve ucdmax adlı iki adet unsigned char değişken bildirimi yaparak, bu veri türünün alabileceği en düşük değer olan 0 değerini ucdmin değişkenine, en yüksek değer olan 255 değerini ise ucdmax değişkenine atar. Tüm değişken değerlerini onlu ve ikili sayı sisteminde ekrana yazar.
ucd adlı unsigned char bir değişken bildirimi yaparak, 235 değerini bu değişkene atar. Bu değerin ikili sistemdeki yazılışına karşılık gelen negatif değeri bulmak için, char veri türünden elde edilebilecek maksimum sayı miktarından (0-255 -> 256 adet) mevcut değeri (235) çıkarır, elde edilen değerin negatif değerini alır. Bu yöntemle elde edilen -21 değeri cd adlı char değişkene atanır. ucd ve cd değişken değerlerini onlu ve ikili sayı sisteminde ekrana yazar.
Aynı işlemleri ucd değişkenine 149 değerini atayarak yapar.
Şimdi, int veri türünün alabileceği minimum ve maksimum değerler ile bu değerlerin signed ve unsigned olarak ikili sistemde yazılışlarını bir örnek üzerinde incelemeye çalışalım:
#include <iostream>
#include <cstdlib>
using namespace std;
// Parametre olarak verilen int değeri ikili sistemde yazan fonksiyon
template <typename t> void IntToBin(t val);
int main(void)
{
signed int idmin = (signed)-2147483648U; // Alabileceği minimum değer : -2147483648 =
signed int idmax = 2147483647; // Alabileceği maksimum değer : 2147483647 =
unsigned int uidmin = 0; // Alabileceği minimum değer : 0 = 00000000 00000000 00000000 00000000
unsigned int uidmax = 4294967295U; // Alabileceği azami değer : 4294967295 = 11111111 11111111 11111111 11111111
cout << "int veri türünün alabileceği minimum değer: ";
IntToBin(idmin); // -2147483648 =
cout << "int veri türünün alabileceği maksimum değer: ";
IntToBin(idmax); // 2147483647 =
cout << "\n";
cout << "unsigned int veri türünün alabileceği minimum değer: ";
IntToBin(uidmin); // 0 = 00000000 00000000 00000000 00000000
cout << "unsigned int veri türünün alabileceği maksimum değer: ";
IntToBin(uidmax); // 4294967295 = 11111111 11111111 11111111 11111111
cout << "\n";
unsigned int uid = 3384272514U;
// Unsigned int bir değerin ikili sistemdeki yazılışına karşılık gelen negatif değeri bulmak için,
// veri türü (burada int) ile elde edilebilecek maksimum sayı miktarından (0-4294967295 -> 4294967296 adet)
// mevcut değer (3384272514) çıkarılır, elde edilen değerin negatif değeri alınır.
// 4294967296 - 3384272514 = 910694782 -> -910694782
// 235 değerinin ikili sistemdeki yazılışına karşılık gelen negatif değer -21'dir.
int id = (signed) -(4294967296U-3384272514U); // -910694782
IntToBin(uid);
IntToBin(id);
return 0;
}
template <typename t> void IntToBin(t val)
{
int bitsayi = sizeof(val) * 8; // Integer değerin bit adet değeri
char *cdizi = (char*) malloc(bitsayi+1); // Dizi sonu '\0' karakteri için
cdizi[bitsayi] = '\0';
// En soldaki bit'in negatif değerler sorununu önlemek için unsigned değişken olarak işlem yapma
unsigned int u = *(unsigned int*)&val;
// 1 sayısını bit genişliğinden bir düşük değer kadar sola kaydırarak 32 bit'in en soldaki bit'ini 1 diğer bitleri 0 yapar.
unsigned int mask = 1 << (bitsayi-1);
int id;
for (id=0; id<bitsayi; id++, mask >>= 1) {
//Döngü değişkeninin her artışında mask değerinin en solundaki 1 değeri bir sağa kayar
cdizi[id] = (u & mask) ? '1' : '0';
}
cout << val << " = " << cdizi << "\n";
free(cdizi);
}
Yukarıdaki programı derleyip çalıştırdığımızda, aşağıdaki ifadeleri ekrana yazar:
int veri türünün alabileceği minimum değer: -2147483648 = 10000000000000000000000000000000 int veri türünün alabileceği maksimum değer: 2147483647 = 01111111111111111111111111111111 unsigned int veri türünün alabileceği minimum değer: 0 = 00000000000000000000000000000000 unsigned int veri türünün alabileceği maksimum değer: 4294967295 = 11111111111111111111111111111111 3384272514 = 11001001101101111110011010000010 -910694782 = 11001001101101111110011010000010
Program, idmin ve idmax adlı iki adet signed int değişken bildirimi yaparak, bu veri türünün alabileceği en düşük değer olan -2147483648 değerini idmin değişkenine, en yüksek değer olan 2147483647 değerini ise idmax değişkenine atar.
Sonra, uidmin ve uidmax adlı iki adet unsigned int değişken bildirimi yaparak, bu veri türünün alabileceği en düşük değer olan 0 değerini uidmin değişkenine, en yüksek değer olan 4294967295 değerini ise uidmax değişkenine atar. Tüm değişken değerlerini onlu ve ikili sayı sisteminde ekrana yazar.
uid adlı unsigned int bir değişken bildirimi yaparak, 3384272514 değerini bu değişkene atar. Bu değerin ikili sistemdeki yazılışına karşılık gelen negatif değeri bulmak için, int veri türünden elde edilebilecek maksimum sayı miktarından (0-4294967295 -> 4294967296 adet) mevcut değeri (3384272514) çıkarır, elde edilen değerin negatif değerini alır. Bu yöntemle elde edilen -3384272514 değeri id adlı int değişkene atanır. uid ve id değişken değerlerini onlu ve ikili sayı sisteminde ekrana yazar.
C++ dilinde temel veri çeşitleri kullanılarak oluşturulabilen bütün veri çeşitleri ile byte uzunlukları ve sınırlarının genel olarak kullanılan değerleri ile printf() ve scanf() fonksiyonları ile kullanılan format tanımlayıcıları aşağıdaki tabloda gösterilmektedir:
C++'nin diğer önemli bir özelliği de, char değişkenlerin ASCII karakter seti dışında değerler taşıyabilmesidir. Eğer, -128 ile 127 arasında kalan küçük int değerlerle işlem yapıyorsak, bu int değerleri atamak için int değişken yerine char bir değişken kullanabiliriz.
Veri türü | Bit genişliği | Alt sınır | Üst sınır | Format tanımlayıcısı | |
---|---|---|---|---|---|
printf() | scanf() | ||||
char | 8 | -128 | 127 | %c | %c |
unsigned char | 8 | 0 | 255 | %c | %c |
signed char | 8 | -128 | 127 | %c | %c |
int | 16 veya 32 | -32.768 veya -2.147.483.648 | 32.767 veya 2.147.483.647 | %d | %d |
unsigned int | 16 veya 32 | 0 | 65.535 veya 4.294.967.295 | %u | %u |
short int | 16 | -32.768 | 32767 | %hd | %hd |
unsigned short int | 16 | 0 | 65.535 | %hu | %hu |
long int | 32 | -2.147.483.648 | 2.147.483.647 | %ld | %ld |
long long int (C99) | 64 | −9.223.372.036.854.775.808 | 9.223.372.036.854.775.807 | %lld | %lld |
unsigned long int | 32 | 0 | 4.294.967.295 | %lu | %lu |
unsigned long long int (C99) | 64 | 0 | 18.446.744.073.709.551.615 | %llu | %llu |
float | 32 | 1.17549e-038 | 3.40282e+038 | %f | %f |
double | 64 | 2.22507e-308 | 1.79769e+308 | %f | %lf |
long double | 96 | 3.3621e-4932 | 1.18973e+4932 | %Lf | %Lf |
bool | 8 | - | - | - | - |
wchar_t | 16 | - | - | - | - |
void | 0 | - | - | - | - |
Aşağıdaki program çalıştırıldığı bilgisayardaki tanımlı veri türlerinin byte ve bit olarak genişlikleri ile <climits> (limits.h) ve <cfloat> (float.h) başlık dosyalarında tanımlı alt ve üst sınır değerlerini ekrana yazar.
#include <iostream>
#include <cfloat>
#include <climits>
using namespace std;
int main(void)
{
cout << "char -> byte: " << sizeof(char) << " bit: " << sizeof(char)*8 << " min: " << CHAR_MIN << " max: " << CHAR_MAX << "\n";
cout << "unsigned char -> byte: " << sizeof(unsigned char) << " bit: " << sizeof(unsigned char)*8 << " min: " << 0 << " max: " << UCHAR_MAX << "\n";
cout << "signed char -> byte: " << sizeof(signed char) << " bit: " << sizeof(signed char)*8 << " min: " << SCHAR_MIN << " max: " << SCHAR_MAX << "\n\n";
cout << "int -> byte: " << sizeof(int) << " bit: " << sizeof(int)*8 << " min: " << INT_MIN << " max: " << INT_MAX << "\n";
cout << "unsigned int -> byte: " << sizeof(unsigned int) << " bit: " << sizeof(unsigned int)*8 << " min: " << 0 << " max: " << UINT_MAX << "\n";
cout << "short int -> byte: " << sizeof(short int) << " bit: " << sizeof(short int)*8 << " min: " << SHRT_MIN << " max: " << SHRT_MAX << "\n";
cout << "unsigned short int -> byte: " << sizeof(unsigned short int) << " bit: " << sizeof(unsigned short int)*8 << " min: " << 0 << " max: " << USHRT_MAX << "\n\n";
cout << "long int -> byte: " << sizeof(long int) << " bit: " << sizeof(long int)*8 << " min: " << LONG_MIN << " max: " << LONG_MAX << "\n";
cout << "long long int -> byte: " << sizeof(long long int) << " bit: " << sizeof(long long int)*8 << " min: " << LLONG_MIN << " max: " << LLONG_MAX << "\n";
cout << "unsigned long int -> byte: " << sizeof(unsigned long int) << " bit: " << sizeof(unsigned long int)*8 << " min: " << 0 << " max: " << ULONG_MAX << "\n";
cout << "unsigned long long int -> byte: " << sizeof(unsigned long long int) << " bit: " << sizeof(unsigned long long int)*8 << " min: " << 0 << " max: " << ULLONG_MAX << "\n\n";
cout << "float -> byte: " << sizeof(float) << " bit: " << sizeof(float)*8 << " min: " << FLT_MIN << " max: " << FLT_MAX << "\n";
cout << "double -> byte: " << sizeof(double) << " bit: " << sizeof(double)*8 << " min: " << DBL_MIN << " max: " << DBL_MAX << "\n";
cout << "long double -> byte: " << sizeof(long double) << " bit: " << sizeof(long double)*8 << " min: " << LDBL_MIN << " max: " << LDBL_MAX;
return 0;
}
Yukarıdaki program aşağıdaki verileri ekrana yazar.
char -> byte: 1 bit: 8 min: -128 max: 127 unsigned char -> byte: 1 bit: 8 min: 0 max: 255 signed char -> byte: 1 bit: 8 min: -128 max: 127 int -> byte: 4 bit: 32 min: -2147483648 max: 2147483647 unsigned int -> byte: 4 bit: 32 min: 0 max: 4294967295 short int -> byte: 2 bit: 16 min: -32768 max: 32767 unsigned short int -> byte: 2 bit: 16 min: 0 max: 65535 long int -> byte: 4 bit: 32 min: -2147483648 max: 2147483647 long long int -> byte: 8 bit: 64 min: -9223372036854775808 max: 9223372036854775807 unsigned long int -> byte: 4 bit: 32 min: 0 max: 4294967295 unsigned long long int -> byte: 8 bit: 64 min: 0 max: 18446744073709551615 float -> byte: 4 bit: 32 min: 1.17549e-038 max: 3.40282e+038 double -> byte: 8 bit: 64 min: 2.22507e-308 max: 1.79769e+308 long double -> byte: 12 bit: 96 min: 3.3621e-4932 max: 1.18973e+4932