Konwersja typu

Z Wikipedii, wolnej encyklopedii
Skocz do: nawigacja, szukaj

Konwersja typu[1][2][3][4][5], zmiana typu (zmiennej w odwołaniu, wyrażenia)[6], rzutowanie typu[4][7], przekształcenie typu[7], to konstrukcja programistyczna dostępna w określonym języku programowania, umożliwiająca traktowanie danej pewnego, konkretnego typu, jak daną innego typu[1], lub taką zmianę tej danej albo jej reprezentacji w pamięci operacyjnej, aby wartość tej danej, odpowiadała według przyjętych kryteriów odwzorowania, danej innego, wybranego typu[2]. Pojęcie konwersji odnosi się także do sytuacji wyboru, rzutowania danych, które nie posiadają przypisanego typu, na wybrany, konkretny typ, celem interpretacji tych danych. Konwersja typu jest więc w swej istocie wykonaniem pewnego, z góry ustalonego, odwzorowania pomiędzy różnymi typami[2].

Zastosowanie konwersji typu[edytuj | edytuj kod]

W językach programowania wartości, dane (reprezentowane przez np. literał, wyrażenie, a w szczególności zmienną, parametry, itd.), mogą mieć przypisane różne atrybuty, w szczególności w większości języków programowania, typ danych. Fizyczną reprezentacją danych jest jednak ciąg bitów, a atrybuty przypisane danej, decydują między innymi o tym:

  • jak długi ciąg bitów stanowi określoną daną,
  • w jaki sposób jest interpretowany ciąg bitów określonej długości, stanowiący rozpatrywaną daną; ten sam ciąg bitów może być z powodzeniem interpretowany zarówno jako liczba, łańcuch znaków, wartość logiczna, itd.[notatka 1].

W programowaniu często istnieje konieczność wykonania wspólnej operacji na danych różnych typów i różnych innych atrybutów danej. Pojawia się również konieczność traktowania danej pewnego typu jak danej innego typu, oraz jak wyżej wspomniano nadanie interpretacji danym, które nie mają przypisanego typu. Realizacja wymienionych zagadnień wymaga stosowania konwersji typu.

Rodzaje konwersji[edytuj | edytuj kod]

Konwersje typu mogą być rozróżniane według różnych kryteriów podziału.

  • Podział ze względu na sposób specyfikacji:
    • jawne,
    • ukryte (automatyczne).
  • Podział według konstrukcji programistycznej:
  • Podział według sposobu realizacji:
    • konwersje bez zmiany sposobu reprezentacji danej w pamięci i rozmiaru danej – tylko zmiana interpretacji,
    • konwersje ze zmianą atrybutu rozmiaru danej, bez zmiany sposobu interpretacji danej,
    • konwersje ze zmianą sposobu reprezentacji bez zmiany interpretacji danej,
    • konwersje ze zmianą sposobu interpretacji danej.
  • Podział ze względu na utratę (części) informacji:
    • konwersje bez utraty informacji,
    • konwersje z częściową utratą informacji.

Języki programowania[edytuj | edytuj kod]

W językach programowania są stosowane różne rozwiązania:

  • konwersje mogą być zbędne, interpretacja danej następuje w określonym kontekście według narzuconego klucza – języki operujące tylko prostymi, beztypowymi[notatka 2] danymi, np. tylko słowem, bajtem itp.: PL/M[8], BCPL[1], Bliss[1], Forth[9], ewentualne konwersje w tych językach ograniczają się do rozszerzania mniejszych danych do rozmiaru większych danych, np. danej bajtowej do dwu bajtowej (słowowej do dwusłowowej[9]),
  • konwersje mogą być niedopuszczalne,
  • konwersje mogą być dopuszczalne w określonym zakresie – wymagane jest jawne specyfikowanie konwersji,
  • konwersje mogą być dopuszczalne w określonym zakresie oraz pewne konwersje mogą być wykonywane automatycznie – większość uniwersalnych języków programowania, np. C[7], C++[5], Pascal[10][6] itd.
  • konwersje wykonywanie automatycznie, użycie danej określonego typu dopuszczalne w każdym kontekście, np. PL/1[11], Snobol[12][notatka 3].

Konstrukcje programistyczne[edytuj | edytuj kod]

Konstrukcje programistyczne dotyczące wykonania konwersji typu, są elementami występującymi w kodzie źródłowym, w konkretnym języku programowania. To jakie konstrukcje są dopuszczalne wynika z przyjętych przez autorów język bądź implementacji danego języka, rozwiązań w zakresie składni i jego realizacji.

Konwersje niejawne[edytuj | edytuj kod]

Konwersje niejawne są generowane przez translator. Programista kodując określony algorytm nie musi zajmować się zapisem takich konwersji; wystarczy, że jest świadomy sposobu ich wykonania przez środowisko programistyczne oraz efektów i skutków jakie wykonanie danej konwersji przyniesie. W kodzie źródłowym konwersja taka nie ma jakiegokolwiek odzwierciedlenia w tekście kodu.

