“内存地址差异”是什么意思?

时间:2010-09-22 09:07:08

标签: c++ c

考虑

#include <cstdio>

int main() {
    char a[10];
    char *begin = &a[0];
    char *end = &a[9];
    int i = end - begin;
    printf("%i\n", i);
    getchar();
}

#include <cstdio>

int main() {
    int a[10];
    int *begin = &a[0];
    int *end = &a[9];
    int i = end - begin;
    printf("%i\n", i);
    getchar();
}

#include <cstdio>

int main() {
    double a[10];
    double *begin = &a[0];
    double *end = &a[9];
    int i = end - begin;
    printf("%i\n", i);
    getchar();
}

以上三个例子也打印 9

我可以知道,我应该如何理解9.这是什么意思?

4 个答案:

答案 0 :(得分:12)

9表示&amp; a [9]和&amp; a [0]之间类型'T'的元素数量(其中T分别是char,int,double)。

它们之间的实际字节数为(&a[9] - &a[0])*sizeof(T)。请注意,根据定义,sizeof(char)为1。进一步注意,字节不是强制为8位。 而是在实现的基本字符集中保存所有字符所需的多个8位内存位置。

编辑:正如@pmg指出的那样,一个字节被定义为一个足够宽的内存位置,可以保存实现基本字符集中的所有字符。

答案 1 :(得分:6)

指向某种类型的指针之间的差异是它们之间的实例数(也就是说它等于数组索引之间的差异)。或者换句话说,它等同于(不确定正确的整数类型)

((int)end - (int)begin)/sizeof(type)
  

6.5.6.9 当减去两个指针时,两个指针都指向   同一个数组对象的元素,或   一个超过数组的最后一个元素   宾语;结果是差异   这两个数组的下标   元素

答案 2 :(得分:3)

编译器将根据指针类型自动计算指针运算,这就是为什么你不能使用void*(无类型信息)或混合指针类型(模糊类型)执行操作。

在MSVC2008(以及我认为的大多数其他编译器)中,语法被解释为计算两个指针之间的元素差异量。

int i = end - begin;
00411479  mov         eax,dword ptr [end] 
0041147C  sub         eax,dword ptr [begin] 
0041147F  sar         eax,3 
00411482  mov         dword ptr [i],eax 

由于减法之后是右移,结果将向下舍入,因此保证N元素可以适合两个指针之间的存储空间(并且可能存在未使用的间隙)。这在下面的代码中得到了证明,其结果也是9。

int main()
{
    double a[10];
    double *begin = &a[0];
    char *endc = (char*)&a[9];
    endc += 7;
    double *end = (double*)endc;
    int i = end - begin;
    printf("%i\n", i);
    getchar();

    return 0;
}

答案 3 :(得分:3)

只需考虑减法的定义:如果,一般

r = b - a

意味着

b = a + r

指针的含义相同:

ptrdiff_t res = end - begin;

从而

end == begin + res

现在,了解正常的指针算术规则,您可以轻松推断resbeginend指向的类型的元素数begin。 1}}和end

<小时/> 请注意,我没有使用int作为res的类型,而是使用ptrdiff_t:这非常有意,因为ptrdiff_t被定义为“由两个指针之间的减法运算返回的类型“(link),所以它是保存这种结果的完美类型。