为什么如果我从指针中减去另一个没有类型转换的指针(整数指针),结果将是1而不是4个字节(就像我将两个指针都转换为int时一样)。示例:
int a , b , *p , *q;
p = &b;
q = p + 1; // q = &a;
printf("%d",q - p); // The result will be one .
printf("%d",(int)q - (int)p); // The result will be 4(bytes). The memory address of b minus The memory address of a.
答案 0 :(得分:4)
根据C标准(6.5.6添加剂操作员)
9当减去两个指针时,都指向元素 相同的数组对象,或者超过数组最后一个元素的数组 宾语;结果是两者下标的差异 数组元素......
如果两个指针指向同一个数组的元素,那么就像在标准引用中所说的那样
结果是两个数组下标的差异 元素
那就是你会得到这两个指针之间数组的元素数量。这是所谓的指针算法的结果。
如果将存储在指针中的地址减去整数值,则会得到与算术减法运算相对应的数字。
答案 1 :(得分:3)
因为指针减法的ptrdiff_t
是相对于指向的元素的大小计算的。这样方式更方便;例如,它会告诉您在到达另一个指针之前可以增加一个指针的次数。
答案 2 :(得分:3)
为什么如果我从指针中减去另一个没有类型转换的指针(整数指针),结果将是1而不是4个字节
这是指针指向的数据类型的重点。查看下面的数组上下文可能更容易。无论基础数据类型(此处为long
或double
)如何,您都可以使用指针算法来导航数组,而无需关心其元素的大小。换句话说,(指针+ 1)表示指向下一个元素,无论其类型如何。
long l[] = { 10e4, 10e5, 10e6 };
long *pl = l + 1; // point to the 2nd element in the "long" array.
double d[] = { 10e7, 10e8, 10e9 };
double *pd = d + 2; // point to the 3rd element in the "double" array.
请在代码中注明:
int a , b , *p , *q;
p = &b;
q = p + 1; // q = &a; <--- NO this is wrong.
a
和b
声明彼此相邻的事实并不意味着a
和b
被分配在内存中彼此相邻。因此q
指向b
旁边的内存地址 - 但该地址中的内容未定义。
答案 3 :(得分:3)
你有
的地方int a , b , *p , *q;
编译器可以将a
和b
置于任何位置。他们甚至不必彼此靠近。此外,当您减去两个int
指针时,结果的大小为int
,而不是字节。
答案 4 :(得分:2)
C不是汇编语言。所以指针不只是简单的整数 - 指针是特殊的人,知道如何指向其他东西。
指针和指针算术在C中的工作方式的基础是它们可以指向数组的连续元素。所以,如果我们写
int a[10];
int *p1 = &a[4];
int *p2 = &a[3];
然后p1 - p2
将为1.结果为1,因为&#34;距离&#34; a[3]
和a[4]
之间是一个int。结果是1,因为4 - 3 = 1.结果是不 4(因为您可能认为如果您知道int
在您的计算机上是32位),因为我们在进行汇编语言编程或使用机器地址时并不感兴趣;我们正在使用数组进行更高级别的语言编程,我们正在考虑这些术语。
(但是,是的,在机器地址级别,计算p2 - p1
的方式通常为(&lt; p2
中的原始地址值&gt; - &lt; {{1中的原始地址值}}&gt;)/ p1
。)