为什么在所有数据类型中,int 取决于操作系统或编译器
Why out of all data types int is OS or compiler dependant
我想知道,在C/C++中通常可用的所有数据类型中,为什么其中一些依赖于操作系统或编译器?
这有什么合乎逻辑的原因,还是只是设计使然?
是的。因为 C/C++ 在许多不同的机器架构上运行。
因此,int
被定义为机器的"自然大小" - 这允许编译器生成在该机器上运行良好的代码。
在现代机器上,这通常是 32 位或 64 位。在较旧的机器上,它是 16 位。 在某些机器上(您可以查找),它是 24 或 36 位。
C 标准在这些类型的定义中非常谨慎。 它需要一些东西(如"long
不能小于int
"),而将其他事情留给实现。
int
在这方面并不特别。每个整型数据类型都依赖于编译器。每种类型都有最小范围,并且类型具有不递减大小的顺序:char
->short
->int
->long
->long long
。一个符合标准的实现可以使所有这些实现都为 64 位宽。
int
类型应该是您正在使用的体系结构的自然大小。因此,在 32 位计算机上,int
通常为 32 位。在 64 位上,int
通常为 64 位。(64 位计算机上的 32 位操作系统可能是 32 位int
。
其原因是效率。通常,最大可表示数量实际上并不重要,您只想使用最有效的类型。最常见的示例是循环。
for(int i=0; i< NUM_ITER; ++i) {
// ...
}
对于大多数循环,迭代次数通常不会那么大。但是,即使您知道不需要循环超过 255 次,使用unsigned char
作为循环计数器实际上在寄存器使用等方面可能效率较低。
编辑:这是另一个例子。假设字大小为 4 个字节,并且您有一些函数,其开头如下所示:
void foo() {
static char x;
static char y;
// ...
}
一个天真的编译可能会把变量x
放在某个地址,比如0x0F00
。然后变量y
将由朴素编译放置在地址0x0F01
x
因为只需要 1 个字节。但是在许多架构上,内存访问针对 4 字节对齐的地址进行了优化,因此访问y
可能实现为对/从0x0F00
的 4 字节访问,然后丢弃其中的 3 个字节。这在带宽消耗方面显然是浪费,但更大的问题是必须进行额外的处理才能打包/解压缩 4 字节字中的字节。
OTOH,如果x
和y
大于 1 个字节是可以的(即,如果您不依赖算法中溢出的变量),那么您最好将它们声明为int
.即使您的值为 <256,您每次最终也会访问 4 个字节,这是浪费,但不会比前一种情况更浪费。但是,您不再需要打包或解压缩变量,因此消除了一点开销。
关键是,如果您只是简单地将x
和y
声明为int
,则不必担心 32 位体系结构与 64 位体系结构的对齐。无论哪种方式,编译器都会做正确的事情。
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 没有显式声明的int[]中的foreach
- 在c++中访问int到类对象的映射时出错
- 为什么我无法更改"set<set>"循环中的值<int>
- 长 长 int 不要 长 int 好
- C++程序在循环后给出奇怪的int值
- 如何计算数据类型的范围,例如int
- 为什么在所有数据类型中,int 取决于操作系统或编译器
- 长 int* 到 np_intp* 取决于平台的转换