Literał całkowity

W informatyce literał całkowity jest rodzajem literału dla liczby całkowitej , której wartość jest bezpośrednio reprezentowana w kodzie źródłowym . Na przykład w instrukcji przypisania x = 1 łańcuch 1 jest literałem całkowitym wskazującym wartość 1, podczas gdy w instrukcji x = 0x10 ciąg 0x10 jest literałem całkowitym wskazującym wartość 16, która jest reprezentowana przez 10 w systemie szesnastkowym ( wskazany przez 0x prefiks).

Z kolei w x = cos(0) wyrażenie cos(0) zwraca 1 (jako cosinus 0), ale wartość 1 nie jest dosłownie zawarta w kodzie źródłowym. Mówiąc prościej, w przypadku x = 2 + 2 wyrażenie 2 + 2 daje w wyniku 4, ale wartość 4 nie jest uwzględniona dosłownie. Ponadto w x = „1” 1” jest literałem łańcuchowym , a nie literałem całkowitym, ponieważ jest w cudzysłowach. Wartość łańcucha to 1 , co jest ciągiem całkowitym, ale jest to analiza semantyczna literału łańcuchowego – na poziomie składni „1” to po prostu ciąg znaków, niczym nie różniący się od „foo” .

Rozbiór gramatyczny zdania

Rozpoznanie ciągu znaków (sekwencji znaków w kodzie źródłowym) jako literału całkowitoliczbowego jest częścią fazy analizy leksykalnej (leksingu), podczas gdy ocena literału do jego wartości jest częścią fazy analizy semantycznej . W leksyce i gramatyce fraz klasa tokenów jest często oznaczana jako integer , przy czym małe litery wskazują klasę tokenów na poziomie leksykalnym, w przeciwieństwie do reguły produkcji na poziomie frazy (takiej jak ListOfIntegers ). Gdy łańcuch zostanie zapisany (tokenizowany) jako literał całkowity, jego wartości nie można określić składniowo (jest to po prostu liczbą całkowitą), a ocena jej wartości staje się kwestią semantyczną.

Literały całkowitoliczbowe są zazwyczaj leksykowane za pomocą wyrażeń regularnych , tak jak w Pythonie .

Ocena

Podobnie jak w przypadku innych literałów, literały całkowite są zazwyczaj oceniane w czasie kompilacji, jako część fazy analizy semantycznej. W niektórych przypadkach ta analiza semantyczna jest wykonywana w lekserze, natychmiast po rozpoznaniu literału całkowitego, podczas gdy w innych przypadkach jest to odroczone do etapu analizy składniowej lub do całkowitego zbudowania drzewa analizy . Na przykład, po rozpoznaniu łańcucha 0x10 , leksykon mógłby natychmiast ocenić to na 16 i zapisać to (token typu integer i wartość 16) lub odroczyć ocenę i zamiast tego zapisać token typu integer i value 0x10 .

Po oszacowaniu literałów możliwa jest dalsza analiza semantyczna w postaci ciągłego składania , co oznacza, że ​​wyrażenia literalne zawierające wartości literałów mogą być oceniane w fazie kompilacji. Na przykład w instrukcji x = 2 + 2 po obliczeniu literałów i przeanalizowaniu wyrażenia 2 + 2 można ją następnie ocenić na 4, chociaż sama wartość 4 nie pojawia się jako literał.

Afiksy

Literały całkowite często mają przedrostki wskazujące podstawę, a rzadziej sufiksy wskazujące typ. Na przykład w C++ 0x10ULL wskazuje wartość 16 (ponieważ szesnastkowa) jako liczbę całkowitą typu unsigned long long.

Typowe przedrostki obejmują:

Typowe przyrostki obejmują:

  • l lub L dla długiej liczby całkowitej;
  • ll lub LL dla long long integer;
  • u lub U dla liczby całkowitej bez znaku.

Te afiksy są nieco podobne do sigili , chociaż sigile dołączają się do identyfikatorów (nazw), a nie dosłownych.

Separatory cyfr

W niektórych językach literały całkowite mogą zawierać separatory cyfr, aby umożliwić grupowanie cyfr w bardziej czytelne formy. Jeśli jest to dostępne, zwykle można to zrobić również dla literałów zmiennoprzecinkowych. Jest to szczególnie przydatne w przypadku pól bitowych i ułatwia szybkie zobaczenie wielkości dużych liczb (takich jak milion) dzięki dzieleniu cyfr na mniejsze części niż na zliczaniu. Jest to również przydatne w przypadku numerów, które są zazwyczaj pogrupowane, na przykład numer karty kredytowej lub numer ubezpieczenia społecznego . Bardzo długie liczby można dalej grupować, podwajając separatory.

Zazwyczaj liczby dziesiętne (podstawa-10) są pogrupowane w trzy grupy cyfr (reprezentujące jedną z 1000 możliwych wartości), liczby binarne (podstawa-2) w czterocyfrowe grupy (jeden półbajt, reprezentujący jedną z 16 możliwych wartości), a liczby szesnastkowe ( base-16) w dwóch grupach cyfr (każda cyfra to jeden półbajt, więc dwie cyfry to jeden bajt , reprezentujący jedną z 256 możliwych wartości). Numery z innych systemów (takie jak numery identyfikacyjne) są pogrupowane zgodnie z obowiązującą konwencją.

Przykłady

W Ada , C# (od wersji 7.0), D , Eiffel , Go (od wersji 1.13), Haskell (od wersji GHC 8.6.1), Java (od wersji 7), Julia , Perl , Python (od wersji 3.6), Ruby , Rust i Swift , literały całkowite i literały zmiennoprzecinkowe można oddzielić znakiem podkreślenia ( _ ). Mogą istnieć pewne ograniczenia dotyczące umieszczania; na przykład w Javie nie mogą pojawiać się na początku ani na końcu literału ani obok kropki dziesiętnej. Zauważ, że chociaż kropka, przecinek i (cienkie) spacje są używane w normalnym piśmie do separacji cyfr, są one sprzeczne z ich istniejącym użyciem w językach programowania jako punkt podstawy, separator listy (a w C/C++ operator przecinka ) i separator tokenów.

Przykłady obejmują:

   
   
    int  jeden milion  =  1_000_000  ;  int  numer karty kredytowej  =  1234_5678_9012_3456  ;  int  socialSecurityNumber  =  123_45_6789  ; 

W C++ 14 (2014) i kolejnej wersji C od 2022 r., C23 , znak apostrofu może być używany do dowolnego oddzielania cyfr w literałach numerycznych. Podkreślenie zostało początkowo zaproponowane, ze wstępną propozycją w 1993 r., i ponownie dla C++ 11 , po innych językach. Spowodowało to jednak konflikt z literałami zdefiniowanymi przez użytkownika , więc zamiast tego zaproponowano apostrof jako „ górny przecinek ” (który jest używany w niektórych innych kontekstach).

   
   
  
     auto  integer_literal  =  1'000'000  ;  auto  litera_binarna  =  0b0100'1100'0110  ;  auto  very_long_binary_literal  =  0b0000'0001'0010'0011  ''  0100'0101'0110'0111  ; 

Notatki