如何在C ++中编写简短的文字?


120

一个非常基本的问题:如何short用C ++ 编写文字?

我知道以下几点:

  • 2 是一个 int
  • 2U 是一个 unsigned int
  • 2L 是一个 long
  • 2LL 是一个 long long
  • 2.0f 是一个 float
  • 2.0 是一个 double
  • '\2'是一个char

但是我怎么写short文字呢?我试过了,2S但是给出了编译器警告。


10
我猜短的文字不被支持,仅仅是因为这样的事实,即小于int的任何东西在评估过程中都会被“提升”为int。int具有最自然的大小。这在C ++中称为整数提升。
user534498'2

Answers:


82
((short)2)

是的,严格来说,这不是一个简短的字面量,更多的是强制转换,但是行为是相同的,我认为没有直接的方法。

那就是我一直在做的事情,因为我找不到任何东西。我猜想编译器会足够聪明,就好像它是一个短文字一样进行编译(即实际上不会分配一个int然后每次都强制转换它)。

下面说明了您应该为此担心多少:

a = 2L;
b = 2.0;
c = (short)2;
d = '\2';

编译->反汇编->

movl    $2, _a
movl    $2, _b
movl    $2, _c
movl    $2, _d

那就是我一直在做的事情,因为我找不到任何东西。我猜想编译器会足够聪明,就好像它是一个短文字一样进行编译(即实际上不会分配一个int然后每次都强制转换它)。
基普(Kip)

“ cast”实际上并没有做任何事情。当我们谈论C或C ++时,没有“ cast”汇编程序指令(.NET MSIL却是另一回事)。在金属上,它们全都是二进制数字
Isak Savo

9
上面的a,b,c和d有哪些类型?
Ates Goral,

2
@Ates Goral:所有整数。更改为short或char大概会更改整个指令movw或movb的指令。

2
这不是简短的文字。当您使用该强制转换并通过GCC和选项-Wconversion进行编译时,您仍然会得到该语句的编译器诊断信息short foo = 1; foo += (short)2;。但这不能因整数提升而被规避。
哈珀2014年

51

C ++ 11使您接近所需的内容。(搜索“用户定义的文字”以了解更多信息。)

#include <cstdint>

inline std::uint16_t operator "" _u(unsigned long long value)
{
    return static_cast<std::uint16_t>(value);
}

void func(std::uint32_t value); // 1
void func(std::uint16_t value); // 2

func(0x1234U); // calls 1
func(0x1234_u); // calls 2

// also
inline std::int16_t operator "" _s(unsigned long long value)
{
    return static_cast<std::int16_t>(value);
}

6
short物理上不能是std::uint任何东西,因为它是带符号的类型。而且,它不需要是16位或与...相同的类型,如果平台无法提供精确宽度的类型std::int16_t,则它本身甚至不需要存在于给定的实现中。这个答案的核心思想是好的,但是它被OP没问到的无关类型的莫名其妙的切线所贬低。
underscore_d

注意VS2015之前,Visual Studio中不支持用户定义的文字:msdn.microsoft.com/zh-cn/library/hh567368
v=vs.140).aspx

我不知道该爱还是恨它,但这是我正在开发的C ++中我的Strong整数类型系统的最后一部分,真是太神奇了。
Sahsahae

回显@underscore_d,我会投票赞成,但经过shortOP 的修改后。
v.oddou

28

甚至C99标准的编写者都被这一点所吸引。这是Danny Smith的公共领域stdint.h实现的摘录:

/* 7.18.4.1  Macros for minimum-width integer constants

    Accoding to Douglas Gwyn <gwyn@arl.mil>:
    "This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
    9899:1999 as initially published, the expansion was required
    to be an integer constant of precisely matching type, which
    is impossible to accomplish for the shorter types on most
    platforms, because C99 provides no standard way to designate
    an integer constant with width less than that of type int.
    TC1 changed this to require just an integer constant
    *expression* with *promoted* type."
*/

18

如果使用Microsoft Visual C ++,则每种整数类型都有字面后缀:

auto var1 = 10i8;  // char
auto var2 = 10ui8; // unsigned char

auto var3 = 10i16;  // short
auto var4 = 10ui16; // unsigned short

auto var5 = 10i32;  // int
auto var6 = 10ui32; // unsigned int

auto var7 = 10i64;  // long long
auto var8 = 10ui64; // unsigned long long

请注意,这些是非标准扩展不能移植。实际上,我什至在MSDN上都找不到这些后缀的任何信息。


1
追踪其中一个后缀时,您会看到eg ""ui8定义为'\000',本质上是'\0'
Nikita

10

您还可以使用伪构造函数语法。

short(2)

我发现它比强制转换更具可读性。


4
它被称为“功能转换表达式”。我也非常喜欢它,尤其是在使用Windows API编程时。
klaus triendl'2

6

据我所知,您没有,没有这样的后缀。但是,如果整数文字太大而无法放入要存储的任何变量,大多数编译器都会发出警告。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.