Почему sizeof(int) = 4 а sizeof(int*) = 8? [закрыт]
Вопрос вызван проблемой, которая больше не воспроизводится, или опечаткой. Хотя похожие вопросы могут быть уместны на этом сайте, решение для этого вопроса вряд ли поможет будущим посетителям. Обычно можно избежать подобных вопросов написанием и исследованием минимальной программы для воспроизведения проблемы до публикации вопроса.
Закрыт 1 год назад .
Написал следующий код
#include #include int main()
Вывод следующий
Integer: 4 PtrInteger: 8
Почему так? Почему PtrInteger не равен 4?
Отслеживать
задан 17 авг 2022 в 7:27
У вас же 64 битная система? Указатель это адрес, размер адреса = размеру слова в процессоре (и разрядности ОС). А вот значение int обычно (так повелось издревле) 4 байта или 32 разряда
17 авг 2022 в 7:34
Очевидно, что вы компилируете 64-х битный код. Т.е. указатель размером 64 бита. 64/8==8
17 авг 2022 в 7:34
Все указатели занимают 8 байт.
17 авг 2022 в 18:38
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Потому что в указателе хранится код ячейки памяти, который в зависимости от разрядности системы занимает 32 или 64 бита, т.е. 4 или 8 байт соответственно, о чем вам и говорит sizeof . int же имеет диапазон в чисел от −2 147 483 648 до 2 147 483 647, что соответствует 2 32 вариантам чисел, которые можно вписать в него, а значит он должен занимать 32 бита, или же 4 байта.
Отслеживать
ответ дан 17 авг 2022 в 7:40
1,767 2 2 золотых знака 5 5 серебряных знаков 17 17 бронзовых знаков
С единственным дополнением: int же [обычно] занимает 32 бита, или 4 байта, а значит, имеет диапазон представления от . и до . Ни размер, ни диапазон int в стандарте не указаны, да и плясать надо не от диапазона, а от размера.
17 авг 2022 в 8:13
Не совсем от разрядности системы. Я могу запустить х32 приложение на х64 винде, и там будут 4-байтные указатели.
Типы char, short, int и long
Целый тип char занимает в памяти 1 байт (8 бит) и позволяет выразить в двоичной системе счисления 2^8 значений=256. Тип char может содержать как положительные, так и отрицательные значения. Диапазон изменения значений составляет от -128 до 127.
uchar
Целый тип uchar также занимает в памяти 1 байт, как и тип char, но в отличие от него, uchar предназначен только для положительных значений. Минимальное значение равно нулю, максимальное значение равно 255. Первая буква u в названии типа uchar является сокращением слова unsigned (беззнаковый).
short
Целый тип short имеет размер 2 байта(16 бит) и, соответственно, позволяет выразить множество значений равное 2 в степени 16: 2^16=65 536. Так как тип short является знаковым и содержит как положительные, так и отрицательные значения, то диапазон значений находится между -32 768 и 32 767.
ushort
Беззнаковым типом short является тип ushort, который также имеет размер 2 байта. Минимальное значение равно 0, максимальное значение 65 535.
int
Целый тип int имеет размер 4 байта (32 бита). Минимальное значение -2 147 483 648, максимальное значение 2 147 483 647.
uint
Беззнаковый целый тип uint занимает в памяти 4 байта и позволяет выражать целочисленные значения от 0 до 4 294 967 295.
long
Целый тип long имеет размер 8 байт (64 бита). Минимальное значение -9 223 372 036 854 775 808, максимальное значение 9 223 372 036 854 775 807.
ulong
Целый тип ulong также занимает 8 байт и позволяет хранить значения от 0 до 18 446 744 073 709 551 615.
char ch= 12 ;
short sh=- 5000 ;
int in= 2445777 ;
Так как беззнаковые целые типы не предназначены для хранения отрицательных значений, то попытка установить отрицательное значение может привести к неожиданным последствиям. Вот такой невинный скрипт приведет к бесконечному циклу:
//— бесконечный цикл
void OnStart ()
<
uchar u_ch;
for ( char ch=-128;ch <128;ch++)
<
u_ch=ch;
Print ( «ch = » ,ch, » u_ch = » ,u_ch);
>
>
Правильно будет так:
//— правильный вариант
void OnStart ()
<
uchar u_ch;
for ( char ch=-128;ch <=127;ch++)
<
u_ch=ch;
Print ( «ch = » ,ch, » u_ch = » ,u_ch);
if (ch==127) break ;
>
>
ch= -128 u_ch= 128
ch= -127 u_ch= 129
ch= -126 u_ch= 130
ch= -125 u_ch= 131
ch= -124 u_ch= 132
ch= -123 u_ch= 133
ch= -122 u_ch= 134
ch= -121 u_ch= 135
ch= -120 u_ch= 136
ch= -119 u_ch= 137
ch= -118 u_ch= 138
ch= -117 u_ch= 139
ch= -116 u_ch= 140
ch= -115 u_ch= 141
ch= -114 u_ch= 142
ch= -113 u_ch= 143
ch= -112 u_ch= 144
ch= -111 u_ch= 145
.
//— отрицательные значения нельзя хранить в беззнаковых типах
uchar u_ch=-120;
ushort u_sh=-5000;
uint u_in=-401280;
Шестнадцатеричные: цифры 0-9, буквы а-f или А-F для значений 10-15; начинаются с 0х или 0Х.
0x0A , 0x12 , 0X12 , 0x2f , 0xA3 , 0Xa3 , 0X7C7
Какой тип данных на всех процессорах будет 4 байта (не указатель и не вещественное число)?
Тип int может быть и 2 байта, я конечно таких процессоров не видел но пишут что бывает.
Я присматриваюсь к знаковому типу, если таковых нет предложите без знаковый.
Может быть long ? Или есть инструкции что он тоже может быть 2 байта?
Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Enum и типы данных. Как задать тип значений явно, и какой тип будет при переполнении?
Пытаюсь сделать функцию с передачей нескольких параметров,используя битовые операции. В качестве.
Вещественное число (4 байта)
Как описать в Pascal ABC вещественное число длиной 4 байта (как float на C), если SizeOf(real)=8.
Прочитать 4 байта как вещественное число с плавающей точкой
Всем здравствуйте. имеется байтовый массив из четырёх байт как прочитать его как одно значение.
Добавляются дополнительные разряды в вещественное число после запятой при получении данных из базы (тип float)
Доброго времени суток. При записи вещественных чисел из базы данных MS SQL в переменные.
1742 / 1036 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
Сообщение было отмечено Nexi99 как решение
Решение
143 / 27 / 4
Регистрация: 06.05.2019
Сообщений: 1,739
Записей в блоге: 4
Сообщение от L0M
он строго заточен на 32 бита т.е. на 4 байта?
11126 / 6084 / 1663
Регистрация: 18.10.2014
Сообщений: 15,295
Сообщение от Nexi99
Какой тип данных на всех процессорах будет 4 байта (не указатель и не вещественное число)?
Сколько можно повторять одно и то же: что такое «байт». И при чем здесь «процессоры» вообще?
В C++ байт — это std::byte или unsigned char . sizeof(std::byte) всегда равно 1. Фундаментального типа с гарантированным размером ровно в 4 байта нет и быть не может в принципе, ибо ширина байта в С и С++ не фиксирована.
Никакое std::int32_t ответом на этот вопрос не является, ибо sizeof(std::int32_t) запросто может быть равен и 1, и 2. (Это не говоря уже от том, что std::int32_t может просто не быть вообще.)
Поэтому только так:
using Bytes4 = std::byte[4];
using Bytes4 = char[4];
143 / 27 / 4
Регистрация: 06.05.2019
Сообщений: 1,739
Записей в блоге: 4
Сообщение от TheCalligrapher
Никакое std::int32_t ответом на этот вопрос не является
Ну человек предложил свой вариант. Возникает вопрос где же мне найти тип данных который всегда будет 4. Я использую int но так получилось что не у всех он занимает 4, значит надо что-то подобрать.
Добавлено через 5 минут
вот что пишут
1.Во-первых, зачем нам нужен int32_t, поскольку у нас уже есть разные варианты для него, такие как short int unsigned int и т. д.
Потому что short int, unsigned int и т. д. не переносятся среди архитектур.
Если вы имеете в виду ровно 32 бита, просто скажите это явно. В противном случае вы можете использовать 64 бита, просто используя unsigned int с другой архитектурой CPU.
2.Во-вторых, использование этого типа типов фиксированного размера делает программы портативными?
Да, как упоминалось выше.
1) int32_t обеспечивает точное 32-битное целое число . Это важно, потому что вы можете переносить свои приложения на разные платформы без алгоритма перезаписи (если они будут компилироваться и да, int не всегда 16 или 32 или 64 бит, проверьте ссылку C). Проверьте хорошую страницу с пояснениями о типах stdint.h
так что да мы явно указывает сколько конкретно будет занимать тип. Другой вопрос если попадётся компьютер на 10 бит и более так тут уже да сложно.
Добавлено через 1 минуту
Сообщение от TheCalligrapher
using Bytes4 = char[4];
Использование байтов конечно надёжнее, если так то как из этих ваших записей получить 4ёх байтовый тип чтобы объявить переменную?
11126 / 6084 / 1663
Регистрация: 18.10.2014
Сообщений: 15,295
— Петька, приборы!
— 300
— Что «300»?
— А что «приборы»?
Сообщение от Nexi99
Возникает вопрос где же мне найти тип данных который всегда будет 4.
4 чего? Еще раз: вам нужно сначала определиться, что вы назваете «байтом». С-байт, т.е. единицу измерения sizeof ? Или, может быть, октет, т.е. 8 бит? Или что-то еще?
Без этого ваш вопрос бессмыслен.
Сообщение от Nexi99
Во-первых, зачем нам нужен int32_t, поскольку у нас уже есть разные варианты для него, такие как short int unsigned int и т. д.
Потому что short int, unsigned int и т. д. не переносятся среди архитектур.
Де-факто или де-юре?
Де-юре, int32_t тоже не переносится среди архитектур. Все типы фиксированной ширины являются опциональными.
Сообщение от Nexi99
int32_t обеспечивает точное 32-битное целое число
Так что именно вам нужно: 32-битовое целое число или 4-байтовое целое число? Почему ваш вопрос сформулирован в теминах байтов, а здесь вдруг речь зашла о битах?
143 / 27 / 4
Регистрация: 06.05.2019
Сообщений: 1,739
Записей в блоге: 4
Сообщение от TheCalligrapher
Еще раз: вам нужно сначала определиться, что вы назваете «байтом». С-байт, т.е. единицу измерения sizeof?
Ну да. Потому что если битами мерять то может попадётся и то что на 10 бит и int32_t тут уже не прокатит. Вы говорите что этот тип может тоже не переносится среди архитектур, так что нету такого типа который будет хранить 4 байта?
Добавлено через 29 секунд
Сообщение от TheCalligrapher
Так что именно вам нужно: 32-битовое целое число или 4-байтовое целое число?
4 байтовое целое со знаком.
8737 / 4315 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
Сообщение от Nexi99
Какой тип данных на всех процессорах будет 4 байта (не указатель и не вещественное число)?
11126 / 6084 / 1663
Регистрация: 18.10.2014
Сообщений: 15,295
Сообщение от Nexi99
4 байтовое целое со знаком.
Сообщение от TheCalligrapher
4 чего? Еще раз: вам нужно сначала определиться, что вы назваете «байтом». С-байт, т.е. единицу измерения sizeof? Или, может быть, октет, т.е. 8 бит? Или что-то еще? Без этого ваш вопрос бессмыслен.
1742 / 1036 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
Теоретически, TheCalligrapher, вы в общем правы. Но к тому, что Bytes4 будет содержать ровно 32 бита (цитирую ТС: он строго заточен на 32 бита т.е. на 4 байта?), можно докопаться. Вы сами пишите, что ширина байта в С и С++ не фиксирована. Следовательно нельзя гарантировать, что char[4] содержит ровно 32 бита. Это с точки зрения Стандарта (теории).
С практической точки зрения, если не брать заведомо экзотическую архитектуру, байт всё-таки содержит именно 8 бит. И, опять-таки, если не брать экзотику, а популярные компиляторы под популярные архитектуры (а я думаю, что Nexi99 конкретно интересует архитектура x86, и вопрос проистекает либо из компиляции под x32/x64, либо размеров типа для разных компиляторов/платформ), то название типа std::int32_t как бы намекаэ. А если более формально, то см. Стандарт C++20 (у меня это Working Draft, Standard for Programming Language C++ N4849 от 2020-01-14), раздел 17.4.1 Header synopsis, который ссылается на раздел ISO C 7.20, в котором написано
7.20.1.1 Exact-width integer types
1 The typedef name intN_t designates a signed integer type with width N, no padding
bits, and a two’s complement representation. Thus, int8_t denotes such a signed
integer type with a width of exactly 8 bits.
2 The typedef name uintN_t designates an unsigned integer type with width N and no
padding bits. Thus, uint24_t denotes such an unsigned integer type with a width of
exactly 24 bits.
3 These types are optional. However, if an implementation provides integer types with
widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a
two’s complement representation, it shall define the corresponding typedef names.
Т.е. эти типы гарантируют указанную в их названии битность.
Другой вопрос, что эти типы могут быть не определны в библиотеке конкретного компилятора.
Добавлено через 6 минут
Ух, тут уже сколько написали.
TheCalligrapher, вы совсем зашпыняли ТС. В обыденности «байт» == 8 бит.
Ему просто нужно 32-битное знаковое число, которое бы не зависело от компилятора и битности приложения (32/64).
Почему char — 1 байт, а символьный литерал (‘A’) — 4?
Я понял, что то, что мы называем символами, на самом деле является числовым кодом, а потому символьным литералам выделяется столько же памяти, сколько и типу int (4 байта).
Но я не совсем понял, как в однобайтный char вмещается четырехбайтный символ?
И когда я объявляю char test = ‘A’; то сколько в компьютере выделилось памяти: 1 байт или 4?
(Если попробовать sizeof(test), то выйдет, что все таки 1. Но ведь ‘A’ — это 4 байта?)
- Вопрос задан более двух лет назад
- 801 просмотр
1 комментарий
Простой 1 комментарий
David Park , потому что типом ‘A’ является int .
Решения вопроса 1
Программист на «си с крестами» и не только
А теперь скажу правильный ответ.
В Си символьный литерал имеет тип int и потому его sizeof 4 байта.
В Си++ у него тип char и 1 байт. Потому те, кто создавал CPP-файл, проблемы не видели. Очевидно, связано с перегрузкой функций: как-то не хочется, чтобы в foo(‘A’) вызывалась версия для int.
#include int main() < int sz = sizeof('A'); // латинское printf("sz = %d\n", sz); return 0; >
При написании char test=’A’ на стеке будет 1 байт (+выравнивание). Здесь Си, грубо говоря, проводит преобразование типа — прямо при компиляции. Если написать char test=L’Й’ , сообщит, что преобразование при компиляции ushort→char обрежет результат с 1049 до 25.
Ответ написан более двух лет назад
Комментировать
Нравится 4 Комментировать
Ответы на вопрос 4
Saboteur @saboteur_kiev
software engineer
Я понял, что то, что мы называем символами, на самом деле является числовым кодом
Все в компьютере хранится в виде бит, сгруппированных по байтам.
Символ — абстракция для упрощения программирования, и есть различные таблицы кодировки для того, чтобы преобразовывать байты в символы при выводе на экран.
Количество байт, нужных на символ зависит собственно от кодировки.
В старых кодировках один байт означал один символ, в современных UTF, количество байт может быть разное (до 6 байт на символ в виде иероглифа).
а потому символьным литералам выделяется столько же памяти, сколько и типу int (4 байта).
Юзай typeid чтобы уточнить тип данных
Но я не совсем понял, как в однобайтный char вмещается четырехбайтный символ?
никак, это не char.
в С по дефолту char это однобайтный символ в ascII
И когда я объявляю char test = ‘A’; то сколько в компьютере выделилось памяти: 1 байт или 4?
Ты же сам указываешь тип при объявлении. Надо было привести код целиком.
(Если попробовать sizeof(test), то выйдет, что все таки 1. Но ведь ‘A’ — это 4 байта?)
‘A’ это значение, а не тип. Может быть это int?
Ответ написан более двух лет назад
Комментировать
Нравится 1 Комментировать
А нечего русские буквы в char запихивать
In (1), if c-char is not a numeric character sequence and is not representable as a single byte in the execution character set, the character literal is conditionally supported, has type int and implementation-defined value.
Ответ написан более двух лет назад
70-C9-4E-54-03-2F @Xproz Автор вопроса
char test = ‘Z’;
sizeof(test) = 1
sizeof(‘Z’) = 4
Вопрос, как в однойбайтовый char поместился четырехбайтовых ‘Z’ и сколько в итоге выделилось памяти после char test = ‘Z’, все еще остается открытым
David Park, ок, извините, тут C, а в нем, как ни странно, char литералы имеют тип int. Почему — а хрен его знает, так сложилось со времен К&Р (почитайте, например, тут, если хотите).
В плюсах такие литералы имеют тип char и размер 1 байт.
Вопрос, как в однойбайтовый char поместился четырехбайтовых ‘Z’ и сколько в итоге выделилось памяти после char test = ‘Z’,
сконвертится до байта. Ровно так же, как если бы вы написали char c = 1;
1 — имеет тип int, но это же не вызывает вопросов у вас?
#include #include //for 'typeid' to work using namespace std; int main ()
Как у вас 4 байта получилось?
Ответ написан более двух лет назад
70-C9-4E-54-03-2F @Xproz Автор вопроса
Не знаю, принципиально ли это здесь, но я писал на языке Си.
В книге (по Си) поясняется, что символьный литерал хранится в виде числового кода, поэтому для него выделяется 4 байта (столько же выделяется и для int).
Дальше поясняется, что под char — выделяется 1 байт.
Но как именно в char залез символ, под который выделяется 4 байта, я не понял.
sizeof(‘Y’) = 4 байт
char y = ‘Y’
sizeof(y) = 1 байт
#include #include #include #include #define typename(x) _Generic((x), /* Get the name of a type */ \ \ _Bool: "_Bool", unsigned char: "unsigned char", \ char: "char", signed char: "signed char", \ short int: "short int", unsigned short int: "unsigned short int", \ int: "int", unsigned int: "unsigned int", \ long int: "long int", unsigned long int: "unsigned long int", \ long long int: "long long int", unsigned long long int: "unsigned long long int", \ float: "float", double: "double", \ long double: "long double", char *: "pointer to char", \ void *: "pointer to void", int *: "pointer to int", \ default: "other") #define fmt "%20s is '%s'\n" int main()
‘A’ — это int.
Видать для поддержки всякого не влазящего в чар