繁体   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