enum在實(shí)際中應(yīng)用比較少,容易被忽略。其實(shí)enum 和 struct、class一樣,都是用戶自定義類型。既然是自定義類型,就可以有他的數(shù)據(jù)成員,還有成員函數(shù)!
For example:
enum e{a=1 , b=2 , c=4};
那么:
001: enum e e1; //enum e不是對(duì)象,它是類型,e1才是類型enum的對(duì)象!
002: e e1; //e是類型enum e的簡(jiǎn)寫(xiě)
003: e1 = 1; //錯(cuò)誤!考試大提示int不能賦值給一個(gè)用戶自定義類型
004: e1 = e(); //默認(rèn)構(gòu)造函數(shù)
005: e1 = e(1) //從int構(gòu)造enum e類型對(duì)象的構(gòu)造函數(shù)
006:e1 = a; //默認(rèn)調(diào)用“拷貝構(gòu)造函數(shù)”
enum的“取值范圍”和“內(nèi)存分配”
如何確定一個(gè)enum的取值范圍?
For example:
enum e1{ a=2, b=4 };
首先找到其絕對(duì)值的值,但為了容易理解,先不談負(fù)數(shù),也就是先找到其值,這里的值是4。
4 用二進(jìn)制表示就是 100,也就是需要3bits才能最小的容納下4這個(gè)值,而3bits所能表示的范圍是 0-7,于是e1的取值范圍為[0,7]。
現(xiàn)在來(lái)看看負(fù)數(shù),
enum e2{ a=-2, b=4 };
其中絕對(duì)值的是4,需要3bits才能容納下,但因?yàn)榭梢匀∝?fù)值(而元素b=4不是負(fù)值),也就是說(shuō)需要增加一個(gè)符號(hào)位,那么就需要4bits。
4bits的取值范圍是 1000 - 0111(二進(jìn)制表示),也就是 -8 到 7(十進(jìn)制表示)。
enum e3{ a=-4, b=2 } 就只需要3bits,取值范圍是[-4,3]。
簡(jiǎn)單的說(shuō)就是找到最少的能容納下所有的元素的位數(shù)
因?yàn)镃++標(biāo)準(zhǔn)規(guī)定超出枚舉類型表示范圍的賦值結(jié)果是undefined的,也就是說(shuō) e2 x = (e2)6 是肯定正確的,而 e2 y = (e2)8 行為是未定義的。
enum的內(nèi)存分配,如 e2 需要3bits,那么C++規(guī)定e2的尺寸只要容得下3bits就行,到底是取1個(gè)byte,還是4個(gè)byte,還是...,那由編譯器自己決定。但是,C++標(biāo)準(zhǔn)在這里有個(gè)限制:1<= sizeof(enmu)<=sizeof(int)。
以上內(nèi)容參考自Bjarne Stroustrup的 The C++ Programming Languane .
原文如下:
4.8 Enumerations [dcl.enum]
An enumeration is a type that can hold a set of values specified by the user. Once defined, an enumeration is used very much like an integer type.Named integer constants can be defined as members of an enumeration. For example,
enum { A S M , A U T O , B R E A K };
defines three integer constants, called enumerators, and assigns values to them. By default, enumerator values are assigned increasing from 0 , so A S M ==0 , A U T O ==1 , and B R E A K ==2 . An enumeration can be named. For example:
enum keyword {A S M ,A U T O ,B R E A K };
Each enumeration is a distinct type. The type of an enumerator is its enumeration. For example,
A U T O is of type keyword .
Declaring a variable k e y w o r d instead of plain i n t can give both the user and the compiler a hint as to the intended use. For example:
void f(keyword key )
{
switch (key) {
c a s e A S M :
/ / do something
b r e a k ;
c a s e B R E A K :
/ / do something
break ;
}
}
A compiler can issue a warning because only two out of three k e y w o r d values are handled.An enumerator can be initialized by a constantexpression(§C.5) of integral type (§4.1.1). The range of an enumeration holds all the enumeration’s enumerator values rounded up to the nearest larger binary power minus 1 . The range goes down to 0 if the smallest enumerator is nonnegative and to the nearest lesser negative binary power if the smallest enumerator is negative. This defines the smallest bitfield capable of holding the enumerator values. For example:
enum e1 { dark , light }; // range 0:1
enum e2 { a = 3 , b = 9 }; // range 0:15
enum e3 {min = 10 ,m a x = 1000000}; // range 1048576:1048575
A value of integral type may be explicitly converted to an enumeration type. The result of such a conversion is undefined unless the value is within the range of the enumeration. For example:
enum flag { x =1 , y =2 , z =4 , e =8 }; // range 0:15
flag f1 = 5 ; // type error: 5 is not of type flag
flag f2 = flag (5 ); // ok: flag(5) is of type flag and within the range of flag
flag f3 = flag (z |e ); // ok: flag(12) is of type flag and within the range of flag
flag f4 = flag (99); // undefined: 99 is not within the range of flag
The last assignment shows why there is no implicit conversion from an integer to an enumeration; most integer values do not have a representation in a particular enumeration. The notion of a range of values for an enumeration differs from the enumeration notion in the
Pascal family of languages. However, bitmanipulation examples that require values outside the set of enumerators to be welldefined
have a long history in C and C++.
The sizeof an enumeration is the s i z e o f some integral type that can hold its range and not larger than sizeof (i n t ), unless an enumerator cannot be represented as an i n t or as an u n s i g n e d i n t . Forexample, sizeof (e 1 ) could be 1 or maybe 4 but not 8 on a machine where s i z e o f (i n t )==4 .By default, enumerations are converted to integers for arithmetic operations (§6.2). An enumeration
is a userdefined type, so users can define their own operations, such as ++ and << for an enumeration(§11.2.3).
For example:
enum e{a=1 , b=2 , c=4};
那么:
001: enum e e1; //enum e不是對(duì)象,它是類型,e1才是類型enum的對(duì)象!
002: e e1; //e是類型enum e的簡(jiǎn)寫(xiě)
003: e1 = 1; //錯(cuò)誤!考試大提示int不能賦值給一個(gè)用戶自定義類型
004: e1 = e(); //默認(rèn)構(gòu)造函數(shù)
005: e1 = e(1) //從int構(gòu)造enum e類型對(duì)象的構(gòu)造函數(shù)
006:e1 = a; //默認(rèn)調(diào)用“拷貝構(gòu)造函數(shù)”
enum的“取值范圍”和“內(nèi)存分配”
如何確定一個(gè)enum的取值范圍?
For example:
enum e1{ a=2, b=4 };
首先找到其絕對(duì)值的值,但為了容易理解,先不談負(fù)數(shù),也就是先找到其值,這里的值是4。
4 用二進(jìn)制表示就是 100,也就是需要3bits才能最小的容納下4這個(gè)值,而3bits所能表示的范圍是 0-7,于是e1的取值范圍為[0,7]。
現(xiàn)在來(lái)看看負(fù)數(shù),
enum e2{ a=-2, b=4 };
其中絕對(duì)值的是4,需要3bits才能容納下,但因?yàn)榭梢匀∝?fù)值(而元素b=4不是負(fù)值),也就是說(shuō)需要增加一個(gè)符號(hào)位,那么就需要4bits。
4bits的取值范圍是 1000 - 0111(二進(jìn)制表示),也就是 -8 到 7(十進(jìn)制表示)。
enum e3{ a=-4, b=2 } 就只需要3bits,取值范圍是[-4,3]。
簡(jiǎn)單的說(shuō)就是找到最少的能容納下所有的元素的位數(shù)
因?yàn)镃++標(biāo)準(zhǔn)規(guī)定超出枚舉類型表示范圍的賦值結(jié)果是undefined的,也就是說(shuō) e2 x = (e2)6 是肯定正確的,而 e2 y = (e2)8 行為是未定義的。
enum的內(nèi)存分配,如 e2 需要3bits,那么C++規(guī)定e2的尺寸只要容得下3bits就行,到底是取1個(gè)byte,還是4個(gè)byte,還是...,那由編譯器自己決定。但是,C++標(biāo)準(zhǔn)在這里有個(gè)限制:1<= sizeof(enmu)<=sizeof(int)。
以上內(nèi)容參考自Bjarne Stroustrup的 The C++ Programming Languane .
原文如下:
4.8 Enumerations [dcl.enum]
An enumeration is a type that can hold a set of values specified by the user. Once defined, an enumeration is used very much like an integer type.Named integer constants can be defined as members of an enumeration. For example,
enum { A S M , A U T O , B R E A K };
defines three integer constants, called enumerators, and assigns values to them. By default, enumerator values are assigned increasing from 0 , so A S M ==0 , A U T O ==1 , and B R E A K ==2 . An enumeration can be named. For example:
enum keyword {A S M ,A U T O ,B R E A K };
Each enumeration is a distinct type. The type of an enumerator is its enumeration. For example,
A U T O is of type keyword .
Declaring a variable k e y w o r d instead of plain i n t can give both the user and the compiler a hint as to the intended use. For example:
void f(keyword key )
{
switch (key) {
c a s e A S M :
/ / do something
b r e a k ;
c a s e B R E A K :
/ / do something
break ;
}
}
A compiler can issue a warning because only two out of three k e y w o r d values are handled.An enumerator can be initialized by a constantexpression(§C.5) of integral type (§4.1.1). The range of an enumeration holds all the enumeration’s enumerator values rounded up to the nearest larger binary power minus 1 . The range goes down to 0 if the smallest enumerator is nonnegative and to the nearest lesser negative binary power if the smallest enumerator is negative. This defines the smallest bitfield capable of holding the enumerator values. For example:
enum e1 { dark , light }; // range 0:1
enum e2 { a = 3 , b = 9 }; // range 0:15
enum e3 {min = 10 ,m a x = 1000000}; // range 1048576:1048575
A value of integral type may be explicitly converted to an enumeration type. The result of such a conversion is undefined unless the value is within the range of the enumeration. For example:
enum flag { x =1 , y =2 , z =4 , e =8 }; // range 0:15
flag f1 = 5 ; // type error: 5 is not of type flag
flag f2 = flag (5 ); // ok: flag(5) is of type flag and within the range of flag
flag f3 = flag (z |e ); // ok: flag(12) is of type flag and within the range of flag
flag f4 = flag (99); // undefined: 99 is not within the range of flag
The last assignment shows why there is no implicit conversion from an integer to an enumeration; most integer values do not have a representation in a particular enumeration. The notion of a range of values for an enumeration differs from the enumeration notion in the
Pascal family of languages. However, bitmanipulation examples that require values outside the set of enumerators to be welldefined
have a long history in C and C++.
The sizeof an enumeration is the s i z e o f some integral type that can hold its range and not larger than sizeof (i n t ), unless an enumerator cannot be represented as an i n t or as an u n s i g n e d i n t . Forexample, sizeof (e 1 ) could be 1 or maybe 4 but not 8 on a machine where s i z e o f (i n t )==4 .By default, enumerations are converted to integers for arithmetic operations (§6.2). An enumeration
is a userdefined type, so users can define their own operations, such as ++ and << for an enumeration(§11.2.3).

