【问题标题】:What is the actual use of "signed" keyword?“签名”关键字的实际用途是什么?
【发布时间】:2015-03-16 18:26:57
【问题描述】:

我知道无符号整数只是正数(和 0),与普通整数相比,它的值可以翻倍。有没有区别

int variable = 12;

还有:

signed int variable = 12;

何时以及为什么应该使用签名关键字?

【问题讨论】:

  • 几乎没有。这是暗示的。一种可能的例外是signed char;标准没有指定普通的char 是有符号还是无符号,所以如果出于某种原因你特别想要一个有符号的字符,你必须明确地说出来。
  • 我用它来表明号码是明确签名的,更多的是对读者的提醒。
  • @IgorTandetnik 甚至,charsigned charunsigned char三种不同的类型。对于所有其他整数类型,Xsigned X 是相同的。
  • 如果你写signed,那么你实际上可以放弃int。我不知道为什么要这样做,但它确实使signed 的存在不是多余的。

标签: c++


【解决方案1】:

int 的情况下,没有区别。它只对char 产生影响,因为

  1. 没有定义char是有符号还是无符号,并且
  2. 无论如何,charsigned charunsigned char 是三种不同的类型。

因此,如果您需要signed char(这可能很少见),您应该使用signed。除此之外,我想不出原因。

【讨论】:

  • 关于 char 的优点,老实说,编译器(尤其是 devstudio)允许您指定 char 的默认值
  • @hvanbrug:我不认为这是“值得注意的”。值得注意的是,GCC 有这样的选择。
  • 禁止编译器势利我刚刚提到 devstudio,因为我确信它确实如此。我不确定 gcc 所以我没有提到它。此外,GCC 并不比开发工作室更引人注目。当您考虑到 Windows 仍然拥有世界上最大的安装基础时,很容易看到开发工作室,因此 Visual C++ 拥有大量用户(GCC 也是如此)。也就是说,也许“包括”这个词比“显着”更能表达我的观点。
  • @hvanbrug:你是说 Visual Studio? (那是一个 IDE,而不是编译器。它的 C++ 编译器直到最近才特别关心标准。)还是 Anjuta DevStudio(另一个 IDE)?如果你真的指的是一个名为“devstudio”的编译器,那么恐怕它一点也不引人注目,因为基本上没有人听说过它。
  • @cHao:我有调用VC++ DevStudio的坏习惯。 +1 让我了解命名习惯。我确实知道 Visual Studio(很久以前被称为 Dev Studio)是 IDE,但我的坏习惯源于我只将它用于 VC++。你是正确的,VC++ 不以遵循标准而闻名,但这不是真正的问题。我只是指出,特定的编译器(被广泛使用)确实允许您指定字符默认为有符号还是无符号。
【解决方案2】:

就 int 而言,两者之间没有区别。如果您还声明 unsigned int,则可以包括用于格式化的单词 signed 以便它们更容易排列和阅读,但出于所有意图和目的,您不需要使用 signed 关键字。

【讨论】:

  • “您可能包含 ... 用于格式化”是向代码添加内容的一个非常糟糕的理由。首先,人们应该努力使他们的代码简单,避免不必要的混乱使代码更简单。
  • 感谢您的意见@cmaster。在我看来,格式是一个非常重要的话题。在我 30 多年的编程中,我看到了更多的错误,因为开发人员无法阅读代码并因此误解了其含义。程序员应该始终确保他们的代码可读,因为你可能不是唯一一个在看它的人,而且在几年内你可能也认不出自己的代码。
  • @cmaster 我认为您选择措辞是有理由拒绝投票的。再次阅读他的完整答案。
  • @ChristiaanWesterbeek,hvanbrug:我没有投反对票。这并不是一个完全错误的答案,因此不值得对恕我直言。我刚刚评论说,格式化是向程序添加任何内容的一个非常糟糕的理由。是的,格式很重要,但格式应该限制为空格。但比格式化更重要的是代码的良好、清晰和简单的结构,可以通过适当的格式化来展示。我从未添加过,并且(希望)永远不会将signed 添加到我的代码中以进行格式化。
  • 如果你正在处理一堆无符号变量,然后由于某种原因有一个有符号变量,我可以理解使用它。它更清楚地表明您意味着要对其进行签名,并且不会忘记那里的unsigned。但这不仅仅是格式化;代码的美感甚至不是一个因素。
【解决方案3】:

只有一个实例可能需要使用signed 关键字。 signed char 始终是不同于“普通”char 的类型,后者可能是有符号或无符号类型,具体取决于实现。

C++14 3.9.1/1 说:

char 对象是否可以保存负值是实现定义的。字符可以显式声明为unsignedsigned。普通的 charsigned charunsigned char 是三种不同的类型 [...]

在其他情况下,signed 是多余的。


在 C++14 之前(以及在 C 中),还有第二个实例:位域。例如,int x:2;(在类的声明中)是否与unsigned int x:2; 相同或与signed int x:2 相同是实现定义的。

C++11 9.6/3 说:

一个普通的(既没有显式签名也没有无符号)charshortintlonglong long 位域是有符号还是无符号是由实现定义的。

但是,从 C++14 开始,这已更改为 int x:2; 始终表示 signed intLink to discussion

【讨论】:

  • 请注意,在历史上,基于 PowerPC 的编译器默认将 char 视为 unsigned,而 x86 和 ARM 将其视为 signed
  • @fluffy:如果 char 是 8 位并且源字符集是 EBCDIC,那么在没有 signedunsigned 关键字的情况下,char 必须是无符号的,因为EBCDIC 用代码 0xF0 到 0xF9 表示数字 0-9,并且数字(以及 C 标准中定义的字母和任何标点符号)必须由正的 char 值表示。顺便说一句,在charint 大小相同的机器上,char 不能等同于unsigned char,因为int 必须能够保存char 的所有值,但unsigned char不能有填充。
  • 为什么最新绘制的 c++11,例如 N3690/N3797,没有声明:“它是实现定义的普通(既没有显式签名也没有无符号)char、short、int 、long 或 long long 位域是有符号的还是无符号的”。变了吗?
  • @pezy:只是因为我还没有最新标准的副本,尽管据我所知这些部分没有改变。
  • @CharlesBailey 第二个已经改变。鉴于template <typename T> struct S;S<int>S<signed int> 是同一类型。即使S 最终定义为template <typename T> struct S { T bitfield : 4; };,它们也必须保持相同的类型,因此实现定义的位域符号是行不通的。有一个提议将实现定义的签名限制为具有非依赖类型的位字段,但从未将其纳入标准。最后,简单地删除了将此类位字段视为无符号的权限。请参阅 CWG 问题 675 和 739。
【解决方案4】:

signed 是默认整数类型。所以不,你给出的例子没有区别。仅在char 的情况下有所不同。

来源:C++ Reference

【讨论】:

    猜你喜欢
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 2019-05-17
    • 2015-04-22
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多