代码之家  ›  专栏  ›  技术社区  ›  me_and

C中小整数使用char的优缺点

  •  5
  • me_and  · 技术社区  · 15 年前

    使用有什么缺点吗 char 对于C中的小整数?除了占用/记忆方面的优势外,还有其他优势吗?

    特别是,处理器是否可能处理 烧焦 比在( long / short ) int ?

    我知道这将是特定于处理器/系统/编译器的,但我希望在一般情况下得到答案,或者至少在32位Windows和Solaris的一般情况下得到答案,这是我目前正在研究的系统。我还假设已经处理了溢出/包围问题。

    更新:Visual Studio 6.0实际上没有 stdint.h 按照克里斯托夫的建议。在Windows上进行一点基准测试(与6.0、调试构建、32位相比),并使用少量的堆栈循环给出 int 长的 提供类似的性能,速度大约是 烧焦 . 在Linux上用gcc类似的pegs运行相同的测试 int 长的 相似,都比 烧焦 尽管差异不那么明显。

    作为旁注,我没有花太多时间去寻找,但是 the first implementation of stdint.h for VS 6.0 I found (通过 Wikipedia 定义 uint_fast8_t 作为 unsigned char 尽管这在我的测试中看起来慢了些。因此,这个故事的寓意,正如克里斯托夫正确的建议:永远是基准!

    6 回复  |  直到 15 年前
        1
  •  12
  •   Christoph    15 年前

    C99增加了所谓的“最快”最小宽度整数类型来解决这个问题。对于您感兴趣的范围,类型将是 int_fast8_t uint_fast8_t ,可以在 stdint.h .

    请记住,可能没有性能提升(内存消耗的增加甚至会使事情变慢);和往常一样,基准测试!不要过早地或仅仅根据可能存在缺陷的假设来优化应该工作的内容。

        2
  •  6
  •   caf    15 年前

    好吧,第一个问题是,C标准没有定义 char 是有符号的还是无符号的-所以您可以移植依赖的唯一范围是0到127。

    除此之外,一般来说 int 应该是与体系结构的本机字大小相对应的类型(当然,这不是由任何东西强制实现的)。这往往是具有最佳算术性能的类型,但这就是您能说的全部内容。

    注意,操作数小于 int 扩大到 int unsigned int 无论如何,在表达式计算期间。

        3
  •  3
  •   Carl Smotricz    15 年前

    我能想到的另一个缺点是(据我所知)“现代”处理器用“全”整数(通常是32位)来做所有的数学运算。所以处理一个 char 通常意味着从内存中取出一个字节,在传输到寄存器时用0填充,然后用它做一些事情,然后只将结果的最低有效位压缩回内存。尤其是如果 烧焦 不是在一个方便的边界上对齐,这个内存访问需要更多的工作来完成。

    使用 烧焦 对于 int 只有当你 许多 你需要节省空间。

        4
  •  3
  •   anon    15 年前

    字符上的算术几乎肯定会使用与整数上的算术相同的寄存器来执行。例如:

    char c1 = 1;
    char c2 = c1 + 2;
    

    加法用vc++编译为以下内容:

    00401030   movsx       eax,byte ptr [ebp-4]
    00401034   add         eax,2
    00401037   mov         byte ptr [ebp-0Ch],al
    

    其中eax是32位寄存器。

    因此,在算术性能方面,使用chars比ints没有优势。

        5
  •  2
  •   moonshadow    15 年前

    在内部,处理器通常对机器字执行算术运算。这意味着,当对其他类型进行计算时,尽管计算本身需要相同的时间长度,但根据可用的指令集,可能需要做额外的工作来读取输入并将计算结果强制转换为目标类型(例如,符号扩展/零填充、移位/屏蔽以避免未对齐的MEM)。ORY通道等)。

    这就是C定义类型和操作的原因-大小 int 不受标准的强制,允许编译器作者使其与机器字相对应,并且定义表达式计算以将较小的整数类型提升为 int ,大大减少了必须将结果强制到某个目标类型的点的数量。

    使用的正当理由 char 对于存储整数值来说,当空间真的很重要(不像您想象的那样频繁)时,以及在描述一些外部数据格式/协议时,您正在将数据编组到/从中。预期用途 烧焦 要引起性能的轻微损失,特别是在硬件上,如cellsspu,其中只有机器字大小的内存访问可用,因此访问内存中的字符需要进行几次移位和屏蔽。

        6
  •  0
  •   T.J. Crowder    15 年前

    我将看到的主要问题是,您的代码使用的类型对于表示其他内容的值来说意味着一件事——例如,存在语义问题,这可能是维护问题。如果你这么做了,我可能会建议你把它改成typedefing:

    typedef char REALLYSHORT;
    

    这样,a)你做的事情更清楚,b)如果你遇到麻烦,你可以很容易地改变它(例如,只有一个地方)。

    你有没有 很好的理由 不使用 int ?