鉴于此代码:
int *p, *q;
p = (int *) 1000;
q = (int *) 2000;
什么是q - p
以及如何?
根据标准,它实际上是未定义的。指针算法不能保证工作,除非指针都指向同一个数组中的一个元素,或者刚好超出同一个数组。
该标准的相关部分是 6.5.6:9(c1x 的 n1362 草案,但自 c99 以来没有改变),其中指出:
当两个指针相减时,都应指向同一个数组对象的元素,或者指向数组对象的最后一个元素;结果是两个数组元素的下标之差。
如果您的int
数据类型是 4 个字节,您很可能会得到 250,但不能保证。未定义的行为(与实现定义的行为不同)意味着未定义。任何事情都可能发生,甚至包括大部分时空的彻底破坏。
进修课程:
q - p 为 250。
2000 - 1000 = 1000
1000 / sizeof(int) = 250
指针运算,假设 sizeof(int) 为 4。
struct foo { int ar[1000]; } big[10];
char small[10];
struct foo *fs, *fe;
char *ss, *se;
fs = &big[0]; fe = &big[9];
ss = &small[0]; se = &small[9];
fe - fs == se - ss;
也就是说,这种情况下两个指针之间的差异是它们之间的数组元素个数。在这种情况下,它是 0、1、... 8 或 9 个元素。
q-p
应该返回从p
到应该执行的增量步数q
。等于250。1000 / sizeof(int)
记住q++
实际上会转到 int 类型的下一个元素,而不是在它的中间,所以它应该在指针的实际值上加 4。因此结果。
答案: qp 将是 250,假设你在一个 anint
是 4 字节的机器上。
计算如下:
q - p = 1000 1000 / 4(整数大小)= 250
它背后的想法:
指针算法背后的想法是,如果你有一个int
指向 1000 的指针和一个int
指向 2000 的指针,并要求两者之间的差异,那么你并不是在问 2000-1000 是多少。您要问的是,我可以在两者之间容纳多少个。int
这对于各种操作都非常方便,例如:
int *i = 100;
i++; // This is **not** 101, it is 104, cause you actually want the next place an int could fit in memory.
这在处理数组时特别有用。整数数组(已定义int arr[10]
)基本上被视为指针。当您编写arr[5]
时,编译器将其转换为*(arr + 5)
,即,将 5 加到int
称为 的指针arr
上,并获取该地址处的值。
之所以可行,是因为这并不arr + 5
意味着“将 5 的值加到 arr ”,它的意思是“将任何必要的值加到 arr 的值以前进 5秒”,或者更准确地说,“将 5 * 添加到arr 值"int
sizeof(int)
因为 p 指向一个 int,所以 q,qp 将是 1000。