Przykładem konwersji niejawnych-automatycznych, są konwersje – w językach C[7][5], C++[5], Python[3] i innych – typów arytmetycznych dokonywane automatycznie i niejawnie w wyrażeniach. Jeżeli w wyrażeniu występują wartości o różnych typach arytmetycznych, stosuje się zasadę, że operandy typów o mniejszych rozmiarach są przekształcane do typów o większych rozmiarach. Pozwala to na używanie w jednym wyrażeniu danych typów, np. char, int, long, single, double itd.[notatka 4].

Konwersje wymuszone[edytuj | edytuj kod]

Konwersja danej może zostać wymuszona przez programistę, przy zastosowaniu istniejącego w języku lub implementacji mechanizmu automatycznej konwersji. Przykładem wymuszenia konwersji w języku JavaScript[13] jest umieszczenie w kodzie zapisu: ""+3. Użycie łańcucha pustego w operacji konkatenacji nie zmienia wartości łańcucha wynikowego, ale ponieważ dana reprezentowana przez literał liczbowy 3 reprezentuje całkowity typ danych, następuje wymuszone przekształcenie tej liczby na łańcuch.

Operatory konwersji[edytuj | edytuj kod]

Operator umożliwia jawny zapis konwersji w kodzie źródłowym zgodnie z zasadami składni danego języka. Operatory konwersji dostępne są między innymi w takich językach jak:

  • język C[7][5], C++[5]; (typ_docelowy)wyrażenie, lub typ_docelowy(wyrażenie), np. (int)znaki, lub int(znaki),
  • PHP[4]; (typ_docelowy)wyrażenie,
  • JavaScript[13]; typ_docelowy(wyrażenie),

Podprogramy[edytuj | edytuj kod]

Największe możliwości w zakresie konwersji dają podprogramy, w których można definiować wiele różnych odwzorowań, nawet dla dwóch wybranych, tych samych typów. W wielu językach istnieją podprogramy wbudowane dla podstawowych konwersji. Także wiele bibliotek programistycznych oferuje podprogramy standardowe w tym zakresie. Ale największą zaletą tej metody jest możliwość definiowania własnych odwzorowań przez programistę.

Podprogramy wbudowane dostępne są m.in. w

Referencja[edytuj | edytuj kod]

Mechanizm ten oparty jest o wskazania tego samego obszaru pamięci przez różne zmienne wskaźnikowe, oparte na różnych typach bazowych.

 Osobny artykuł: Referencja (informatyka).

Inne, odrębne konstrukcje[edytuj | edytuj kod]

W niektórych językach operacja konwersji jest odrębną kategorią jednostek składniowych, nie zaliczaną ani do operatorów, ani podprogramów, ani innych typowych konstrukcji. Tak jest np. w Turbo/Borland Pascalu[6], mimo że sam literalny zapis konwersji w kodzie źródłowym może mieć postać identyczną jak operator konwersji znany z języka C, tj.

 typ(zmienna)
 typ(wyrażenie) 

np.

integer(znak)

Inne, analogiczne konstrukcje[edytuj | edytuj kod]

Znaczącą analogię do konwersji typu, jako zmiany interpretacji danej bez zmiany jej reprezentacji, można dostrzec w odniesieniu do nakładania zmiennych. Mamy tu do czynienia z interpretacją danej zawartej w pewnym obszarze przynależnym do wielu zmiennych nałożonych na ten obszar pamięci, według różnych typów przypisanych do poszczególnych zmiennych.

Przykład w języku Turbo Pascal[6]:

var znak:char;
    kod:byte absolute znak;
 Osobny artykuł: Zmienna nakładana.

Inną, podobną analogię można dostrzec w odniesieniu do pól unii i pól pojedynczego wariantu w rekordzie z wariantami.

 Osobny artykuł: Unia (programowanie).
 Osobny artykuł: Rekord z wariantami.

Porównanie konstrukcji[edytuj | edytuj kod]

Poniżej pokazany jest trywialny przykład konwersji danej znakowej na daną liczbową w języku Pascal, dla środowiska Turbo Pascal.

Porównanie różnych konstrukcji w Turbo Pascalu[notatka 5]
forma konwersji przykład
jawna konwersja typu
var znak:char;
    liczba:byte;
begin
  znak:='1';
  liczba:=byte(znak);
  { wypisanie liczby 49 }
  writeln(liczba)
end.
podprogram standardowy Ord
var znak:char;
    liczba:byte;
begin
  znak:='1';
  liczba:=Ord(znak);
  { wypisanie liczby 49 }
  writeln(liczba)
end.
podprogram standardowy Val
var znak:char;
    liczba:byte;
begin
  znak:='1';
  Val(znak, liczba);
  { wypisanie liczby 1 }
  writeln(liczba)
