【问题标题】:How does a C program get information from an array internally?C 程序如何在内部从数组中获取信息?
【发布时间】:2014-02-11 01:36:55
【问题描述】:
我对编程比较陌生,所以当有人建议构建一个结构数组(每个结构包含特定“项目”的 n 个属性)比构建 n 个属性数组更快时,我发现我不知道关于数组的争论已经足够了。
我读到了:
how do arrays work internally in c/c++
和
Basic Arrays Tutorial
但我还是不太明白 C 程序如何通过索引从数组中检索特定值。
数组的数据元素在内存中相邻存储,并且数组名称指向第一个元素,这似乎很清楚。
C 程序是否足够聪明,可以根据数据类型和索引进行算术运算以计算出目标数据的确切内存地址,或者程序是否必须以某种方式在每个中间数据块到达那里之前对其进行迭代(就像在链表数据结构中一样)?
更根本的是,如果一个程序通过它的内存地址请求一条信息,机器是如何找到它的?
【问题讨论】:
标签:
c
arrays
cpu-architecture
low-level
array-indexing
【解决方案1】:
让我们举一个更简单的例子。假设你有一个数组int test[10],它像这样存储在地址 1000:
1|2|3|4|5|6|7|8|9|10
编译器知道,例如,一个 int 是 4 个字节。数组访问公式是这样的:
baseaddr + sizeof(type) * index
结构的大小只是其元素大小加上编译器添加的任何填充的总和。所以这个结构的大小:
struct test {
int i;
char c;
}
可能是 5。也可能不是,因为填充。
至于你的最后一个问题,很快(这很复杂)MMU 使用页表将虚拟地址转换为物理地址,然后请求物理地址,如果它在缓存中,则返回,否则为从主内存中获取。
【解决方案2】:
你写道:
C 程序是否足够聪明,可以根据数据类型和索引来计算目标数据的确切内存地址
是的,这正是他们所做的。它们不会迭代中间项目(这样做无济于事,因为没有标记来指导每个项目的开始和结束)。
【解决方案3】:
这就是整个技巧,数组元素在内存中是相邻的。
当你声明一个数组时,例如:int A[10];
变量A 是指向数组中第一个元素的指针。
现在是索引部分,无论何时您执行A[i],都与您执行*(A+i) 完全相同。
索引只是数组起始地址的偏移量,还要记住,在指针算术中,偏移量乘以数组数据类型的大小。
为了更好地理解这一点,请编写一些代码,声明一个数组并打印它的地址,然后打印数组中每个元素的地址。
并注意偏移量如何始终相同并等于机器上数组数据类型的大小。