C++枚舉是帶符號還是無符號?通過擴展來驗證輸入是安全的,通過檢查它是< =您的最大值,並且忽略> =您的最小值(假設您從0開始並增加1)?C++枚舉是已簽名還是未簽名?
回答
您不應該依賴任何特定的表示形式。閱讀以下link。此外,該標準說,它是實現定義的哪種整數類型用作枚舉的基礎類型,除非它不應大於int,除非某些值不適合int或unsigned int。
簡而言之:你不能依賴一個有符號或無符號的枚舉。
[Michael Burr的回答](http:///stackoverflow.com/a/159308/594137)(其中引用標準)實際上意味着如果您將枚舉值定義爲負數,則可以依靠它進行簽名,因爲類型能夠「表示所有定義的枚舉器值在列舉中「。 – 2012-12-11 08:20:25
編譯器可以決定枚舉是否有符號或無符號。
驗證枚舉的另一種方法是使用枚舉本身作爲變量類型。例如:
enum Fruit
{
Apple = 0,
Banana,
Pineapple,
Orange,
Kumquat
};
enum Fruit fruitVariable = Banana; // Okay, Banana is a member of the Fruit enum
fruitVariable = 1; // Error, 1 is not a member of enum Fruit even though it has the same value as banana.
您不應該依賴它們被簽名或未簽名。如果你想使他們明確符號或無符號,你可以使用以下命令:
enum X : signed int { ... }; // signed enum
enum Y : unsigned int { ... }; // unsigned enum
在未來,隨着的C++ 0x,strongly typed enumerations將可用,並且有幾個優點(如類型安全,顯基礎類型或顯式範圍)。有了這個,你可以更好地確定這種類型的標誌。
讓我們來源。下面介紹一下C++標準03(ISO/IEC 14882:2003)文檔中7.2-5說(枚舉聲明):
基礎類型的枚舉 的是能夠代表 所有整型在枚舉中定義的枚舉值在 中定義。它是 實現定義其積分 類型用作底層類型 用於枚舉不同的是 基礎類型不得大於INT較大 除非 枚舉的值可以不適合在int或 無符號整型。
總之,您的編譯器可以選擇(顯然,如果您的某些ennumeration值有負數,它將被簽名)。
您不應該依賴它是有符號還是無符號。根據標準,它是實現定義的,其中整型被用作枚舉的基礎類型。但是在大多數實現中,它是一個有符號的整數。
在C++ 0X strongly typed enumerations將被添加,這將允許用戶指定一個枚舉的類型,例如:
enum X : signed int { ... }; // signed enum
enum Y : unsigned int { ... }; // unsigned enum
即使是現在,雖然,一些簡單的驗證可以通過使用作爲枚舉實現一個變量或參數類型是這樣的:
enum Fruit { Apple, Banana };
enum Fruit fruitVariable = Banana; // Okay, Banana is a member of the Fruit enum
fruitVariable = 1; // Error, 1 is not a member of enum Fruit
// even though it has the same value as banana.
除了別人已經說過符號/無符號,這裏就是標準說,大約一個枚舉類型的範圍:
7.2(6):「對於e(min)是最小枚舉數且e(max)最大的枚舉,枚舉值是範圍b(min)到b (max),其中b(min)和b(max)分別是可以存儲e(min)和e(max)的最小位域的最小值和最大值。它可以定義具有不受任何其枚舉的定義的值的枚舉「
因此,例如:。
enum { A = 1, B = 4};
定義枚舉類型,其中e(分鐘)爲1和e(最大)是4.如果底層類型是帶符號的int,那麼最小的所需位域有4位,如果實現中的整數是二進制補碼,那麼枚舉的有效範圍是-8到7.如果底層類型是無符號的,那麼它有3位,範圍是0到7.檢查你的編譯器文檔,如果你關心的話(例如,如果你想將枚舉類型之外的整型值轉換爲枚舉類型,那麼你需要知道該值是否在枚舉與否 - 如果不是,則生成的枚舉值未指定)。
無論這些值是否爲有效的函數輸入,可能與它們是否爲枚舉類型的有效值不同。你的檢查代碼可能擔心前者而不是後者,因此在這個例子中至少應該檢查> = A和< = B。
即使一些舊的答案有44個upvotes,我傾向於不同意他們所有人。總之,我不認爲我們應該關心enum的underlying type
。
首先,C++ 03枚舉類型是它自己的獨特類型,沒有符號概念。由於從C++ 03標準dcl.enum
7.2 Enumeration declarations
5 Each enumeration defines a type that is different from all other types....
所以,當我們在談論一個枚舉類型的標誌,說使用<
操作比較2個枚舉操作數的時候,我們實際上是在談論隱式枚舉類型轉換爲一些整體類型。 這是整體類型的標誌,重要的是。當將enum轉換爲整數類型時,此語句適用:
9 The value of an enumerator or an object of an enumeration type is converted to an integer by integral promotion (4.5).
而且,顯然,枚舉的基本類型與Integral Promotion無關。由於標準定義積分促進這樣的:
4.5 Integral promotions conv.prom
.. An rvalue of an enumeration type (7.2) can be converted to an rvalue of the first of the following types that can represent all the values of the enumeration
(i.e. the values in the range bmin to bmax as described in 7.2: int, unsigned int, long, or unsigned long.
所以,枚舉類型是否變爲signed int
或unsigned int
取決於signed int
是否可以包含所定義的枚舉,而不是基本的類型枚舉的所有的值。
見我相關的問題 Sign of C++ Enum Type Incorrect After Converting to Integral Type
- 1. 默認在iOS上是char簽名還是未簽名?
- 2. SAML響應和斷言是否已簽名/未簽名?
- 3. 查找證書是自簽名還是CA簽名
- 4. 檢查DLL是否已簽名C++
- 5. 簽名中的通用枚舉集
- 6. 要枚舉還是不枚舉?
- 7. 彙編代碼如何知道值是否已簽名或未簽名?
- 8. 未簽名簽名的jar
- 9. ClickOnce簽名 - 實際簽名是什麼?
- 10. 在c#接口實現枚舉和接口的方法簽名
- 11. C++複製構造函數的結構與枚舉的簽名
- 12. 爲了避免簽名/未簽名的比較,此C是否有意義?
- 13. c標準是否保證對簽名和未簽名的位模式解釋?
- 14. 重新簽名已簽名的應用
- 15. 未簽名與已簽名問題的比特NOT和比較
- 16. 已簽名和未簽名數字的比較
- 17. 已簽名未簽名Applets/Java Web Start,Socket連接?
- 18. OAuth2承載令牌是否已簽名?
- 19. 檢查文件是否已簽名
- 20. C#:反映枚舉名
- 21. C++枚舉名稱重疊
- 22. JSTL枚舉標籤
- 23. 簽名與未簽名的解釋
- 24. 在MySQL中籤名或未簽名
- 25. 未簽名/簽名不匹配
- 26. 如何簽名未簽名的IPA?
- 27. 簽名與未簽名的apk:classDeffNotFound
- 28. 映射枚舉表列其中DB值是枚舉領域,而不是標籤
- 29. 如何確定列是否未簽名?
- 30. C#中枚舉值名稱的別名
當我們使用一個背景,它要求它的標誌枚舉類型,我們實際上是在談論枚舉隱含轉換爲整型。 C++ 03標準說這是通過Integral Promotion完成的,與枚舉的基礎類型沒有任何關係。所以,我不明白爲什麼這裏的每個答案都提到標準沒有定義的底層類型?我在這裏描述了預期的行爲:http://stackoverflow.com/questions/24802322/sign-of-c-enum-type-incorrect-after-converting-to-integral-type – JavaMan 2014-07-17 12:10:30