今天我了解到如果你声明一个char变量(1个字节),汇编器实际上在内存中使用4个字节,这样边界就是字大小的倍数。
如果char变量无论如何都使用4个字节,那么将它声明为char是什么意思?为什么不将它声明为int?他们不要使用相同数量的内存吗?
答案 0 :(得分:4)
当您使用汇编语言编写并为字符声明空间时,汇编程序会为一个字符分配空间而不再分配空间。 (我写的是关于常见的汇编程序。)如果要使用汇编语言对齐对象,则必须包含汇编程序指令。
当您使用C编写,并且编译器将其转换为程序集和/或机器代码时,可以填充字符的空间。通常这不是因为角色对象的对齐优势,而是因为你在程序中声明了几件事。例如,考虑一下声明:
时会发生什么char a;
char b;
int i;
char c;
double d;
天真的编译器可能会这样做:
a
分配一个字节,恰好与16个字节的倍数对齐。b
分配下一个字节。int i
。在此计算机上,int
个对象必须与四个字节的倍数对齐,否则尝试访问它们的程序将崩溃。因此编译器会跳过两个字节,然后为i
留出四个字节。c
分配下一个字节。d
留出八个字节。这使得d
与八个字节的倍数对齐,这对这个假想的机器是有益的。因此,即使使用简单的编译器,字符对象也不需要四个完整的字节。它可以与邻居角色对象或其他不需要更大对齐的对象共享。但是会有一些浪费的空间。
更智能的编译器将执行此操作:
d
预留八个字节。i
留出四个字节。请注意,i
与四个字节的倍数对齐,因为它跟随d
,这是一个8字节的对象,与8个字节的倍数对齐。a
,b
和c
分别留出一个字节。这种重新排序可以避免浪费空间,任何体面的编译器都会将它用于可以自由排列的内存(例如堆栈上的自动对象或全局内存中的静态对象)。
在结构中声明成员时,编译器需要使用声明成员的顺序,因此无法执行此重新排序以节省空间。在这种情况下,声明字符对象和其他对象的混合可能会浪费空间。
答案 1 :(得分:3)
问:程序是否为您声明的每个“char”分配了四个字节?
答:不 - 绝对没有;)
问:如果你分配一个字节,程序可能会“填充”额外的字节吗?
<答>答:是的 - 绝对是的。问题是“对齐”。某些计算机体系结构必须访问特定偏移量的数据值:16位,32位等。如果其他体系结构执行更好,如果它们总是访问一个字节相对于抵消。因此“填充”:
答案 2 :(得分:0)
声明单个char
变量确实没有任何意义。
但是,有一个很好的理由需要一个char
- 数组,其中一个int
- 数组实际上不会这样做!
(尝试使用整数填充数据结构......)
答案 3 :(得分:0)
其他人在很大程度上回答了这个问题。假设char是一个字节,声明一个char意味着它总是填充到一个对齐?不,有些编译器在默认情况下做了一些,而且很多你可以在某处使用某种命令来改变默认值。这是否意味着你不应该使用char?这取决于,首先填充不总是发生,所以几个浪费的字节不总是发生。您正在使用编译器以高级语言进行编程,因此如果您认为整个二进制文件中只有3个浪费的字节,那么请再想一想。根据使用字符的体系结构可以节省一些成本,例如加载即时节点可以在某些体系结构上节省三个字节或更多字节。其他架构只是为了使用寄存器额外指令进行简单操作,需要对较大寄存器进行符号扩展或限幅,使其行为类似于字节大小的寄存器。如果您使用的是32位计算机并且使用的是8位字符,因为您的计数从1到100,那么您可能需要使用全尺寸的int,从长远来看,您可能无法通过使用焦炭。现在,如果这是一台基于8086的pc运行dos,那就是另一回事了。或者是一个8位微控制器,那么你想尽可能地倾向于8位变量。