Zamknij komunikat

Nowy Office 2013
Do góry Skomentuj

10. Typy proste i referencyjne

10. Typy proste i referencyjne

Daniel Celeda
31 stycznia 2006
157 013
Odsłony
Daniel Celeda
31 stycznia 2006
157 013
Odsłony

W C#, tak jak w innych językach obiektowych, mamy typy proste i referencyjne.

Do typów prostych należą dane liczbowe takie jak: „int”, „float”, itd., a także typy wyliczeniowe oraz struktury („string” to struktura, a więc jest typem prostym). Przypisując do jednej zmiennej prostej jakąś wartość lub wartość z innej zmiennej prostej, tworzy się kopia.  W  przypadku referencji nie powstaje kopia danych, lecz kopiuje się tzw. wskaźnik na dane, czyli wskazanie na jakie dane zmienna wskazuje. Spróbuję to zobrazować przykładami.

Najpierw przyjrzyjmy się operacjom na typach prostych.

class KlasaGlowna
{
    static void Main()
    {
        int x = 2;
        int y = x;
        x = x + 8;

        System.Console.WriteLine("Wartość x: " + x);
        System.Console.WriteLine("Wartość y: " + y);
        System.Console.ReadLine();
    }
}

Na początku przypisujemy wartość 2 do zmiennej “x”, następnie kopię wartości “x” (w zasadzie wartości 2 znajdującej się w zmiennej “x”) zmiennej “y”. Na koniec zwiększamy wartość zmiennej „x” o 8 i wypisujemy zawartości obu zmiennych na ekranie.

Widać, że zmiana wartości zmiennej „x” nie miała wpływu na wartość zmiennej „y”.
Zupełnie inaczej jest w przypadku zmiennych referencyjnych.

class KlasaPomocnicza
{
    public int x;
}
class KlasaGlowna
{
    static void Main()
    {
        KlasaPomocnicza obiekt1 = new KlasaPomocnicza();
        KlasaPomocnicza obiekt2 = new KlasaPomocnicza();

        obiekt1.x = 2;
        obiekt2 = obiekt1;
        obiekt1.x = obiekt1.x + 8;

        System.Console.WriteLine("Wartość x w obiekcie pierwszym: " + obiekt1.x);
        System.Console.WriteLine("Wartość x w obiekcie drugim: " + obiekt2.x);
        System.Console.ReadLine();
    }
}

Wynik wykonania powyższego programu może być zaskakujący.

Zwiększaliśmy wartość „x” tylko w obiekcie pierwszym, jednak zwiększyła się też wartość „x” w obiekcie drugim. Stało się tak dlatego, ponieważ obiekty to typy referencyjne. W linijce

obiekt2 = obiekt1;

określiliśmy, że obydwa obiekty wskazują na to samo miejsce w pamięci, a więc każda zmiana danych wskazywanych przez jeden z obiektów, powoduje zmianę danych wskazywanych przez drugi (jest to oczywistem, ponieważ są to te same dane).

Rzutowanie

Typy „z tej samej rodziny” możemy rzutować jeden na drugi. Np. typ „long” na „int”

class KlasaGlowna
{
    static void Main()
    {
        long x = 2;
        int y = (int)x;
    }
}

lub „int” na „long”

class KlasaGlowna
{
    static void Main()
    {
        int x = 2;
        long y = (long)x;
    }
}

Jednak pierwszy przypadek jest niepoprawny, ponieważ typ „long” jest dokładniejszy od „int” i podczas rzutowania możemy utracić poprawność danych.

Konwersja między typami

Konwersja służy do konwertowania typów z jednego na drugi. W części kursu poświęconej łańcuchom znakowym konwertowaliśmy wartości liczbowe na typ „string” podczas łączenia łańcuchów za pomocą operatora „+”. Była to konwersja niejawna, czyli taka, której sami nie wywołaliśmy. Kompilator sam rozpoznał, że musi skonwertować typ liczbowy na „string”. Napiszmy krótki program konwertujący łańcuch znakowy na typ liczbowy.

