Pierwotny typ danych — Primitive data type

W informatyce , prymitywny typ danych jest jedną z następujących czynności:

  • podstawowy typ to typ danych dostarczana przez język programowania jako podstawowy element. Większość języków pozwala na rekurencyjne konstruowanie bardziej skomplikowanych typów złożonych, zaczynając od typów podstawowych.
  • wbudowany typ to typ danych, dla których język programowania oferuje wbudowaną obsługę.

W większości języków programowania wbudowane są wszystkie podstawowe typy danych. Ponadto wiele języków udostępnia również zestaw złożonych typów danych.

W zależności od języka i jego implementacji, prymitywne typy danych mogą, ale nie muszą odpowiadać jeden do jednego z obiektami w pamięci komputera. Jednak zwykle oczekuje się, że operacje na podstawowych typach danych pierwotnych będą najszybszymi konstrukcjami językowymi. Na przykład dodawanie liczb całkowitych może być wykonywane jako pojedyncza instrukcja maszynowa, a niektóre procesory oferują określone instrukcje do przetwarzania sekwencji znaków za pomocą pojedynczej instrukcji. W szczególności norma C wspomina, że ​​„zwykły obiekt int ma naturalną wielkość sugerowaną przez architekturę środowiska wykonawczego”. Oznacza to, że intprawdopodobnie będzie to 32 bity na architekturze 32-bitowej. Podstawowe typy pierwotne są prawie zawsze typami wartościowymi .

Większość języków nie pozwala na modyfikowanie przez programy zachowania lub możliwości prymitywnych (zarówno wbudowanych, jak i podstawowych) typów danych. Wyjątkiem jest Smalltalk , który pozwala na rozszerzanie wszystkich typów danych w programie, dodawanie operacji, które można na nich wykonać, a nawet redefiniowanie operacji wbudowanych.

Przegląd

Rzeczywisty zakres dostępnych typów danych pierwotnych zależy od używanego języka programowania. Na przykład w języku C # , ciągi są kompozytem ale wbudowany typ danych, natomiast we współczesnych dialektów BASIC i JavaScript są one zaliczane do prymitywnego typu danych, który jest jednocześnie proste i wbudowanej.

Klasyczne podstawowe typy prymitywne mogą obejmować:

Powyższe prymitywy są generalnie obsługiwane mniej więcej bezpośrednio przez sprzęt komputerowy, z wyjątkiem być może operacji zmiennoprzecinkowych, więc operacje na takich prymitywach są zwykle dość wydajne. Niektóre języki programowania obsługują ciągi tekstowe jako prymitywne (np. BASIC), podczas gdy inne traktują ciąg tekstowy jako tablicę znaków (np. C). Niektóre komputery (np. x86) mają instrukcje, które pomagają radzić sobie z ciągami tekstowymi, ale pełna obsługa sprzętowa ciągów tekstowych jest rzadkością.

Łańcuchy mogą być dowolnymi seriami znaków w używanym kodowaniu . Aby oddzielić ciągi od kodu, większość języków umieszcza je w pojedynczych lub podwójnych cudzysłowach. Na przykład „Witaj świecie” lub „Witaj świecie”. Zauważ, że "200" może być pomylone z typem całkowitym, ale w rzeczywistości jest typem ciągu, ponieważ jest zawarte w podwójnych cudzysłowach.

Bardziej wyrafinowane typy, które można wbudować, obejmują:

Specyficzne typy danych pierwotnych

Liczby całkowite

Całkowita typ danych reprezentuje pewien zakres liczb matematycznych . Liczby całkowite mogą być ze znakiem (dopuszczanie wartości ujemnych) lub bez znaku ( tylko nieujemne liczby całkowite ). Typowe zakresy to:

Rozmiar ( bajty ) Rozmiar ( bity ) Nazwy Podpisany zakres (zakładając uzupełnienie do dwóch dla podpisanego ) Zakres bez znaku
1 bajt 8 bitów Bajt , oktet , minimalny rozmiar charw C99 ( patrz limity.h CHAR_BIT ) -128 do +127 0 do 255
2 bajty 16 bitów x86 słowo , minimalny rozmiar shorti intw C -32 768 do +32 767 0 do 65 535
4 bajty 32 bity podwójne słowo x86, minimalny rozmiar longw C, rzeczywisty rozmiar intdla większości nowoczesnych kompilatorów C, wskaźnik na procesory zgodne z IA-32 -2147483648 do +2147483647 0 do 4 294 967 295
8 bajtów 64 bity x86 poczwórne słowo, minimalny rozmiar long longw C, rzeczywisty rozmiar longdla większości nowoczesnych kompilatorów C, wskaźnik dla procesorów kompatybilnych z x86-64 -9 223 372 036 854 775 808 do +9 223 372 036 854 775 807 0 do 18 446 744 073 709 551 615
nieograniczona/8 Nieograniczony Bignum -2 nieograniczona /2 do +(2 nieograniczona /2 − 1) 0 do 2 nieograniczony − 1

