1. Jak działa pamięć
Każdy komputer ma pamięć operacyjną. Co to właściwie jest, jakie ma właściwości i – co najważniejsze – co nam z tego przychodzi?
Każdy program (w tym programy napisane w C#) przed uruchomieniem ładuje się do pamięci operacyjnej. W pamięci operacyjnej znajduje się kod programu (który wykonuje procesor) oraz dane programu (które program sam umieszcza w pamięci).
Czym więc jest pamięć operacyjna i do czego jest podobna?
Wyobraź sobie Excela 😎 Arkusz w Excelu składa się z komórek, a każda komórka ma swój unikalny numer (A1, A2, ... B1, B2). Znając numer komórki, zawsze możesz wpisać do niej jakąś wartość albo pobrać to, co tam jest zapisane. Pamięć komputera działa bardzo podobnie.

Program i jego dane podczas działania są przechowywane w pamięci. Cała pamięć komputera to taki zbiór małych komórek – bajtów. Każda komórka ma swój unikalny numer – 0, 1, 2, 3, ...; (numeracja zaczyna się od zera). Znając numer komórki, możemy zapisać tam jakieś dane. Albo je stamtąd pobrać. W jednych komórkach jest kod programu – zestaw instrukcji dla procesora, w innych – dane tego programu. Numer komórki nazywamy też adresem komórki.
Procesor potrafi wykonywać instrukcje z załadowanego do pamięci programu. Prawie wszystkie instrukcje procesora to coś w stylu: weź dane z kilku komórek → zrób z nimi coś → wynik wrzuć do innych komórek.
Łącząc setki prostych instrukcji, dostajemy złożone i przydatne polecenia.
Kiedy w kodzie programu deklarujesz zmienną, dostaje ona kawałek jeszcze nieużywanej pamięci. Zazwyczaj to kilka bajtów. Przy deklaracji zmiennej musisz podać typ informacji, którą program będzie tam trzymał: liczby, tekst albo coś innego. Bez tej wiedzy nie wiadomo, jak duży blok pamięci trzeba zarezerwować dla zmiennej.
Na początku historii komputerów programy operowały po prostu na numerach komórek pamięci, ale potem – dla wygody programistów – komórkom zaczęto nadawać nazwy. Unikalna nazwa zmiennej to głównie dla wygody programistów: program podczas działania spokojnie poradziłby sobie tylko z numerami.
2. Zmienne w pamięci
W C# są 4 podstawowe typy danych do przechowywania liczb całkowitych. To byte, short, int i long.
| Typ | Rozmiar, bajty | Pochodzenie nazwy |
|---|---|---|
| byte | 1 | Byte, bo zajmuje jeden bajt pamięci |
| short | 2 | Skrót od Short Integer |
| int | 4 | Skrót od Integer |
| long | 8 | Skrót od Long Integer |
W C# są też 2 typy zmiennoprzecinkowe — float i double:
| Typ | Rozmiar, bajty | Pochodzenie nazwy |
|---|---|---|
| float | 4 | Skrót od Floating Point Number |
| double | 8 | Skrót od Double Float |
Za każdym razem, gdy program dochodzi do instrukcji utworzenia zmiennej, rezerwuje dla niej kawałek pamięci (rozmiar zależy od typu zmiennej).
int a = 10;
Adresem zmiennej jest adres pierwszej komórki zarezerwowanego dla niej bloku pamięci.
C#-programom nie wolno bezpośrednio odwoływać się do pamięci. Cała praca z pamięcią odbywa się pod ścisłą kontrolą C# i .NET.
3. Typ string w pamięci
Typ string może przechowywać duże ilości danych, więc to nie jest zwykły typ danych, tylko pełnoprawny obiekt.
Sama zawartość typu string (tekst) trafia do specjalnego obiektu, dla którego rezerwuje się pamięć, a adres tego obiektu trafia do zmiennej, dla której też rezerwuje się pamięć.

- Zmienna a typu int zajmuje 4 bajty i przechowuje wartość 1.
- Zmienna b typu int zajmuje 4 bajty i przechowuje wartość 10,555. Przecinek – to nie część ułamkowa liczby, tylko rozdzielenie rzędów. Część ułamkowa oddzielana jest kropką.
- Zmienna d typu double zajmuje 8 bajtów i przechowuje wartość 13.001.
- Zmienna str typu string zajmuje 4 bajty i przechowuje wartość D12 – adres pierwszej komórki obiektu z tekstem.
Obiekt typu string (z tekstem) jest przechowywany w osobnym bloku pamięci. Adres jego pierwszej komórki jest zapisany w zmiennej str.
4. Co się dzieje, gdy przypisujemy
Jeszcze jedna ważna rzecz – jak działa przypisanie. Na przykład:
int a = 10;
int b = a;
b = 20;
Console.WriteLine(a); // 10
W tym przykładzie w pamięci powstają dwie komórki: jedna dla a, jedna dla b. Gdy piszemy b = a;, kopiowana jest wartość (10), a nie sam "pudełko". Zmiany w b nie mają wpływu na a.
Teraz podobnie, ale ze stringami:
string s1 = "Hello";
string s2 = s1;
s2 = s2 + " World";
Console.WriteLine(s1); // "Hello"
Console.WriteLine(s2); // "Hello World"
Tutaj obie zmienne s1 i s2 wskazują na ten sam string "Hello" aż do momentu zmiany. Ale gdy wykonujemy s2 = s2 + " World", dla s2 powstaje nowy string "Hello World", a s1 dalej wskazuje na stary string "Hello".
5. Dlaczego w programowaniu wszystko numeruje się od zera
Ludzie często się dziwią, czemu w programowaniu prawie wszędzie liczy się od zera. Chodzi o to, że jest mnóstwo sytuacji, gdzie liczenie od zera jest wygodniejsze (choć są też takie, gdzie wygodniej liczyć od 1).
Najprostsza z takich sytuacji – to adresowanie pamięci. Jeśli Twojej zmiennej przydzielono 4 bajty pamięci i masz X – adres pierwszego bajtu, to jakie będą adresy wszystkich bajtów? X+0, X+1, X+2, X+3. I już mamy grupę bajtów z indeksami 0, 1, 2, 3.
Kiedy myślimy o adresie względnym wewnątrz jakiegoś bloku danych, zawsze wychodzi numeracja od zera. To jest pierwsza i najczęstsza przyczyna liczenia od zera.
GO TO FULL VERSION