class KlasaGlowna
{
    static void Main()
    {
        System.Console.WriteLine("Podaj liczbę.");
        string napis = System.Console.ReadLine();
        int x = int.Parse(napis);
        int wynik = x * 2;
        System.Console.WriteLine("Liczba " + x + " pomnożona przez 2 " + "równa się " + wynik);
        System.Console.ReadLine();
    }
}

„Int” posiada statyczną metodę „Parse(string parametr)”, która jako parametr przyjmuje łańcuch znakowy, który następnie konwertuje na typ całkowitoliczbowy.

Jeśli łańcuch znakowy nie będzie liczbą, (np. podamy zamiast liczby literę „s”) otrzymamy błąd podczas wykonania programu.
W .NET mamy bardzo przydatna klasę „Convert”, która posiada wiele metod statycznych do konwersji typów. Działanie tych metod możemy zobrazować poniższym przykładem.

class KlasaGlowna
{
    static void Main()
    {
        System.Console.WriteLine("Podaj liczbę.");
        string napis = System.Console.ReadLine();
        int x = System.Convert.ToInt32(napis);
        int wynik = x * 2;
        System.Console.WriteLine("Liczba " + x + " pomnożona przez 2 " + "równa się " + wynik);
        System.Console.ReadLine();
    }
}

Wynik jaki otrzymamy powinien być taki sam, jak w poprzednim programie.

Proste typy danych w C#

Warto poznać kilka z wbudowanych prostych typów danych w C#.

bool – typ logiczny, oznaczający prawdę („true”) lub fałsz („false”), używany do operacji logicznych,
short
– 16-bitowa liczba całkowita,
int
– 32-bitowa liczba całkowita,
long
– 64-bitowa liczba całkowita,
float
– 32-bitowa liczba zmiennoprzecinkowa,
double
– 64-bitowa liczba zmiennoprzecinkowa,
char
– pojedynczy znak zapisany w formacie Unicode,
string
– łańcuch znakowy, zbiór znaków w formacie Unicode.

Stałe

Stałe to dane, których wartości nie możemy zmieniać. W pewnym uproszczeniu możemy sobie wyobrazić, że są to zmienne, których wartości są zawsze takie same. Ze stałymi związane jest słówko „const”, które definiuje nam stałą.

class KlasaGlowna
{
    public const double PI = 3.14;
    public const double E = 2.74;

    static void Main()
    {
        System.Console.WriteLine("Liczba PI ma warość: " + PI);
        System.Console.WriteLine("Liczba e ma wartość: " + E);
        System.Console.ReadLine();
    }
}

Wygodniej jest stworzyć klasę ze stałymi, którą możemy wykorzystać w wielu innych klasach (a nawet programach).

class Liczby
{
    public const double PI = 3.14;
    public const double E = 2.74;
}

class
KlasaGlowna
{
    static void Main()
    {
        System.Console.WriteLine("Liczba PI ma warość: " + Liczby.PI);
        System.Console.WriteLine("Liczba e ma wartość: " + Liczby.E);
        System.Console.ReadLine();
    }
}

Ponieważ „PI” oraz „E” są stałymi, nie musimy tworzyć obiektów klasy „Liczby” – wartości tych stałych będą zawsze dostępne i niezmienne.
A oto wynik działania obydwu powyższych programów.

Zobacz również

Komentarze