Literały dla liczb całkowitych można zapisać jako zwykłe cyfry arabskie , składające się z ciągu cyfr i z negacją oznaczoną znakiem minus przed wartością. Jednak większość języków programowania nie zezwala na używanie przecinków lub spacji do grupowania cyfr . Przykładami literałów całkowitych są:

  • 42
  • dziesięć tysięcy
  • -233000

Istnieje kilka alternatywnych metod pisania literałów całkowitych w wielu językach programowania:

  • Większość języków programowania, zwłaszcza tych, na które ma wpływ C , poprzedza literał całkowity z 0X lub 0x, aby reprezentować wartość szesnastkową , np . 0xDEADBEEF . Inne języki mogą używać innej notacji, np. niektóre języki asemblerowe dodają H lub h na końcu wartości szesnastkowej.
  • Perl , Ruby , Java , Julia , D , Rust i Python (począwszy od wersji 3.6) umożliwiają osadzone podkreślenia dla przejrzystości, np. 10_000_000 , a Fortran o stałej formie ignoruje osadzone spacje w literałach całkowitych.
  • W C i C++ początkowe zero oznacza wartość ósemkową , np . 0755 . To było przeznaczone głównie do użytku z trybami Unix ; jednak został skrytykowany, ponieważ normalne liczby całkowite mogą również prowadzić z zerem. Jako takie, Python , Ruby , Haskell i OCaml prefiks wartości ósemkowych z 0O lub 0o , zgodnie z układem używanym przez wartości szesnastkowe.
  • Kilka języków, w tym Java , C# , Scala , Python , Ruby i OCaml , może reprezentować wartości binarne przez poprzedzenie liczby 0B lub 0b .

Liczb zmiennoprzecinkowych

Liczba zmiennoprzecinkowa reprezentuje liczbę wymierną o ograniczonej precyzji, która może mieć część ułamkową. Liczby te są przechowywane wewnętrznie w formacie odpowiadającym notacji naukowej , zazwyczaj w postaci binarnej, ale czasami dziesiętnej . Ponieważ liczby zmiennoprzecinkowe mają ograniczoną precyzję, tylko podzbiór liczb rzeczywistych lub wymiernych jest dokładnie reprezentowany; inne liczby mogą być reprezentowane tylko w przybliżeniu.

Wiele języków ma zarówno pojedynczą precyzję (często nazywaną „zmiennoprzecinkową”), jak i typ o podwójnej precyzji .

Literały dla liczb zmiennoprzecinkowych zawierają kropkę dziesiętną i zwykle używają e lub E do oznaczenia notacji naukowej. Przykładami literałów zmiennoprzecinkowych są:

  • 20.0005
  • 99,9
  • -5000,12
  • 6.02e23

Niektóre języki (np. Fortran , Python , D ) mają również złożony typ liczbowy składający się z dwóch liczb zmiennoprzecinkowych: części rzeczywistej i części urojonej.

Liczby stałoprzecinkowe

Liczba stałoprzecinkowa reprezentuje liczbę wymierną o ograniczonej precyzji, która może mieć część ułamkową. Liczby te są przechowywane wewnętrznie w postaci przeskalowanych liczb całkowitych, zwykle w postaci binarnej, ale czasami dziesiętnej . Ponieważ liczby stałoprzecinkowe mają ograniczoną precyzję, tylko podzbiór liczb rzeczywistych lub wymiernych jest dokładnie reprezentowany; inne liczby mogą być reprezentowane tylko w przybliżeniu. Liczby stałoprzecinkowe mają również tendencję do posiadania bardziej ograniczonego zakresu wartości niż zmiennoprzecinkowe , dlatego programista musi uważać, aby uniknąć przepełnienia obliczeń pośrednich, a także wyniku końcowego.

Boole'a

Logiczna typu, zazwyczaj oznaczone „bool” lub „logiczna”, jest zazwyczaj logiczne typu , które mogą mieć albo wartość „true” albo wartość „false”. Chociaż do dostosowania zestawu wartości „true” i „false” potrzebny jest tylko jeden bit, języki programowania zazwyczaj implementują typy logiczne jako jeden lub więcej bajtów.

Wiele języków (np. Java , Pascal i Ada ) implementuje wartości logiczne zgodnie z koncepcją wartości logicznej jako odrębnego typu logicznego. Jednak języki mogą czasami niejawnie konwertować wartości logiczne na typy liczbowe, aby nadać rozszerzoną semantykę wyrażeniom boolowskim i wyrażeniom boolowskim lub uzyskać zgodność wsteczną z wcześniejszymi wersjami języka. Na przykład wczesne wersje języka programowania C, które były zgodne z ANSI C i jego poprzednimi standardami, nie miały dedykowanego typu logicznego. Zamiast tego wartości liczbowe zero są interpretowane jako „fałsz”, a każda inna wartość jest interpretowana jako „prawda”. Nowszy C99 dodał odrębny typ logiczny, który można dołączyć do stdbool.h , a C++ obsługuje booljako typ wbudowany oraz "true" i "false" jako słowa zastrzeżone.

