对数组元素的地址进行减法时出现意外结果

问题描述

我使用的是基于 x32 的处理器,其中 char = 1 byte,short = 2 bytes and int = 4 bytes

当我创建一个包含 char 元素的 20 类型数组时,我希望看到 20 个内存空间分配给该数组,其地址仅相差 1 byte,因为数组的类型。

如果我从数组中取出两个连续的元素并减去它们的地址,在这种情况下我应该不会得到 1 吗?

对于类型为 shortint 的数组,我希望得到 24。这是因为 shortint 元素需要在内存中对齐。 short elements 将位于偶数地址 (diff 2) 上,而 int elements 将位于可被 4 整除的地址上。

但是,为什么当我运行以下代码时,我得到的是 1,1,1 而不是 1,2,4

我怀疑我在指针算术方面遗漏了一些关键细节。

char vecc[20];
printf("%i\n",&vecc[1]-&vecc[0]);
    
short vecs[20];
printf("%i\n",&vecs[1]-&vecs[0]);
    
int veci[20];
printf("%i\n",&veci[1]-&veci[0]);

解决方法

指针减法产生的结果是索引的差异,而不是地址之间的差距大小。

引用 C11,第 6.5.6 章,(强调我的

当两个指针相减时,都指向同一个数组对象的元素,或者指向数组对象最后一个元素后的一个; 结果是两个数组元素的下标之差。 [...]

,

如果你这样写代码:

        printf("%i\n",(char*)(&vecs[1]) - (char*)(&vecs[0]));
        printf("%i\n",(char*)(&veci[1]) - (char*)(&veci[0]));

输出将是 2 和 4。