根据大小选择数据类型

时间:2016-01-15 00:02:40

标签: c++

我想知道你们所有的(有经验的程序员)程序在C ++中,你们如何选择原始数据类型?例如,如果你有一个你知道迭代4次的for循环,你使用unsigned short int还是int8_t?为什么?或者为什么不呢?这是关于优化内存的吗?

有很多不同大小的int类型,我认为必须有一个原因。

3 个答案:

答案 0 :(得分:4)

当不需要专门的尺寸时,我使用原生字大小。例如,我对所有计数循环使用unsigned int

访问硬件时,我使用特定大小的整数,例如uint16_tuint8_t

对于具有大量内存和速度的现代台式计算机,不需要过早优化,例如担心可变大小。

在嵌入式系统中,特别是在内存受限的情况下,可变大小可能会有所不同。

最佳做法是使程序正常运行,然后根据需要应用优化。一个非常小的错误程序不如大型正确和强大的程序有用。速度相同。

原理

处理器在使用原生单词大小时非常有效。字大小因处理器而异。一些处理器是8位字大小,大约16位,其他32位(是的,有大小和更大)。

不是处理器字(寄存器)大小的数据可能会导致处理器的额外工作。例如,具有16位字长的处理器需要进行两次存储器提取以构建32位数量。对于16位数量,32位处理器将获取32位,而不是移位位或屏蔽位以使16位数量进入处理器寄存器中的正确位置。

硬件寄存器有不同的尺寸。当存在8位宽的硬件寄存器时,不希望将32位写入寄存器,这就是为什么存在8位宽数据类型而不是32位数据类型的原因。

答案 1 :(得分:3)

通常情况下,如果没有特殊原因,我会使用int对所有带循环计数器的迭代循环。当然,当迭代容器时,我使用新的样式循环:

std::string str = "Hello, World!";
for(auto c: str)
    std::cout << c;

(一种相当愚蠢的打印方式&#34;你好,世界!&#34;)

使用int的原因是它意味着最好的&#34;该特定体系结构的速度整数大小。使用int8_t或其他类型可能并不慢,但它也不能保证编译器不必执行额外的步骤来扩展&#34;进行比较时int8_t,以便:

 for(int8_t i = 0; i < 4; i++)
   ...

基本上变成了:

 for(int8_t i = 0; (int)i < 4; i++)
  ...

因此,代码越来越大。

在除了非常微小的处理器之外的所有处理器[或计数器本身未被使用的非常大的循环]中,循环变量i无论如何都将在寄存器中,并且99%的时间,你可以在寄存器中有效地存储多个东西[没有惩罚,即使例如x86允许alah作为由64位{{1}形成的两个8位寄存器它是一个寄存器,处理器必须处理&#34;部分寄存器更新&#34;这对于处理器而言是复杂的,并且在x86处理器的许多变体上都会降低代码的速度,编译器确实不太可能使用寄存器的其他部分来做任何有用的事情。

答案 2 :(得分:1)

在比较时(如while(i < 4)的情况),最佳选择是当比较的值具有相同的类型时。 Integer literal 4的类型为int,因此i应为相同类型(或更大)以避免溢出。 valuess应该具有相同的签名也很重要。如果由于某种原因他们有不同的签名,你应该手动将它们转换为适当的类型,但要确保转换是安全的。一个典型的例子:

size_t max = 4096;
ssize_t n = read(fd, buf, max);
if(n < 0) {
    handle_error(errno);
    return;
}
assert(n >= 0); // Now we are sure we can cast away signedness safely
if((size_t)n < max) {
    // ...
}

只有当大小对某个问题至关重要时,才应使用固定大小的整数类型(如uint8_tuint32_t等)。例如,将整数序列化为可在另一台计算机上读取的文件时。

在选择原始类型时,我通常不会担心性能,因为鲁棒性对我来说更重要。