我应该相信C中的short通常是2个字节吗?
我有一个从 0 到 65535 循环的大数字(我选择 16 位只是为了有一个很好的截止点)。我正在递增一个 int,并且有一个 if 语句检查 int 是否为 65536。如果是,则将 int 设置为 0;如果是,则将 int 设置为 0。有点笨拙,但它有效。我知道只使用一个短整型并让它溢出会更有效,但我最初没有这样做,因为短整型不能保证为 2 个字节,这只是相当可能的。
这是在 Linux (ubuntu) 机器上运行的 C 代码。如果我要使用一个简短的程序,后来决定在另一个操作系统上运行这个程序(或者说,在 64 位机器上运行它,因为我现在正在 32 位机器上进行测试),是否有很好的机会我的 Short 仍然是 2 个字节?我可以轻松地在几台不同的机器上测试它,但是这里的一些人已经使用过很多计算机。有什么我应该提防的可怕陷阱吗?
I have a large number that loops from 0 to 65535 (I chose 16 bits simply to have a nice cutting off point). I'm incrementing an int, and there's an if statement that checks if the int is 65536. If it is, it sets the int to 0; a little kludgy, but it works. I know it would be much more efficient to just use a short int and let it overflow, but I initially didn't do that because a short is not guaranteed to be 2 bytes, it's just fairly likely.
This is C code running on a linux (ubuntu) machine. If I were to use a short and later decided to run this program on another OS (or say, run it on a 64-bit machine, since I'm testing on a 32-bit one now), is there a pretty good chance that my short will still be 2 bytes? I can easily test it on a few different machines, but some of the people here have worked with a LOT of computers. Is there a terrible pitfall I should be watching out for?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
无法保证 Short 是 16 位 - 例如,我使用了一个使用 32 位作为 Short 的编译器,因为这样做比使用 16 位效率更高。 (在 ARM 架构上)
但是,使用保证为 16 位的类型非常容易,并且您可以添加断言检查,一旦您尝试使用编译器,它就会向您发出警告这不是真的:
There's no guarantee that short is 16 bits - e.g. I've used a compiler that used 32 bits for a short because it was much more efficient to do this than use 16 bits. (On ARM architecture)
However, it's dead easy to use a type that is guaranteed to be 16 bits, and you can add an assertion check that will warn you as soon as you try to use a compiler where this isn't true:
不,你唯一可以假设的是,shorts 不大于 ints。
如果你想在 65535 之后回绕到 0 而不进行测试,你可以这样做:
No, the only thing you can assume is that shorts are not larger than ints.
If you want to wrap around to 0 after 65535 without a test, you can do it this way:
无论
sizeof
说它有多长,short
都会有多长。 C 标准规定short
必须至少为 16 位。它不需要小于int
,尽管通常是这样。A
short
is going to be however longsizeof
says it is. The C standard says that ashort
is required to be at least sixteen bits. It is not required to be smaller than anint
, though it often is.使用
sizeof(short)
查找平台MAX_SHORT
,然后迭代直至找到该平台。Find the platform
MAX_SHORT
by usingsizeof(short)
, and iterate until you hit that.如果您遵守 C99,那么您可以安全地假设:
等等,如标准的
5.2.4.2.1 整数类型的大小
中所见证的。当然,请注意,该标准明确指出,在所述部分中定义的最大值将等于或小于实现定义的大小。因此,空头或无符号空头的大小可能比我上面刚刚发布的要大。但是,它不会大于int
。If you obey C99, then you can assume safely that:
And so on, as witnessed in
5.2.4.2.1 Sizes of integer types <limits.h>
of the standard. Noting of course that the standard explicitly notes that the maximum values defined in said section, are to be the size of, or smaller than the implementation defined sizes. Therefore, the size of a short or unsigned short, may be larger than what I just posted above. However, it will not be larger than anint
.使用
uint16_t
,或者如果您坚持使用更大的类型,并在每次迭代时执行x %= 65536;
或x &= 65535
。我保证这比执行条件将其重置为零要快得多。Use
uint16_t
, or if you insist you can use a larger type and performx %= 65536;
orx &= 65535
on each iteration. I guarantee this is a lot faster than performing a conditional to reset it to zero.无法保证任何内置类型(例如
int
、char
等)的大小。 (例如,参见这个问题,这是关于C++的,但也是准确的据我所知,C 在这方面)如果您需要固定大小的整数类型,请包含 C99 的
并使用其中定义的固定宽度类型。There is no guarantee of the size of any of the built-in types like
int
,char
and the like. (See for example this question, which is about C++, but is also accurate for C as far as I know in this regard)If you need fixed-size integer types, include C99's
<stdint.h>
and use the fixed-width typesdefined there.Short 在绝大多数编译器上都是 16 位。如果合理的话,我可能会使用位字段来完成这项工作:
在
short
无论如何都是 16 位的典型情况下,这不会造成任何开销 - 在极少数情况下需要插入一些额外的代码来将值限制在正确的范围内,这会自动处理。唯一的缺点是结构体中只能有一个位字段。
编辑:不幸的是@earlz删除了他的答案,因为他的想法实际上比他想象的要好:如果C99实现有16位无符号整数类型,则需要提供
uint16_t
作为typedef那种类型。如果提供,此必须正好是 16 位宽。还有一个符合他的描述的uint_least16_t
(至少 16 位宽,但可能更多)。Short is 16 bits on the vast majority of compilers. If at all reasonable, I'd probably use a bit-field for the job:
In a typical case where
short
is 16 bits anyway, this won't impose any overhead -- and in the rare case that some extra code needs to be inserted to clamp the value to the right range, this handles that automatically.The only shortcoming is that you can only have a bit-field inside a
struct
.Edit: It's unfortunate that @earlz deleted his answer, because his idea was actually better than he thought: if a C99 implementation has a 16-bit unsigned integer type, it's required to provide
uint16_t
as a typedef for that type. If provided, this must be exactly 16 bits wide. There's also auint_least16_t
that fits his description (at least 16 bits wide, but could be more).