Kod działa, ale zastanawia mnie, w jaki sposób mamy dostęp do zmiennych klasy, bez tworzenia jej instancji, lub bez oznaczania jej jako static, tym bardziej, że jest dostęp poprzez nazwę klasy?
Shreeve, 27 lipca 2006, 07:54
@Shreeve: "KlasaPomocnicza obiekt1 = new KlasaPomocnicza(); KlasaPomocnicza obiekt2 = new KlasaPomocnicza();" Te linie tworzą dwie nowe instancje klasy KlasaPomocnicza: obiekt1 i obiekt2... Dzięki temu, że zmienna x NIE jest statyczna, każda instancja przechowuje swoją wartość iksa, do którego dostęp mamy przez nazwę instancji, np. obiekt1.x - mam nadzieję, że rozjaśniłem. Pozdrawiam :)
nj, 29 lipca 2006, 11:40
Błąd w kodzie; pierwsze okno int x = 2; int y = x; x = x + 8; powinno być: int x = 2; int y = x; y = x + 8;
Wujek, 5 sierpnia 2006, 20:48
Sam jestes błąd w kodzie
Ciocia, 10 sierpnia 2006, 12:38
Ty ciotka nie podskakuj bo ci zaraz zrobie masowanie jąder
Wujek, 10 sierpnia 2006, 17:01
nie błąd w kodzie tylko źle zrozumiałes lekcje
kostii, 11 sierpnia 2006, 11:56
Tak jest!!! Pała!!! Źle zrozumiałeś :) lol
Kazik, 14 sierpnia 2006, 14:24
Przepraszam wszystkich za moje wybryki na forum, oczywiście, że jest bład z mojej strony. Pozdro. Po prostu zwiększamy x'a o 8
Wujek, 18 sierpnia 2006, 17:09
Cytat: Stałe to dane, których wartości nie możemy zmieniać. W pewnym uproszczeniu możemy sobie wyobrazić, że są to zmienne, których wartości są zawsze takie same. Koniec cytatu. Jeżeli stała to nie zmienna!!! Cytat: W C#, tak jak w innych językach obiektowych, mamy typy proste i referencyjne. Koniec cytatu. Tak w C# mamy typy proste, javie też, ale nie jest to regułą w językach obiektowych!!!!!!!
bartek, 21 sierpnia 2006, 16:33
String typem prostym?? Raczej referencyjnym. Poniższy link wszystko wyjaśnia: http://www.microsoft.com/poland/developer/net/podstawy/clr.mspx
yaro27, 11 lipca 2008, 15:26


nie, 16 września 2008, 14:19
Błąd - string jest typem referencyjnym. Dowód: http://msdn.microsoft.com/en-us/library/490f96s2.aspx

carck3r, 1 maja 2009, 21:35
Cytat:
określiliśmy, że obydwa obiekty wskazują na to samo miejsce<br />w pamięci, a więc każda zmiana danych wskazywanych przez jeden z obiektów,<br />powoduje zmianę danych wskazywanych przez drugi

 
Chyba szkoda czasu na ten kurs. Obiekty na coś wskazują? obiekt1 i obiekt2 to nie obiekty tylko referencje do obiektów. A tak BTW po wykonaniu linii biekt2 = obiekt1; w pamięci nie ma już dwóch obiektów tylko jeden, bo drugi zostanie usunięty przez GC. Żenada.<br />


