В С есть тип long. Согласно: Wiki c-types он занимет в памяти 4 байта, да и диапазон значений у него такой же как и у int.
Тогда зачем он нужен?
Выписка из wiki:
int:
Основной тип целого числа со знаком. Может содержать числа в диапазоне [−32767, +32767]. range;[3][4] Таким образом, это по крайней мере 16 бит (2 байта). На практике, во всех современных компиляторах имеет размер в 4 байта и диапазон [-2147483648, +2147483647]
long:
Тип длинного целого числа со знаком. Может содержать числа, как минимум, в диапазоне [−2 147 483 647, +2 147 483 647].[3][4] Таким образом, это по крайней мере 32 бита (4 байта).
Процессоры развивались постепенно все более расширяя емкость регистров. Например, ранее в DOS тип int соответствовал 16 разрядному целочисленному значению, так как на IBM-совместимых компьютеров регистры были 16-разрядными. Например, регистр AX является 16 разрядным, а его подрегистры AL и AH имели разрядность равную 8 битам. До этого вообще регистры процессоров были 8 разрядными.
Если выполнить, допустим, умножение двух объектов 16-разрядного типа int, то для хранения результата нужно использовать два регистра как, например, регистры AX и DX. Для этого результата уже нужно вводить новый целочисленный тип. И такой тип был введен. Это тип long .
Затем появились 64-разрядные процессоры. Необходимо различать 16-разрядные целые числа, 32-разрядные целые числа и 64- разрядные целые числа. Поэтому был введен дополнительный целый тип Long long. Имейте в виду, что нужно было сохранять обратную совместимость с целыми типами, введенными ранее для процессоров с меньшей разрядностью.
Поэтому в стандарте C принято, что
sizeof( short ) <= sizeof( int )
sizeof( int ) <= sizeof( long )
sizeof( long ) <= sizeof( long long )
У разработчиков компиляторов есть свобода выбора, какая разрядность будет у типа long и других целочисленных типов. Например, разрядность типа long может составлять не `32 бита, а 64 бита.
Чтобы программы были переносимы, возникла необходимость вводить новые типы со строго указанной разрядностью такие, как, например, int_least32_t или int32_t.
На одних 64-битовых платформах тип long и тип long long могут иметь 64-битовуж разрядность. На других 64-битовых платформах тип long может быть 32-битовым и тип int также может быть 32-битовым, а тип long long - 64 битовым.
Тем не менее ранг типа long long больше ранга типа long, а тип long в свою очередь имеет ранг выше, чем тип int.
На этом основываются правила преобразования типов в выражениях. Например, если тип long и тип int имеют разрядность равную 32 битам, то в следующем фрагменте кода
long x = 0;
unsigned int y = 0;
x + y;
тип выражения x + y имеет тип unsigned long.
В связи с этим имеются некоторые курьезы, связанные с такими преобразованиями особенно при выборе перегруженной функции в C++.
Один из таких примеров описан в следующей теме, где ближе к ее концу (можно быстро найти это сообщение по ключевому слову int64_t) описывается один из таких курьезов, связанных с вызовом перегруженной функции, у которой параметр имеет тип std::int64_t, который, как оказалось, является не алиасом типа long long int, а алиасом типа long int, который на данной платформе является 64-битовым.
Размеры типов int и long не регламентированы Стандартом языка. Но регламентировано отношение их размеров, т.е. sizeof(int) <= sizeof(long).
На текущий момент можно сказать, что размер long зависит как от разрядности процессора, так и от используемой ОС. Например, для Linux и MacOS он будет 8 байт для 64bit архитектур, и 4 байта для 32bit архитектур. В Windows размер будет 4 байта, независимо от разрядности архитектуры.
Например, в Стандарте С++ даже встречается такой пример:
static_assert(sizeof(long) >= 8, "64-bit code generation required for this library.");
Использовать разные типы можно, например, для обеспечения перегрузки функций:
void f(int) {}
void f(long) {}
f(42); // int
f(42L); // long
Также не стоит забывать, что данные типы имеют разный ранг (integer conversion rank), что влияет на правила преобразования целочисленных типов.
Тип long не "занимает в памяти 4 байта". Он занимает как минимум 32 бита, т.е. имеет диапазон как минимум [−2147483647, +2147483647]. А сверху его размер не ограничен.
Тип int занимает как минимум 16 бит, ибо имеет диапазон как минимум [−32767, +32767] (как вы сами заметили).
Поэтом не совсем ясно, откуда вы взяли предположение об одинаковости диапазонов этих типов - уже из процитированного вами видно, что они запросто могут быть разными.
В языке С++ система целочисленных типов обладает тем свойством, что
sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
т.е. вполне возможно что размеры (и диапазоны) этих типов все будут различными.
В языке С, по каким-то историческим причинам, это соотношение определяется как
диапазон(signed char) ⊆ диапазон(short) ⊆ диапазон(int) ⊆ диапазон(long) ⊆ диапазон(long long)
Но идея, понятное дело, в обоих случаях одна и та же. И все эти типы могут быть различными с точки зрения диапазона. Как, впрочем, все они могу быть и одинаковыми с точки зрения размера и диапазона.
То, что у вас на какой то платформе тип long совпал по представлению с типом int является лишь особенностью вашей платформы.
Язык C предлагает Вам множество типов. В частности гарантированно, что int не больше long. А long не больше long long. Вы выбираете по своим нуждам и удобству.
Когда тип используются часто, то компилятор оптимизирует работу с ним. После оптимизации в компиляторе, начинают рекомендовать использование типа для каких-то целей.
На разных архитектурах ЭВМ разные размеры регистров процессора, но соотношение размеров типов сохраняется.
Простыми словами: часто использовали int в программах, поэтому его вытянули под размер 4 байта на PC, что соответствует регистру процессора x32. long не стали вытягивать до 8 байт, потому что на x32 потребуется две команды процессору вместо одной. Но не удалять же long, ведь его используют какие-то программы.
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости