W języku C# istnieje zestaw typów wbudowanych (zwanych też czasem pierwotnymi lub prymitywnymi). Są one zdefiniowane przez sam język i dostępne bez dodatkowych importów. Każdy z tych typów ma:
- określony rozmiar (ilość pamięci, którą zajmuje w systemie),
- zakres wartości, które może przechowywać,
- zestaw operacji, które można na nim wykonywać.
Oprócz typów wbudowanych, C# pozwala na tworzenie typów zdefiniowanych przez użytkownika (np. klasy, struktury), ale w tej lekcji skupiamy się głównie na podstawowych typach predefiniowanych.
Rozmiar i lokalizacja w pamięci
Typy wartościowe (Value Types) i referencyjne (Reference Types)
- Typy wartościowe (Value Types) przechowują swoje dane bezpośrednio w pamięci stosu (ang. stack). Przykładami są:
bool
,int
,float
,double
,decimal
,char
,byte
,short
, a także struktury. - Typy referencyjne (Reference Types) przechowują w zmiennej jedynie odwołanie (adres) do obiektu, który faktycznie znajduje się w pamięci zarządzanej na stercie (ang. heap). Przykładami są:
object
,string
, klasy, tablice.
W przypadku typów wartościowych zmienna to faktycznie dane (wartość liczbowa, logiczna itp.). W typach referencyjnych zmienna przechowuje wskaźnik do obiektu.
Rozmiar typów wbudowanych
Poniższa tabela prezentuje rozmiar (w bitach) oraz przykładowy zakres niektórych typów:
Typ | Rozmiar (bity) | Zakres wartości | Kategoria |
---|---|---|---|
bool | nieustalony* | true lub false | Wartościowy |
byte | 8 | od 0 do 255 | Wartościowy |
sbyte | 8 | od -128 do 127 | Wartościowy |
short | 16 | od -32768 do 32767 | Wartościowy |
ushort | 16 | od 0 do 65535 | Wartościowy |
int | 32 | od -2,147,483,648 do 2,147,483,647 | Wartościowy |
long | 64 | od -9,223,372,036,854,775,808 do 9,223,372,036,854,775,807 | Wartościowy |
float | 32 | ~±1.5e−45 do ±3.4e38 (zmiennoprzecinkowy) | Wartościowy |
double | 64 | ~±5.0e−324 do ±1.7e308 (zmiennoprzecinkowy) | Wartościowy |
decimal | 128 | ~±1.0e−28 do ±7.9e28 (dokładność 28-29 cyfr) | Wartościowy |
char | 16 | Jeden znak w standardzie Unicode | Wartościowy |
object | – | – | Referencyjny |
string | – | – (ciąg znaków, rozmiar zależny od zawartości) | Referencyjny |
* W praktyce bool
może być reprezentowany przez jeden bajt (8 bitów), jednak standard C# nie narzuca ścisłego rozmiaru, a jedynie wartości logiczne true/false
.
Zakres danych
Zakres odnosi się do minimalnej i maksymalnej wartości, jaką może przyjąć dana zmienna. Jest on powiązany z liczbą bitów przeznaczonych na przechowywanie danej wartości. Przykładowo:
- Typ
int
(32 bity) przechowuje liczby od -2,147,483,648 do 2,147,483,647. - Typ
byte
(8 bitów) przechowuje liczby od 0 do 255 (tylko dodatnie).
W przypadku typów zmiennoprzecinkowych (float
, double
) zakres jest bardzo duży, jednak występuje ograniczenie precyzji (dokładności). Natomiast decimal
jest przeznaczony do obliczeń finansowych, gdzie wymagana jest wysoka dokładność dziesiętna.
Obsługiwane operacje
Operatory arytmetyczne
Większość typów numerycznych (int
, float
, double
, decimal
, byte
, short
, itp.) obsługuje podstawowe operacje:
- Dodawanie:
+
- Odejmowanie:
-
- Mnożenie:
*
- Dzielenie:
/
- Reszta z dzielenia:
%
Przykład:
int a = 10;
int b = 3;
int suma = a + b; // 13
int roznica = a - b; // 7
int iloczyn = a * b; // 30
int iloraz = a / b; // 3 (dzielenie całkowite, reszta pominięta)
int reszta = a % b; // 1
Operatory porównania
Typy numeryczne i typ char
można porównywać za pomocą:
==
(równość),!=
(różność),>
(większe niż),<
(mniejsze niż),>=
(większe lub równe),<=
(mniejsze lub równe).
Przykład:
int x = 5;
int y = 7;
bool czyRowne = (x == y); // false
bool czyWieksze = (x > y); // false
Operatory logiczne
Dla typów logicznych (bool
) dostępne są operatory:
&&
(koniunkcja/logiczne AND),||
(alternatywa/logiczne OR),!
(negacja/logiczne NOT).
Przykład:
bool a = true;
bool b = false;
bool wynikAND = a && b; // false
bool wynikOR = a || b; // true
bool wynikNOT = !a; // false
Typy wbudowane w C#
bool
- Przechowuje wartości logiczne:
true
lubfalse
. - Zwykle używany w instrukcjach warunkowych.
bool czyPada = false;
if (czyPada)
{
Console.WriteLine("Weź parasol!");
}
int
- Najpopularniejszy typ całkowitoliczbowy.
- 32 bity, zakres od -2,147,483,648 do 2,147,483,647.
int liczba = 100;
Console.WriteLine("Wartość liczby: " + liczba);
float
, double
, decimal
- float: 32-bitowy typ zmiennoprzecinkowy, mniejsza precyzja.
- double: 64-bitowy typ zmiennoprzecinkowy, standardowy do większości obliczeń zmiennoprzecinkowych.
- decimal: 128-bitowy typ zmiennoprzecinkowy o wysokiej dokładności dziesiętnej, często używany w obliczeniach finansowych.
float f = 3.14f; // Wartość z sufiksem 'f'
double d = 3.14; // Domyślnie double
decimal dec = 3.14m; // Wartość z sufiksem 'm'
char
- Przechowuje pojedynczy znak w standardzie Unicode.
- Zapisywany w apostrofach:
'a'
,'X'
,'\n'
.
char znak = 'A';
Console.WriteLine(znak);
byte
(i sbyte
), short
(i ushort
)
byte
: 8-bitowy typ bez znaku (0–255).sbyte
: 8-bitowy typ ze znakiem (–128–127).short
: 16-bitowy typ całkowitoliczbowy (–32768–32767).ushort
: 16-bitowy typ bez znaku (0–65535).
byte bajt = 200; // OK
sbyte sbajt = -50; // OK
short liczbaKrotka = 32000;
ushort liczbaKrotkaU = 60000;
object
- Bazowy typ referencyjny dla wszystkich typów w C#.
- Każdy typ (zarówno wartościowy, jak i referencyjny) może być przypisany do zmiennej typu
object
(tzw. boxing).
object obiekt = 123; // boxing int do object
obiekt = "tekst"; // teraz przechowuje string
string
- Przechowuje ciąg znaków Unicode (np. słowa, zdania).
- Typ referencyjny, ale posiada pewne cechy typu wartościowego (np. niemutowalność – ciąg znaków nie może być zmieniony po utworzeniu).
string tekst = "Witaj w C#";
Console.WriteLine(tekst);
Stałe (const
), konwencje nazw
- Słowo kluczowe
const
oznacza, że zmienna jest stałą, czyli jej wartość nie może zostać zmieniona po zainicjalizowaniu. - Stałe muszą być zainicjalizowane w momencie deklaracji.
const double PI = 3.14159;
const int MAX_WIEK = 120;
// PI = 3.14; // błąd kompilacji, nie można zmienić wartości stałej
Konwencje nazw
Stała: często używa się wielkich liter z podkreślnikami (np. MAX_WIEK
), choć nie jest to wymóg języka, a raczej powszechna praktyka.