Programista C++, 23 lipca 2009, 10:49
Cytat: "Do typów prostych należą dane liczbowe takie jak: „int”, „float”, itd., a także typy wyliczeniowe oraz struktury („string” to struktura, a więc jest typem prostym)" Bzdura! Jak już kilka osób wpomniało string jest oczywiście typem referencyjnym jednak jego zachowanie zostało zaimplementowane tak jak struktury, tj. przeciążony został m. in. operator przypisania, który tworzy nowy obiekt string"a. Ponadto największym błędem tego artykułu jest stwierdzenie, że typami prostymi są również wypy wyliczeniowe i struktury (!). Typy proste to NIEKTÓRE struktury, dla których istnieją aliasy, np. dla struktury System.Int32 istnieje alias int, dla System.Double - double, dla System.Int64 - long itp. Ponadto typy proste rządzą się swoimi zasadami: http://msdn.microsoft.com/en-us/library/aa691144(VS.71).aspx
DOŚWIADCZONY programista C#, 24 września 2009, 10:49
I jeszcze jedno - autorowi tego artykułu radzę zdobycie większego doświadczenia w programowaniu w platformie .NET przed napisaniem kolejnego artykułu. Wprawdzie minęło już sporo czasu od publikacji tego artykułu jednak to tyczy się każdego innego zagadnienia, gdyż wiele niedoświadczonych osób zagląda tutaj i bierze ten arykuł za pewnik opowiadając innym podobne brednie. Wydaje misię, że należy rozpatrzyć usunięcie tego artukułu lub poprawienie go przez doświadczoną osobę.
DOŚWIADCZONY programista C#, 24 września 2009, 10:55
Dla "DOŚWIADCZONEGO programisty C#" być może są tu jakieś niścisłości, ale dla początkującego, nie ma znaczenia, czy nazwywa się to tak, czy siak. Akurat w tym przypadku chodzi o przyswojenie tych pojeć, a nie o nazwanie ich. To bardzo początkujący kurs i lepiej go nie usuwajcie (błędy można poprawić :)).
nos, 2 listopada 2009, 15:45
Witam Wlasnie korzystalem z tego artykulu, cos mi nie pasowalo i dzieki niebiosom przeczytalem komentarze... Z mojego punktu widzenia, taki artykul dyskwalifikuje w nauce jezyka! Powód to prawdziwe informacje z zaszytymi powaznymi bledami w tutku, ktore dla swiezaka ( jak ja ;"> ) zapadaja dlugo w pamieci, trudno je potem naprostować! Bardzo mi przykro zolta kartka dla twórcy się należy.
StWolf, 6 listopada 2009, 11:26
Kurs jest niezwykle prosty, a zarazem merytoryczny, bardzo czytelny i zrozumiały. Czuje się, że Autor jest bardzo dobrym programistą a mimo to nie "cwaniakuje" popisując się swoją wiedzą. Dziękuję!
Ryszard, 26 stycznia 2010, 13:44
a ja już się poddaję, dalej nie idę, jak dla mnie jest  lekko chaotyczny, już nie trawię tego, kurs napisany 5 lat temu, teraz mammy 2010r, czy nic sie nei zmieniło do tego czasu w C# i nei powinno być zaktualizowane???
wiki, 12 września 2010, 13:58
nie ten poziom :D
nie, 25 listopada 2010, 10:11
Czy w pierwszym przykładzie nie mamy klasycznego wycieku pamięci? Oczywiście w tak trywialnym przykładzie to nie problem ale czemu tego uczyć? Nie lepiej było napisać tak? KlasaPomocnicza obiekt1 = new KlasaPomocnicza(); KlasaPomocnicza obiekt2;
marco, 27 listopada 2010, 00:00
marco, jak już sygnalizujesz jakiś problem to może opisałbyś go dokładniej? Wiele osób pisze tutaj, że kurs jest kiepski, że trzeba go wywalić, a może po prostu poprawiajcie błędy, albo napiszcie swój idealny tutorial?
Krzys, 1 marca 2011, 11:56
Autorowi może chodzilo o inna liczbe (wlasna), ale liczba e to w przyblizeniu 2,71, a nie 2,74:)
Tomcio, 7 sierpnia 2011, 20:14
Od kiedy string jest typem prostym? http://msdn.microsoft.com/pl-pl/library/system.string%28v=vs.110%29.aspx
Piotr W., 18 grudnia 2014, 10:25
Pamietajcie aby stosować stałe, dlatego, że zajmuje to mniej miejsca w pamieci niz zwykla zmienna w klasie :)
Wojciech, 25 listopada 2015, 15:20

Dodaj swój komentarz

Zasady publikacji komentarzyZasady publikacji komentarzy

Redakcja CentrumXP.pl nie odpowiada za treść komentarzy publikowanych na stronach Portalu
i zastrzega sobie prawo do usuwania wypowiedzi, które:

  • zawierają słowa wulgarne, obraźliwe, prowokujące i inne naruszające dobre obyczaje;
  • są jedynie próbami reklamowania stron internetowych (spamowanie poprzez umieszczanie linków);
  • przyczyniają się do złamania prawa bądź warunków licencyjnych oprogramowania (cracki, seriale, torrenty itp.);
  • zawierają dane osobowe, teleadresowe, adresy mailowe lub numery GG;
  • merytorycznie nie wnoszą nic do dyskusji lub nie mają związku z tematem komentowanego newsa, artykułu bądź pliku.