簡體   English   中英

如何檢查普通字符是否已簽名?

[英]How to check if plain chars are signed or unsigned?

顯然,默認情況下有可能將純char簽名或不簽名。 Stroustrup寫道:

由純字符定義為帶符號還是無符號是由實現定義的。 這打開了一些令人討厭的驚喜和實現依賴性的可能性。

如何檢查我的字符是否已簽名? 我可能想稍后將它們轉換為int ,並且我不希望它們為負數。 我應該始終明確使用unsigned char嗎?

從標題<limits>

std::numeric_limits<char>::is_signed

http://en.cppreference.com/w/cpp/types/numeric_limits/is_signed

一些替代方案:

const bool char_is_signed = (char)-1 < 0;

#include <climits>
const bool char_is_signed = CHAR_MIN < 0;

是的,有些系統確實將普通char無符號類型。 我遇到的示例:Cray T90,Cray SV1,Cray T3E,SGI MIPS IRIX,IBM PowerPC AIX。 並且幾乎所有使用EBCDIC的系統都必須使普通char無符號,以便所有基本字符都具有非負值。 (有些編譯器可以選擇控制char的符號,例如gcc的-fsigned-char-funsigned-char 。)

但是,正如本傑明·林德利Benjamin Lindley)的答案所建議的std::numeric_limits<char>::is_signedstd::numeric_limits<char>::is_signed可能更清楚地表達了意圖。

(另一方面,我建議的方法也可以應用於C。)

始終使用unsigned char可能會給您帶來一些有趣的驚喜,因為大多數C樣式函數(如printffopen )將使用char ,而不是unsigned char

編輯:具有C樣式功能的“有趣”示例:

const unsigned char *cmd = "grep -r blah *.txt";
FILE *pf = popen(cmd, "r"); 

將給出錯誤(實際上,對於*cmd =行,我得到了一個錯誤;對於popen行,我得到了一個錯誤)。 使用const char *cmd = ...可以正常工作。 我之所以選擇popen是因為它不是用標准的C ++功能替代的函數-顯然, printffopen可以很容易地用iostreamfstream類型的功能替代,該功能通常具有采用unsigned charchar替代方法。

但是,如果對大於127的字符使用>< ,則將需要使用unsigned char (或其他解決方案,例如強制轉換為int並屏蔽低8位)。 最好避免直接比較(特別是在涉及非ASCII字符時-總是很混亂,因為取決於語言環境,字符編碼等,通常會有幾種變體)。 但是,比較平等應該起作用。

是的,如果要使用char類型並且始終希望將其取消簽名,請使用unsigned char 請注意,與其他基本整數類型, unsigned char是從不同類型的char -即使是在系統中char是無符號。 另外,從charint轉換應該是無損的,因此,如果結果不正確,則源char值也可能不正確。

測試char是否為無符號的最干凈的方法取決於是否需要將其用作預處理程序測試以及所針對的C ++版本。

要使用預處理程序測試有條件地編譯代碼, CHAR_MIN的值應該起作用:

#include <climits>

#if (CHAR_MIN==0)
// code that relies on char being unsigned
#endif

在C ++ 17中,我將使用std::is_signed_vstd::is_unsigned_v

#include <type_traits>

static_assert(std::is_unsigned_v<char>);
// code that relies on char being unsigned

如果您是針對C ++ 11或C ++ 14編寫的,則需要稍微冗長的std::is_signedstd::is_unsigned

#include <type_traits>

static_assert(std::is_unsigned<char>::value, "char is signed");
// code that relies on char being unsigned

對於C ++的所有版本,@ benjamin-lindley的解決方案都是不錯的選擇。

您可以使用預處理器命令:

 #define is_type_signed(my_type) (((my_type)-1) < 0)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM