我有以下C代码:
#include<stdio.h>
#include<stdlib.h>
int main() {
int a[4] = {1,2,3,4};
int b[4] = {1,2,3,4};
int n = &b[3] - &a[2];
printf("%d\n", n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么值为n-3?我对此没有一个纯粹的解释.变量地址之间的区别如何-3?为什么呢-3?
Eri*_*hil 14
虽然当你减去指向不同数组中元素的指针时,C标准没有定义行为,但似乎发生的事情是你的编译器就b在之前(比地址低)放入内存a.因此,内存布局看起来像:
+------+------+------+------+------+------+------+------+
| b[0] | b[1] | b[2] | b[3] | a[0] | a[1] | a[2] | a[3] |
+------+------+------+------+------+------+------+------+
Run Code Online (Sandbox Code Playgroud)
鉴于这种内存布局,&a[2] - &b[3]是+3因为a[2]内存中的三个元素比b[3].然后&b[3] - &a[2]是-3因为b[3]内存中的三个元素比a[2].(注意,这样的不符合C标准的简单指针算法可能会中断,因为编译器可能会执行各种优化,或者因为某些体系结构上的地址算法很复杂.C标准不仅不定义减法的结果;它一旦执行了未定义的减法,就不会定义程序的行为.)
许多C实现将对象放在堆栈上(如果它们具有自动存储持续时间,而不是静态,分配或线程),并且堆栈通常从高内存地址开始并向低地址增长.所以,如果编译器只是按照你声明它们的顺序为对象分配空间(这通常不是预期的;有很多理由做更好的事情),那么它会有效地a先放入堆栈,然后减少堆栈指针,然后放在b堆栈上,所以b最终的地址低于a.
顺便说一下,两个指针相减的结果有大小ptrdiff_t,这不一定int,所以它应该被印刷printf("%td\n", n);,而不是%d,并n应与被声明ptrdiff_t n;,而不是int n;.的ptrdiff_t类型是在限定的<stddef.h>报头中.
| 归档时间: |
|
| 查看次数: |
120 次 |
| 最近记录: |