Действительно ли sizeof (перечисление) == sizeof (интервал), всегда?

Используйте ClassLoader.getResource () для нахождения URL для текущего класса.

, Например:

package foo;

public class Test
{
    public static void main(String[] args)
    {
        ClassLoader loader = Test.class.getClassLoader();
        System.out.println(loader.getResource("foo/Test.class"));
    }
}

(Этот пример, взятый от подобный вопрос .)

Для нахождения каталога необходимо было бы тогда демонтировать URL вручную. Посмотрите учебное руководство JarClassLoader для формата URL банки.

58
задан Thom Wiggers 26 July 2015 в 12:40
поделиться

5 ответов

Это зависит от компилятора и может различаться в разных перечислениях. Ниже приводится семантика

enum X { A, B };

// A has type int
assert(sizeof(A) == sizeof(int));

// some integer type. Maybe even int. This is
// implementation defined. 
assert(sizeof(enum X) == sizeof(some_integer_type));

. Обратите внимание, что «некоторый целочисленный тип» в C99 может также включать расширенные целочисленные типы (которые, однако, реализация должна задокументировать, если она их предоставляет). Тип перечисления - это некоторый тип, который может хранить значение любого перечислителя (в данном случае A и B ).

Я не думаю, что использование перечислений влечет за собой какие-либо штрафы. Перечислители также являются интегральными константными выражениями (поэтому вы можете использовать их, например, для инициализации статических переменных или переменных области файлов), и я предпочитаю их макросам, когда это возможно.

Счетчикам не нужна оперативная память. Только когда вы создаете переменную перечислимого типа, вы можете использовать оперативную память. Подумайте о счетчиках как о константах времени компиляции.

Я бы просто использовал тип, который может хранить значения перечислителя (я должен заранее знать приблизительный диапазон значений), приводить к нему и отправлять его по сети. Предпочтительно тип должен быть фиксированной ширины, например int32_t , чтобы не возникало конфликтов, когда задействованы разные машины. Или я бы распечатал номер и отсканировал его с другой стороны, что избавит от некоторых из этих проблем.


Ответ на Edit

Что ж, компилятор не обязан использовать какой-либо размер. Легко увидеть, что знак значений имеет значение - беззнаковые типы могут значительно повысить производительность в некоторых вычислениях. Ниже показано поведение GCC 4.4.0 в моем ящике

int main(void) {
  enum X { A = 0 };
  enum X a; // X compatible with "unsigned int"
  unsigned int *p = &a;
}

. Но если вы назначите -1 , тогда GCC выбирает использовать int в качестве типа, который X совместим с

int main(void) {
  enum X { A = -1 };
  enum X a; // X compatible with "int"
  int *p = &a;
}

. Использование опции - short-enums GCC, что заставляет его использовать наименьший тип, по-прежнему соответствующий всем значениям.

int main() {
  enum X { A = 0 };
  enum X a; // X compatible with "unsigned char"
  unsigned char *p = &a;
}
34
ответ дан 7 November 2019 в 05:35
поделиться

C99, 6.7.2.2p4 говорит

Каждый перечислимый тип должен быть совместим с char, подписанный целочисленный тип или беззнаковый целочисленный тип. Выбор типа определяется реализацией, 108), но может представлять ценности всех членов перечисление. [...]

Сноска 108 добавляет

Реализация может отложить выбор целого числа type до тех пор, пока не будут просмотрены все константы перечисления.

Таким образом, он определяется реализацией, и sizeof (enum) может быть равно sizeof (char), то есть 1.

При выборе размера небольшого диапазона целых чисел, всегда есть штраф. Если вы сделаете его маленьким в памяти, вероятно, возникнет штраф обработки; если вы сделаете его больше, будет штраф места. Это компромисс между временем и пространством.

Коды ошибок обычно #define, потому что они должны быть расширяемыми: разные библиотеки могут добавлять новые коды ошибок. Вы не можете этого сделать с перечислениями.

19
ответ дан 7 November 2019 в 05:35
поделиться

Is the sizeof(enum) == sizeof(int), always

The ANSI C standard says:

Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined. (6.7.2.2 Enumerationspecifiers)

So I would take that to mean no.

If this is the case wont #DEFINE be better as it would save memory.

In what way would using defines save memory over using an enum? An enum is just a type that allows you to provide more information to the compiler. In the actual resulting executable, it's just turned in to an integer, just as the preprocessor converts a macro created with #define in to its value.

What is the usual practise. I if i have to transport these return types over a network and some processing has to be done at the other end

If you plan to transport values over a network and process them on the other end, you should define a protocol. Decide on the size in bits of each type, the endianess (in which order the bytes are) and make sure you adhere to that in both the client and the server code. Also don't just assume that because it happens to work, you've got it right. It just might be that the endianess, for example, on your chosen client and server platforms matches, but that might not always be the case.

13
ответ дан 7 November 2019 в 05:35
поделиться

В некоторых компиляторах размер перечисления зависит от того, сколько записей в нем. (менее 255 записей => байт, более 255 записей int) Но это зависит от компилятора и его настроек.

2
ответ дан 7 November 2019 в 05:35
поделиться

Нет.

Пример: Компилятор CodeSourcery

Когда вы определите перечисление, подобное этому:

enum MyEnum1 {
A=1,
B=2,
C=3
};
// will have the sizeof 1 (fits in a char)

enum MyEnum1 {
A=1,
B=2,
C=3,
D=400
};
// will have the sizeof 2 (doesn't fit in a char)

Подробности из их списка рассылки

4
ответ дан 7 November 2019 в 05:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: