假设我有以下数组:
int list[3]={2,8,9};
printf("%p,%p,%p",(void*)&list[0],(void*)&list[1],(void*)&list[2]);
是它总是保证&列表[0] <&列表[1] <&列表[2]?
我曾以为它是在使用下的硬性规定,但现在必须非常肯定它作为OP刚才问我这件事时,我回答了有关他的问题endianness
小端或大端
是什么给了我第二个想法是stacks can grow up or down
issue.I不是很肯定,如此你的严谨的答案是appreciated.Thanks。
是的,它保证了&list[0]<&list[1]
和&list[1]<&list[2]
当指针指向相同的数组的元素进行比较,指针具有较大标元件将被认为具有大的值。 这是在C99 6.5.8@5规定:
指针具有较大标值的数组元素比较比指针更大,以相同的阵列的元件具有较低下标值
但是,它不能保证通过的printf印值%p
也将遵循同样的订货-这些值是实现定义的。
从C标准(“第6.2.5节类型”):
...一个阵列型描述了一种连续地分配非空的一组对象...
阵列将在连续的“记忆”进行分配。
Eric和Interjay说的话,这是一件好事,当我开始写这篇所以谢谢你埃里克和Interjay我不认为是,这仅适用于虚拟内存地址。
你的机器和操作系统很可能会使用它创建了一个虚拟地址空间(在您的工作)和块大小的块(页)映射到这个物理内存的内存管理单元(MMU)。
那么,什么Eric和Interjay要说的是,虽然虚拟地址将是连续的物理内存块,他们映射到可能在不同地址。
Virtual Physical
+----------+ +----------+
| | |
| VMA pg 1 |---------->| PMA 88 (VMA1)
| | |
+----------+ +----------+
| |\ ...
| VMA pg 2 | \ ...
| | \ ...
+----------+ \ ...
\ \ ... big gap in physical
\ \ ... memory
\ \ ...
\ \ ...
\ >--+----------+
\ |
\ | PMA 999 (VMA2)
\ |
>-+----------+
因此,对于小数组(比页面大小更小),这可能是既VMA和PMA地址如此,尽管最有可能的PMA!= VMA。 对于除页面大小较大的阵列,虽然看起来VMA连续的,PMA很可能是不相交的顺序和流出,作为上述图试图表明...
另外,我觉得Interjay和Eric会更进一步,说任何C类地址,虽然在C型连续,可能会在内存中的任何地方。 虽然这是不可能的,因为大多数操作系统的执行某种寻呼获得虚拟到物理映射,它可以在技术上是我想......这是很好的学习考虑,所以感谢家伙:)的情况下
如果正在询问存储器如何出现在C型的内部,然后阵列似乎是在C代码连续的,并且所述C表达式&list[0] < &list[1]
是真实的。
如果你问有关如何实际内存C实现内出现时,C标准并不要求在存储阵列中的任何特殊安排。 大多数C实现使用数组连续上升的虚拟内存,但按降序地址将是一个简单的变化。 并且,在物理内存的水平,阵列通常不是连续的,因为从虚拟内存到物理存储器中的映射由操作系统基于不管它具有可用和处理的执行期间甚至可能改变来确定。
另外,存在不保证由印刷字符串%p
是存储器地址。
文章来源: Are the elements of an array guaranteed to be stored from lower to higher addresses?