使用短片为什么不好

Ede*_*nia 9 c c++ variables int types

即使在脚本中,开发人员也保证变量永远不会超过一个字节,有时甚至超过两个字节,这是很常见的.许多人决定使用int每种可能变量的类型来表示0-1范围内的数字.

为什么使用charshort反而伤害这么多?

我想我听到有人说int是"更标准"类型的..类型.这是什么意思.我的问题是数据类型int是否具有任何明确的优势short(或其他较小的数据类型),因为人们过去几乎总是诉诸于哪些优势int

Ste*_*mit 16

作为一般规则,C中的大多数算术是使用类型int(即普通int,不是shortlong)来执行的.这是因为(a)C的定义是这样说的,这与(b)许多处理器(至少是C的设计者想到的)更喜欢工作的方式有关.

因此,如果您尝试使用shortints 来"节省空间" ,那么您可以编写类似的内容

short a = 1, b = 2;
short c = a + b;
Run Code Online (Sandbox Code Playgroud)

编译器发出的代码转换a,从shortint,转换b来自shortint,做加法,并转换总和回short.您可能已经保存的空间一点点的存储空间a,b以及c,但你的代码很可能要大些(慢).

如果你反而写

int a = 1, b = 2;
int c = a + b;
Run Code Online (Sandbox Code Playgroud)

你花一点点更多的存储空间a,b以及c,但代码可能是更小更快速.

这在某种程度上是一个过于简单的论点,但是你的观察背后是类型的使用short是罕见的,int通常建议使用plain .基本上,因为它是机器的"自然"大小,所以它被认为是最简单的算术类型,没有额外的转换和来自不太自然的类型.它有点像"在罗马时,像罗马人那样做"的论点,但它通常使用普通的int优势.

如果你有很多不那么大的整数要存储,另一方面(大量的整数,或者包含不那么大整数的大量结构),数据的存储节省可能很大,并且值得与代码大小(相对较小的)增加以及潜在的速度增加进行交易.

另请参阅此前的SO问题此C FAQ列表条目.


附录:与任何优化问题一样,如果您真的关心数据空间使用,代码空间使用和代码速度,您将需要使用您的确切机器和处理器进行仔细测量.毕竟,您的处理器可能最终不需要任何"额外的转换指令"来转换为较小的类型,因此使用它们可能不会有太大的劣势.但与此同时,您可以确认,对于孤立变量,使用它们可能也不会产生任何可衡量的优势.


附录2.这是一个数据点.我试验了代码

extern short a, b, c;

void f()
{
    c = a + b;
}
Run Code Online (Sandbox Code Playgroud)

我编译了两个编译器,gcc和clang(在Mac上编译Intel处理器).后来我改变shortint并重新编译.在int-使用代码为下GCC较小7个字节,并且在铛小10个字节.检查汇编语言输出表明不同之处在于截断结果以便将其存储c; 取shortint不是似乎没有改变指令计数.

然而,我接着尝试调用两个不同的版本,并发现即使在10000000000次调用之后,它在运行时间上几乎没有差别.因此,"使用short可能使代码更大"的答案部分得到了确认,但也许并非"并且也使其变慢".

  • 嗯?你没有资格说过,"compller必须发出代码"和"你的代码更大更慢".三十年来我没有认真对待过这个问题,但事实并非如此,现在情况并非如此. (2认同)

Lun*_*din 5

这里有几个问题。

  • 首先,该char类型完全不适合保存整数值。它只能用于保存字符。这是因为它具有实现定义的符号,char实际上是与signed charand分开的不同类型unsigned char。请参阅默认情况下 char 是有符号还是无符号?

  • 然而,如果可能的话,应该避免使用小整数类型(例如char和 )的主要原因是隐式类型提升。short这些类型会受到整数提升的影响,这反过来又可能导致危险的事情,例如符号的无声改变。有关详细信息, 请参阅隐式类型提升规则。

    因此,一些编码标准实际上完全禁止使用较小的整数类型。尽管要使这样的规则可行,您需要 32 位或更大的 CPU。因此,如果要考虑各种微控制器,这并不是一个很好的通用解决方案。

    另请注意,以这种方式对内存进行微观管理主要与嵌入式系统编程相关。如果您正在编写 PC 程序,使用较小的类型来节省内存可能是一种“过早的优化”。

  • C 的默认“原始数据类型”,包括charshort、 、int总体来说是相当不可移植的。当代码移植时,它们的大小可能会发生变化,这反过来又会给它们带来不确定的行为。此外,C 允许这些类型使用各种晦涩和奇异的符号格式,例如补码、符号和幅度、填充位等。

    坚固、可移植、高质量的代码根本不使用这些类型,而是使用stdint.h. 作为奖励,该库只允许正常的行业标准二进制补码。

  • 出于上述所有原因,使用较小的整数类型来节省空间并不是一个好主意。再次,stdint.h是优选的。如果您需要可移植地节省内存的通用类型,除非节省内存意味着降低执行速度,否则请使用int_fast8_t和 类似的类型。这些将是 8 位,除非使用更大的类型意味着执行速度更快。