Znaki i ciągi

Charakter typu (zwykle nazywane „char”) może zawierać jedną literę , cyfrę , znak interpunkcyjny , symbol , kod formatowania, kod sterujący lub jakiś inny kod specjalistycznej (np bajt znaku zamówienie ). W ° C , charokreśla się jako najmniejszą adresowalnego urządzenia pamięci. W większości systemów jest to 8 bitów ; Kilka standardów, takich jak POSIX , wymaga tego rozmiaru. Niektóre języki mają dwa lub więcej typów znaków, na przykład typ jednobajtowy dla znaków ASCII i typ wielobajtowy dla znaków Unicode . Termin „typ znaku” jest zwykle używany nawet w przypadku typów, których wartości dokładniej reprezentują jednostki kodu , na przykład jednostka kodu UTF-16 , jak w Javie (obsługa ograniczona tylko do znaków 16-bitowych) i JavaScript .

Znaki można łączyć w ciągi . Dane ciągu mogą zawierać liczby i inne symbole liczbowe, ale są traktowane jako tekst. Na przykład, operacje matematyczne, które można wykonać na wartości liczbowej (np. 200), generalnie nie mogą być wykonane na tej samej wartości zapisanej jako ciąg (np. "200").

Łańcuchy są implementowane na różne sposoby, w zależności od języka programowania. Najprostszym sposobem na zaimplementowanie łańcuchów jest utworzenie ich jako tablicy znaków, po której następuje znak ograniczający używany do sygnalizowania końca łańcucha, zwykle NUL . Są one określane jako ciągi zakończone znakiem null i zwykle można je znaleźć w językach o małej abstrakcji sprzętowej , takich jak C i Assembly . Chociaż łatwe do zaimplementowania, łańcuchy zakończone znakiem null były krytykowane za powodowanie przepełnień bufora . Większość języków skryptowych wysokiego poziomu, takich jak Python , Ruby i wiele dialektów BASIC , nie ma oddzielnego typu znaków; ciągi o długości jeden są zwykle używane do reprezentowania pojedynczych znaków. Niektóre języki, takie jak C ++ i Java , mają zdolność do korzystania znakiem NUL łańcuchów (zwykle dla środków wstecznej kompatybilności), ale dodatkowo zapewniają własną klasę do obsługi smyczkową ( std::stringi java.lang.String, odpowiednio) w bibliotece standardowej.

Istnieje również różnica w tym, czy łańcuchy są mutowalne lub niezmienne w danym języku. Zmienne ciągi mogą zostać zmienione po ich utworzeniu, podczas gdy niezmienne ciągi zachowują stały rozmiar i zawartość. W tym ostatnim jedynym sposobem na zmianę ciągów jest tworzenie nowych. Każde podejście ma zarówno zalety, jak i wady: chociaż ciągi niezmienne są znacznie mniej elastyczne, są prostsze i całkowicie bezpieczne wątkowo . Niektóre przykłady języków, które używają zmiennych ciągów to C++ , Perl i Ruby , podczas gdy języki, które nie zawierają JavaScript , Lua , Python i Go . Kilka języków, takich jak Objective-C , udostępnia różne typy ciągów zmiennych i niezmiennych.

Literały dla znaków i łańcuchów są zwykle otoczone cudzysłowami : czasami pojedyncze cudzysłowy ( ' ) są używane dla znaków , a podwójne ( " ) są używane dla łańcuchów. Python akceptuje oba warianty jako notację łańcuchową.

Przykłady literałów znakowych w składni C to:

Przykładami literałów napisowych w składni C są:

  • "A"
  • "Witaj świecie"
  • „Są 4 koty”.

Numeryczne zakresy typów danych

Każdy numeryczny typ danych ma swoją maksymalną i minimalną wartość zwaną zakresem . Próba przechowania liczby spoza zakresu może prowadzić do błędów kompilatora/środowiska wykonawczego lub do nieprawidłowych obliczeń (z powodu obcięcia ) w zależności od używanego języka.

Zakres zmiennej jest oparty na liczbie bajtów użytych do zapisania wartości, a typ danych całkowitych zwykle może przechowywać 2 n wartości (gdzie n to liczba bitów, które składają się na wartość). W przypadku innych typów danych (np. wartości zmiennoprzecinkowych ) zakres jest bardziej skomplikowany i będzie się różnić w zależności od metody użytej do jego przechowywania. Istnieją również typy, które nie używają całych bajtów, np. boolean, który wymaga pojedynczego bitu i reprezentuje wartość binarną (chociaż w praktyce często używany jest bajt, a pozostałe 7 bitów jest nadmiarowych). Niektóre języki programowania (takie jak Ada i Pascal ) pozwalają również na przeciwny kierunek, to znaczy programista określa zakres i precyzję potrzebną do rozwiązania danego problemu, a kompilator automatycznie wybiera najbardziej odpowiedni typ liczb całkowitych lub zmiennoprzecinkowych.

Zobacz też

Bibliografia

Zewnętrzne linki