在C中编程时,有时我的函数会收到数值,这些数值总是在0到4之间。一个32位的int
最多可以容纳2,147,483,647
。这是我没有使用的大量已分配内存。我知道的最低范围类型是char
(从0
到255
,对吧?)。使用它来保存低范围的数值是一种很好的做法吗?还有其他类型的我可以用吗?
如果它是一个标量函数参数,那么在传递给函数时,它在实践中肯定会被提升为至少32位类型,因此使用char
不会产生实际影响。我认为最好是为了可读性,int
是明显的"通用整数值"类型。
但是,如果您可能有一个很大的值数组,那么使用char
将使这些值能够更紧密地封装在内存中。如果真的内存紧张,你可以通过每个值只使用3或4位来将它们打包得更紧(3是最小值,4对齐得更好)。然而,这肯定会降低处理效率。
如果确实需要节省空间,可以使用位字段。但是请注意,访问数据可能需要更多的周期。(即使在现代硬件上访问字符也可能比原生整数大小需要更多的周期)
(编辑以给出示例:
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
。
对于精确控制,例如对于8位RGB像素的阵列,请使用uint8_t
。
你用来传递值的类型几乎无关紧要,你应该使用字节对齐的类型,char
对此很好(尽管它可能在几乎任何数字运算后都会上转换为int,所以int可能更容易)。
当您将数据存储在数组中时,应该考虑将数据打包为每个值2位。
char非常适合保存低范围值。它提供了效率,尤其是当您有大量值时。没有比这更小的了,因为char是一个完整的字节,除非您决定通过对位进行分区来将多个值存储在一个变量中。。。祝你好运
char
是一个窄整数类型。它可以是有符号的,也可以是无符号的。如果它是无符号的,则其范围至少为0到255;如果它是有符号的,那么它的范围至少是-127到+127。(是的,-127,而不是-128;对于有符号整数,标准不需要2的补码)。
顾名思义,类型char
主要用于容纳字符,但如果您愿意,您可以使用它来容纳小整数,特别是如果您知道它们只在0到127的范围内。可能最好使用unsigned char
或signed char
。
但在任何情况下,都不要指望与使用int
相比节省了大量空间。许多系统需要更多、更慢的代码来对char
值执行运算,而不是对int
值执行运算——无论如何,在大多数情况下,char
值都会隐式提升为int
。如果您需要存储一个由小整数值组成的大数组,那么某种字符类型的数组是有意义的。对于单个变量,使用char
而不是int
不会节省太多(如果有的话)。
您还应该记住,int
只保证至少是16位,而不是32位。(但现在,除非你在做嵌入式工作,否则在你可能使用的大多数系统上,它可能会是32位或更宽。)如果你需要特定的大小,<stdint.h>
中定义了许多类型(实际上是typedef,现有类型的别名)。
没有关于性能的C规范,所以任何答案充其量都是一个指导原则,并受性能评测的约束。
在通用中
1) 使用int
(或unsigned
)是最好的速度和最小的代码大小。
2) 使用最小整数类型char
、signed char
或unsigned char
),因为它们使用的内存空间最少。除了_Bool
可能不适用于0到4之外,没有更小的单一类型。如果有许多这样的小对象要打包在一起,位字段可能会更小。
当有许多复制(如大数组)时,或者当内存很高时,最好使用小整数类型/位字段。否则,代码的简单性应该占上风。
正如许多人提到的char
假设:
1) 它要么是有符号的,要么是无符号的。
2) 它的最小宽度为8位,最低范围为0到255或-127到127。(非-128)