4

我有一个从 0 到 65535 循环的大量数字(我选择 16 位只是为了有一个很好的截止点)。我正在递增一个 int,并且有一个 if 语句检查 int 是否为 65536。如果是,它将 int 设置为 0;如果是,则将 int 设置为 0。有点笨拙,但它有效。我知道只使用一个 short int 并让它溢出会更有效,但我最初没有这样做,因为不能保证一个 short 是 2 个字节,这很有可能。

这是在 linux (ubuntu) 机器上运行的 C 代码。如果我要使用一个简短的,后来决定在另一个操作系统上运行这个程序(或者说,在 64 位机器上运行它,因为我现在正在 32 位机器上进行测试),是否有一个很好的机会我的short仍然是2个字节?我可以很容易地在几台不同的机器上测试它,但是这里的一些人使用过很多电脑。有什么可怕的陷阱我应该提防吗?

4

8 回答 8

7

无法保证任何内置类型的大小,例如int,char等。(例如,参见这个关于 C++ 的问题,但据我在这方面的了解,对于 C 也是准确的)

如果您需要固定大小的整数类型,请包括 C99<stdint.h>并使用那里定义的固定宽度类型。

于 2011-02-13T19:08:19.787 回答
5

在绝大多数编译器上,Short 是 16 位。如果完全合理的话,我可能会使用一个位域来完成这项工作:

struct { 
    unsigned short my_number : 16;
};

在无论如何都是 16 位的典型情况下short,这不会产生任何开销——在极少数情况下,需要插入一些额外的代码来将值限制在正确的范围内,这会自动处理。

唯一的缺点是您只能在struct.

编辑:很遗憾@earlz 删除了他的答案,因为他的想法实际上比他想象的要好:如果 C99 实现具有 16 位无符号整数类型,则需要提供uint16_t该类型的 typedef。如果提供,它必须正好是 16 位宽。还有一个uint_least16_t符合他的描述(至少 16 位宽,但可能更多)。

于 2011-02-13T19:10:16.433 回答
3

不,您唯一可以假设的是短裤不大于整数。

如果你想在 65535 之后不经过测试就回绕到 0,你可以这样做:

unsigned int i;
...

i = (i + 1) & 0xffff;
于 2011-02-13T19:07:15.690 回答
3

不能保证 short 是 16 位 - 例如,我使用了一个使用 32 位作为 short 的编译器,因为这样做比使用 16 位更有效。(在 ARM 架构上)

但是,使用保证为16 位的类型非常容易,并且您可以添加一个断言检查,当您尝试使用不正确的编译器时会立即警告您:

ASSERT(sizeof(short) == 2);
于 2011-02-13T19:59:02.237 回答
2

Ashort将是多么长sizeof。C 标准规定 ashort必须至少为 16 位。它不需要小于 a int,但通常是这样。

于 2011-02-13T19:10:29.273 回答
0

MAX_SHORT使用找到平台sizeof(short),然后迭代直到找到它。

于 2011-02-13T19:09:19.030 回答
0

如果您遵守 C99,那么您可以安全地假设:

a `short int` may have a minimum value of `-32767`
                         maximum value of `+32767`
an `unsigned short int` may have a minimum value of `0`
                                   maximum value of `65535`

依此类推,正如5.2.4.2.1 Sizes of integer types <limits.h>标准中所见证的那样。当然要注意标准明确指出,在所述部分中定义的最大值将是实现定义的大小或小于实现定义的大小。因此,short 或 unsigned short 的大小可能比我刚刚在上面发布的要大。但是,它不会大于int.

于 2011-02-13T19:10:57.347 回答
-1

使用uint16_t, 或者如果您坚持可以使用更大的类型并在每次迭代中执行x %= 65536;or 。x &= 65535我保证这比执行条件将其重置为零要快得多。

于 2011-02-13T19:27:23.893 回答