为何访问数组元素仅需一次内存访问?结合汇编与栈的疑问
Great question—this is a super common confusion when mixing C arrays, assembly, and stack memory. Let’s break this down clearly using your example.
First, Correct a Key Misconception About Array Names
When you declare char arr[3] = {'a','b','c'}; as a local variable, here’s what actually happens on the stack:
- The compiler allocates 3 consecutive bytes at addresses 8, 9, 10 to store 'a', 'b', 'c' respectively.
- The name
arris not a separate variable that takes up extra stack space to store the value 8 (the first element’s address). Instead,arris just a compile-time symbol that directly refers to the starting address of the array (8). It doesn’t exist as a memory location you need to read from first.
Why Array Element Access is a Single Memory Access
When you write arr[1] in your C code, the compiler does all the math at compile time:
- It knows
arrpoints to address 8, and eachcharis 1 byte. - It calculates the target element’s address directly:
8 + (1 * 1) = 9. - In assembly (e.g., x86), this translates to an instruction like:
mov al, byte ptr [ebp + 8] ; Assuming ebp is the stack base pointer, and arr starts at ebp+8
This is a single memory access—the CPU goes straight to address 9 and reads the value 'b' without any intermediate steps.
Compare This to a Pointer Variable (To See the Difference)
If you instead used a pointer:
char *ptr = arr; // ptr is a separate variable that stores address 8 char b = ptr[1];
Here’s what happens:
- The CPU first reads the value stored in
ptr(address 8) from its own stack location—first memory access. - It adds 1 to get address 9, then reads the value at 9—second memory access.
What About the "Address of arr"?
You mentioned "arr自身也有对应的地址" (arr has its own address). If you take &arr, you’ll get the same address (8) as arr itself. The difference is purely in type: &arr is a pointer to the entire array (char (*)[3]), while arr decays to a pointer to the first element (char *). But this doesn’t mean arr occupies extra memory—it’s just a different way of referring to the same starting address.
内容的提问来源于stack exchange,提问作者user7110415

