Wydaje się, że wszystkie z nich zajmują 4 bajty przestrzeni,Jaka jest różnica między unsigned long/long/int in c/C++?
jaka jest różnica?
Wydaje się, że wszystkie z nich zajmują 4 bajty przestrzeni,Jaka jest różnica między unsigned long/long/int in c/C++?
jaka jest różnica?
Po pierwsze, rozmiar int/long jest nieokreślony. Tak więc na kompilatorze, int
i long
mogą być takie same, ale nie jest to uniwersalne w kompilatorach.
jako różnicę między unsigned long
i long
:
Zakładając 4 bajtów, long
ma szereg -2,147,483,648
do 2,147,483,647
. Długość bez znaku ma zakres od 0
do 4,294,967,295
.
Jedną z różnic jest przepełnienie. W przypadku typu podpisanego przepełnienie ma nieokreślone zachowanie. Ale w przypadku typu bez znaku przepełnienie jest gwarantowane, aby "zawinąć".
Różnica między unsigned long
a long
jest prosta - górna granica. Podpisany long
pochodzi z (na średnio 32-bitowym systemie) około -2,1 miliarda (-2^31) do +2,1 miliarda (+ 2^31 - 1), podczas gdy unsigned long
idzie od 0 do 4,2 miliarda (2^32 - 1).
Tak się składa, że w wielu kompilatorach i systemach operacyjnych (w tym, najwyraźniej Twój), int
jest także wartością 32-bitową. Ale standard C++ nie określa maksymalnych szerokości dla żadnego z tych typów, tylko co najmniej szerokości. W niektórych systemach int
ma 16 bitów. W niektórych systemach long
ma 64 bity. Wiele zależy od docelowej architektury procesora i jego podstawowego rozmiaru słowa.
Istnieje nagłówek definiujący maksymalną pojemność różnych typów w bieżącym środowisku kompilacji, a istnieje stdint.h
, aby zapewnić niezależne od środowiska typy gwarantowanej szerokości, takie jak int32_t
.
Niezależnie od systemu, 'int' i' long' mają tę samą długość - podstawowy rozmiar słowa. Czy to prawda? – user198729
Nie, wcale. W starszych 16-bitowych kompilatorach int ma zwykle 2 bajty, a długie 4 bajty. Nie ma tu twardych i szybkich reguł, jeśli chodzi o rozmiary, tylko względne. char zawsze będzie mniejsze lub równe short, które zawsze będzie mniejsze lub równe int, które zawsze będzie mniejsze lub równe long. Technicznie możesz przestrzegać standardu C++ i mieć wszystkie cztery z nich jeden bajt. –
Jak wybrać właściwy typ danych, gdy definicja jest tak mało precyzyjna ... – user198729
Specyfikacja języka C umożliwia implementację typów int i long w zależności od platformy w ramach kilku ograniczeń. Ta zmienność jest problemem dla kodu wieloplatformowego, ale jest także atutem, ponieważ umożliwia poinformowanemu programiście zbilansowanie celów projektowych między natywną szybkością procesora i pełnym zakresem numerycznym w architekturach sprzętowych, które nie oferują obu.
Ogólnie rzecz ujmując, "int" ma na celu zmapowanie rozmiaru rejestru maszynowej docelowej architektury architektury procesora, tak aby ładowanie, przechowywanie i działanie na danych typu int miało bezpośrednie przełożenie na operacje używające macierzystych rejestrów procesora docelowego. .
Wartość Int może być mniejsza niż wielkość rejestru maszyny w celu zaoszczędzenia miejsca w pamięci (duże pliki Ints zajmują dwa razy więcej pamięci RAM niż małe pliki Int). Powszechnie uważa się, że int jest obiektem 32-bitowym, nawet na 64-bitowych architekturach, gdzie zgodność ze starszymi systemami i efektywność pamięci są priorytetami.
"długi" może być tego samego rozmiaru lub większy niż "int" w zależności od rozmiarów rejestrów architektury docelowej. Operacje na "długim" mogą być zaimplementowane w oprogramowaniu, jeśli docelowa architektura nie obsługuje wartości dużych w swoich macierzystych rejestrach maszynowych.
Chipy procesora zaprojektowane dla energooszczędności lub urządzeń wbudowanych są tam, gdzie można znaleźć rozróżnienie między int i długim w tych dniach.Kompilatory dla procesorów ogólnego przeznaczenia, takich jak komputery stacjonarne lub przenośne, zazwyczaj traktują int i długie, o tym samym rozmiarze, ponieważ procesor wydajnie wykorzystuje rejestry 32-bitowe. Na mniejszych urządzeniach, takich jak telefony komórkowe, można zbudować procesor, który będzie obsługiwał dane 16-bitowe bardziej naturalnie i będzie musiał ciężko pracować, aby obsłużyć dane 32-bitowe lub większe.
Mniejsza liczba bitów na rejestr oznacza mniej obwodów wymaganych na chipie, mniej linii danych do przenoszenia i wyjmowania danych z układu, mniejsze zużycie energii i mniejszy rozmiar matrycy chipów, z których wszystkie powodują niższy koszt (w $ i w watach) urządzenie.
W takiej architekturze najprawdopodobniej okaże się, że int ma 16 bitów i ma długość 32 bitów. Może również występować kara za wydajność związana z używaniem długich, spowodowanych przez stany wait do ładowania 32 bitów w wielu odczytach przez 16-bitową magistralę danych, lub spowodowanych przez wdrażanie długich operacji (dodawanie, odejmowanie itp.) W oprogramowaniu, jeśli natywna sprzęt nie obsługuje takich operacji w sprzęcie.
Zgodnie z ogólną zasadą, jedyną rzeczą, którą można założyć na temat int i longs, jest to, że zakres int powinien zawsze być mniejszy lub równy długo w każdej architekturze. Powinieneś także założyć, że pewnego dnia Twój kod zostanie przekompilowany dla innej architektury, gdzie jakikolwiek związek, który obecnie widzisz pomiędzy int i long już nie istnieje.
Dlatego należy zachować ostrożność, aby zachować ints niezależnie od longs nawet w codziennym przyziemnym kodowaniu. Mogą być całkowicie kompatybilne z dzisiejszym zadaniem, ponieważ ich szczegóły implementacji dla twojej obecnej platformy sprzętowej są zbieżne, ale zbieg okoliczności nie jest gwarantowany na wszystkich platformach.
W jaki sposób zrobiono * wrap around *? – user198729
Zawijanie jest traktowane jako arytmetyka przepełnienia. Kiedy uderzysz (w przykładzie rlbond) 4294967296 w unsigned long, dodanie 1 spowoduje "zawinięcie" i stanie się wartością minimalną: 0. Dodanie 2 będzie owijać wokół i sprawi, że będzie to 1 itd. –
Wygląda na to, że różne rzeczy mogą również zrobić dla podpisanego typu, prawda? – user198729