Каков размер данных типа перечисления в С++? - программирование
Подтвердить что ты не робот

Каков размер данных типа перечисления в С++?

Это вопрос теста на С++, а не домашнее задание.

#include <iostream>
using namespace std;
enum months_t { january, february, march, april, may, june, july, august, september,    
  october, november, december} y2k;

 int main ()
  {
    cout << "sizeof months_t is  " << sizeof(months_t) << endl;
    cout << "sizeof y2k is  " << sizeof(y2k) << endl;
    enum months_t1 { january, february, march, april, may, june, july, august,    
       september, october, november, december} y2k1;
    cout << "sizeof months_t1 is  " << sizeof(months_t1) << endl;
    cout << "sizeof y2k1 is  " << sizeof(y2k1) << endl;
 }

Вывод:

sizeof months_t is 4
sizeof y2k - 4
sizeof months_t1 - 4
sizeof y2k1 равен 4

Почему размер всех этих 4 байтов? Не 12 x 4 = 48 байт?
Я знаю, что элементы объединения занимают одно и то же место памяти, но это перечисление.

4b9b3361

Ответ 1

Размер составляет четыре байта, поскольку enum хранится как int. Имея всего 12 значений, вам действительно нужны только 4 бита, но 32-разрядные машины обрабатывают 32-битные количества более эффективно, чем меньшие.

0 0 0 0  January
0 0 0 1  February
0 0 1 0  March
0 0 1 1  April
0 1 0 0  May
0 1 0 1  June
0 1 1 0  July
0 1 1 1  August
1 0 0 0  September
1 0 0 1  October
1 0 1 0  November
1 0 1 1  December
1 1 0 0  ** unused **
1 1 0 1  ** unused **
1 1 1 0  ** unused **
1 1 1 1  ** unused **

Без перечислений может возникнуть соблазн использовать сырые целые числа для представления месяцев. Это будет работать и быть эффективным, но это сделает ваш код трудным для чтения. С перечислениями вы получаете эффективное хранение и удобочитаемость.

Ответ 2

Это тестовый вопрос C++, а не домашняя работа.

Затем ваш интервьюер должен освежить свои воспоминания о том, как работает стандарт C++. И я цитирую:

Для перечисления, базовый тип которого не является фиксированным, базовый тип является целочисленным типом, который может представлять все значения перечислителя, определенные в перечислении.

Вся часть, "базовый тип которой не фиксированный", взята из C++ 11, но все остальные стандартные C++ 98/03. Короче говоря, sizeof(months_t) не равен 4. Это тоже не 2. Это может быть любой из них. Стандарт не говорит, какого размера он должен быть; только то, что он должен быть достаточно большим, чтобы соответствовать любому перечислителю.

почему весь размер 4 байта? не 12 х 4 = 48 байт?

Потому что перечисления не являются переменными. Члены перечисления не являются фактическими переменными; это просто полу-безопасная форма #define. Это способ хранения числа в удобном для читателя формате. Компилятор преобразует все виды использования перечислителя в фактическое числовое значение.

Перечислители - это просто еще один способ говорить о числе. january это просто сокращение для 0. А сколько места занимает 0? Это зависит от того, что вы храните его.

Ответ 3

Это зависит. Стандарт требует только того, чтобы он был достаточно большим для хранения всех значений, поэтому формальное перечисление типа enum foo { zero, one, two }; должно быть только одним байтом. Однако большинство реализаций делают эти перечисления такими же большими, как ints (что быстрее на современном оборудовании, более того, для совместимости с C, где перечисления в основном прославлены ints). Обратите внимание, однако, что С++ позволяет перечисления с инициализаторами вне диапазона int, и для этих перечислений размер, конечно, также будет больше. Например, если у вас есть enum bar { a, b = 1LL << 35 };, то ваше перечисление будет больше 32 бит (скорее всего, 64 бит) даже в системе с 32-битными int (обратите внимание, что в C это перечисление не будет разрешено).

Ответ 4

Перечисление вроде типа typedef для типа int (типа).

Итак, тип, который вы там определили, имеет 12 возможных значений, однако одна переменная имеет только одно из этих значений.

Подумайте об этом таким образом, когда вы определяете перечисление, вы в основном определяете другой способ присвоить значение int.

В примере, который вы указали, январь - это еще один способ сказать 0, feb - это еще один способ сказать 1 и т.д., пока декабрь не станет другим вариантом 11.

Ответ 5

Так как размер экземпляра типа - предположительно значения перечисления хранятся здесь (32-бит/4-байтовые) ints здесь.

Ответ 6

С моими устаревшими списками компилятора Borland С++ Builder могут быть 1,2 или 4 байта, хотя у него есть флаг, который вы можете перевернуть, чтобы заставить его использовать ints.

Я предполагаю, что это компилятор.

Ответ 7

Мне нравится объяснение от EdX (Microsoft: DEV210x Введение в С++) для аналогичной проблемы:

"Перечисление представляет собой буквальные значения дней как целые числа. Ссылаясь на таблицу числовых типов, вы видите, что int занимает 4 байта памяти. Для 7 дней x 4 байта для каждого из них потребуется 28 байт памяти, если все перечисление было но компилятор использует только один элемент перечисления, поэтому размер в памяти на самом деле составляет 4 байта."

Ответ 8

Перечисление почти целое. Чтобы упростить многое

enum yourenum { a, b, c };

почти как

#define a 0
#define b 1
#define c 2

Конечно, это не так. Я пытаюсь объяснить, что перечисление - это своего рода кодирование...