C 指针算术

发布于 2024-08-18 10:00:11 字数 128 浏览 4 评论 0原文

给定这段代码:

int *p, *q;

p = (int *) 1000;
q = (int *) 2000;

什么是 q - p 以及如何实现?

Given this code:

int *p, *q;

p = (int *) 1000;
q = (int *) 2000;

What is q - p and how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情何以堪。 2024-08-25 10:00:11

根据标准,它实际上是未定义的。指针算术不能保证有效,除非指针都指向同一个数组中的元素,或者指向同一个数组之外的元素。

该标准的相关部分是 6.5.6:9(c1x 的 n1362 草案,但自 c99 以来没有改变),其中规定:

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

如果您的 int 数据类型是 4 个字节,您很可能会得到 250,但不能保证。未定义的行为(与实现定义的行为不同)意味着未定义。任何事情都有可能发生,甚至包括大部分时空的彻底毁灭。

复习课程:

  • 定义的行为是标准强制执行的行为。实现必须这样做才能保持一致。
  • 实现定义的行为由实现决定,但必须清楚地记录该行为。如果您不太关心可移植性,请使用此选项。
  • 未定义的行为意味着任何事情都可能发生。永远不要这样做!

It's actually undefined, according to the standard. Pointer arithmetic is not guaranteed to work unless the pointers are both pointing to either an element in, or just beyond, the same array.

The relevant section of the standard is 6.5.6:9 (n1362 draft of c1x but this hasn't changed since c99) which states:

When two pointers are subtracted, both shall point to elements of the same array object,
or one past the last element of the array object; the result is the difference of the
subscripts of the two array elements.

You'll most likely get 250 if your int datatype is 4 bytes but there's no guarantee. Undefined behaviour (unlike implementation-defined behaviour) means just that, undefined. Anything can happen, up to an including the total destruction of a large proportion of space-time.

A refresher course:

  • Defined behaviour is what is mandated by the standard. Implementations must do this to be conformant.
  • Implementation-defined behaviour is left up to the implementation but it must document that behaviour clearly. Use this if you don't care too much about portability.
  • Undefined behaviour means anything can happen. Don't ever do that!
野生奥特曼 2024-08-25 10:00:11

q - p 为 250。

2000 - 1000 = 1000
1000 / sizeof(int) = 250

指针算术,假设 sizeof(int) 为 4。


Edit:
OK, to clarify. In C when two pointers are of the same type then the difference between them is defined the number of things of the pointed-to type between them. For example,

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 is 250.

2000 - 1000 = 1000
1000 / sizeof(int) = 250

pointer arithmetic, assuming sizeof(int) is 4.


Edit:
OK, to clarify. In C when two pointers are of the same type then the difference between them is defined the number of things of the pointed-to type between them. For example,

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;

That is, the difference between the two pointers in this case is the number of array elements between them. In this case it is 0, 1, ... 8 or 9 elements.

掌心的温暖 2024-08-25 10:00:11

qp 应该返回从 pq 应该执行多少步增量。这是 1000 / sizeof(int) 并且等于 250。记住 q++ 实际上会转到 int 类型的下一个元素,而不是在它的中间,所以它应该添加4 为指针的实际值。于是就有了这样的结果。

q-p supposed to return how many steps with increment you should do to go from p to q. Which is 1000 / sizeof(int) and equals 250. Remember q++ will actually go to the next element of type int, not in the middle of it, so it should add 4 to the actual value of the pointer. Hence the result.

把回忆走一遍 2024-08-25 10:00:11

答案
qp 将是 250,假设您使用的机器的 int 是 4 个字节。

计算公式为:

q - p = 1000
1000 / 4(int 的大小)= 250

其背后的想法

指针算术背后的想法是,如果您有一个指向 1000 的 int 指针和一个 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),即向名为int的指针添加5 arr,并获取该地址处的值。

之所以有效,是因为 arr + 5 确实不是意思是“向 arr 的值添加 5”,它的意思是“向 arr 的值添加任何必要的内容”前进 5 ints”,或者更准确地说,“将 5 * sizeof(int) 添加到 arr 的值”

The answer:
q-p is going to be 250, assuming you're on a machine where an int is 4 bytes.

The calculation is:

q - p = 1000
1000 / 4 (size of an int) = 250

The idea behind it:

The idea behind pointer arithmetic is that, if you have an int pointer to 1000 and an int pointer to 2000, and ask for the difference, you're not asking what's 2000-1000. What you're asking is, how many int's can I fit between the two.

This is very convenient for all sorts of operations, for example:

int *i = 100;
i++; // This is **not** 101, it is 104, cause you actually want the next place an int could fit in memory.

This especially comes in handy when dealing with arrays. An array of ints (defined int arr[10]) is basically treated like a pointer. When you write arr[5], the compiler translates it to *(arr + 5), i.e., add 5 to the int pointer called arr, and get the value at that address.

The reason this works, is because arr + 5 does not mean "add 5 to the value of arr", it means "add whatever is neceassary to the value of arr to go forward 5 ints", or, more precisely, "add 5 * sizeof(int) to the value of arr"

并安 2024-08-25 10:00:11

由于 p 指向 int,因此 q,qp 将是 1000。

As p is pointing to an int and so q, q-p will be 1000.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文