end.
referencja
var znak:char;
    liczba:^byte;
begin
  znak:='1';
  liczba:=Ptr(znak);
  { wypisanie liczby 49 }
  writeln(liczba^)
end.
nakładanie zmiennych
var znak:char;
    liczba:byte absolute znak;
begin
  znak:='1';
  { wypisanie liczby 49 }
  writeln(liczba)
end.
rekord z wariantami
var konwersja=record
      case integer of
        znak:char;
        liczba:byte;
    end;
begin
  with konwersja do
    begin
      znak:='1';
      { wypisanie liczby 49 }
      writeln(liczba)
    end
end.

Zobacz też[edytuj | edytuj kod]

Uwagi[edytuj | edytuj kod]

  1. abstrahując od sensu merytorycznego takiej interpretacji
  2. w językach tych nie istnieje pojęcie typu, co najwyżej rozmiar danej, a jej interpretacja zależy od kontekstu
  3. w Snobolu przekształcenia takie wiążą się z przetwarzaniem łańcuchów, na które ukierunkowano ten język
  4. w wielu językach pojęcie typu obejmuje nie tylko rodzaj zapisanej danej, ale jej wielkość, np. w języku C i pokrewnych, dane typu single i double są typu zmiennoprzecikonwego, lecz definicja języka traktuje te dane, jak dane osobnych typów; jedynie niejawna konwersja pozwala na swobodne, wspólne używanie danych tych typów łącznie i zamiennie w wyrażeniach
  5. przyjęto, że w danym systemie komputerowym obowiązuje tabela kodów znaków ASCII

Przypisy

  1. 1,0 1,1 1,2 1,3 Michael Marcotty, Henry Ledgord, W kręgu języków programowania, tłumaczenie: Krystyna Jerzykiewicz, Wydawnictwa Naukowo-Techniczne, Warszawa 1980, Seria: Biblioteka Inżynierii Oprogramowania, ISBN 83-204-1342-7
  2. 2,0 2,1 2,2 John E. Nicholls, Struktura języków programowania, Wydawnictwa Naukowo-Techniczne, Warszawa 1980, Seria: Informatyka, ISBN 83-204-0246-8
  3. 3,0 3,1 3,2 Marcin Owsiany, Python scripting language a obliczenia i symulacje, czerwiec 2001 r.
  4. 4,0 4,1 4,2 Mateusz (luinnar) Juściński, PHP Konwersja i rzutowanie typów
  5. 5,0 5,1 5,2 5,3 5,4 5,5 Jan Bielecki, Od C do C++, programowanie obiektowe w języku C, Wydawnictwa Naukowo-Techniczne, Warszawa 1990, ISBN 83-204-1332-X
  6. 6,0 6,1 6,2 6,3 Andrzej Marciniak, Borland Pascal 7.0, Wyd. Nakom, Poznań 1994 r., seria: Biblioteka Użytkownika Mikrokomputerów ISBN 83-85060-53-7, ISSN 0867-6011
  7. 7,0 7,1 7,2 7,3 7,4 Brian W. Kernighan, Dennis M. Ritche, Język C, Wydawnictwa Naukowo-Techniczne, Warszawa 1988, Seria: Biblioteka Inżynierii Oprogramowania, ISBN 83-204-1067-3
  8. Jan Bielecki, PL/M język programowania mikroprocesorów, Wydawnictwa Komunikacji i Łączności, Warszawa 1987, Seria: Elektronizacja, zeszyt 25
  9. 9,0 9,1 Jan Bielecki, Język FORTH, Wydawnictwa Naukowo-Techniczne, Warszawa 1988, Seria: Mikrokomputery, ISBN 83-204-0930-6
  10. Michał Iglewski, Jan Madey, Stanisław Matwin, Pascal. Język wzorcowy – Pascal 360., Wydawnictwa Naukowo-Techniczne, Warszawa 1984, wydanie trzecie – zmienione, Seria: Biblioteka Inżynierii Oprogramowania, ISBN 83-204-0597-1
  11. 11,0 11,1 Jan Bielecki, Rozszerzony PL/I i JCL w systemie OS/RIAD, Państwowe Wydawnictwo Naukowe, Warszawa 1986, Seria: Biblioteka Informatyki, ISBN 83-01-06146-4
  12. Paweł Gizbert-Studnicki, Jerzy Kaczmarczuk, Snobol4, Wydawnictwa Naukowo-Techniczne, Warszawa 1984, Seria: Biblioteka Inżynierii Oprogramowania, ISBN 83-204-0546-7
  13. 13,0 13,1 Wojciech Romowicz, HTML i JavaScript, HELION 1998 r., ISBN 83-7197-046-3
  14. Ryszard K. Kott, Krzysztof Walczak. Programowanie w języku Fortran 77, Wydawnictwa Naukowo-Techniczne, Warszawa 1991, ISBN 83-204-1362-1