在使用C语言编程时,有时我的函数会接收0到4范围内的数字值。一个32位的int
可以容纳多达2,147,483,647
个值。这是我没有使用的大量分配的内存。我了解到的最低范围类型是char
(它可以保存从0
到255
的值,对吗?)。将低范围的数值存储在char
中是一个好的实践吗?还有其他的数据类型可以使用吗?
struct packed_values
{
unsigned int val1 : 3; /* ranges from 0-7 */
unsigned int val2 : 3;
unsigned int val3 : 3;
unsigned int val4 : 3;
unsigned int val5 : 3;
unsigned int val6 : 3;
unsigned int val7 : 3;
unsigned int val8 : 3;
unsigned int val9 : 3;
unsigned int val10 : 3;
unsigned int padding : 2; // make this be 32bits
};
packed_value myval;
myval.val1 = 5;
myval.val2 = 6;
myval.val3 = 7;
)
char
没有任何实际区别。我认为更重要的是可读性,而 int
是显而易见的“一般整数值”类型。char
将使这些值在内存中更紧密地打包。 如果您的内存非常紧张,可以仅使用3或4位每个值来更紧密地打包它们(3是最小值,4对齐更好)。 但这将肯定不够高效。char
的实现定义了有符号性。 - Deduplicator传递值时使用的类型几乎不重要,您应使用字节对齐类型,char
很合适(尽管在几乎任何数值操作之后它可能会被上转为int,因此int可能更容易)。
当您将其存储在数组中时,应考虑将数据打包为每个值2位。
char非常适合存储低范围的值。当你有大量值需要处理时,它提供了高效性。除非你决定通过分区位将多个值存储在单个变量中,否则没有更小的选择,因为char是一个完整的字节...祝好运!
char
,这可能需要花费循环周期,具体取决于架构。当然,在另一方面,如果您的程序受到内存速度的限制,那么这可能是值得的,因为您将更少使用缓存。 - Oliver Charlesworthchar
是一种窄整数类型。它可以是有符号的,也可以是无符号的。如果它是无符号的,它的范围至少为0到255;如果它是有符号的,它的范围至少为-127到+127。(是的,-127,而不是-128;标准并不要求有符号整数使用2的补码表示)。
类型char
,顾名思义,主要用于保存字符 -- 但如果你愿意,你也可以用它来保存小整数,特别是如果你知道它们只会在0到127的范围内。最好使用unsigned char
或signed char
。
但无论如何,不要指望与使用int
相比节省空间将是显著的。许多系统需要更多且更慢的代码来执行char
值上的算术运算,而不是执行int
值上的算术运算 -- 而且char
值在大多数情况下都会被隐式提升为int
。如果你需要存储大量的小整数值数组,使用某种字符类型的数组是有意义的。对于单个变量,与使用int
相比使用char
并不能节省多少空间,如果有的话。
int
只能保证至少有16位,而不是32位。(但现在,除非你在进行嵌入式工作,否则在大多数你可能使用的系统上,它很可能是32位或更宽的。)如果你需要特定大小,那么在 <stdint.h>
中定义了许多类型(实际上是 typedefs,即现有类型的别名)。关于C语言性能,没有明确的规范,所以任何答案最多只是一个指南,并且需要进行性能分析。
一般来说:
1)使用int
(或unsigned
)可以获得最佳速度和最小的代码大小。
2)使用最小的整数类型char
,signed char
或unsigned char
),因为它们占用最少的内存空间。除了可能不适用于0到4之外,没有比这更小的单一类型。如果您有许多这样的小对象要打包在一起,则位域可能更小。
当存在许多复制品(例如大型数组)或内存紧缺时,使用小整数类型/位域是一个好习惯。否则,代码的简洁性应优先考虑。
char
的假设:signed char
的最小范围是-127到+127,而 unsigned char
的范围是0到255,其中 char
必须匹配其中之一。CHAR_BIT
至少为8。 - chux - Reinstate Monica
char
有2 **CHAR_BIT
个值,最少256个,但它可以是signed
或unsigned
。因此,你的范围是错误的。不过对于这么低的无符号数来说,这并不重要。 - Deduplicator