C 这个涉及指针的算术表达式发生了什么?

C 这个涉及指针的算术表达式发生了什么?,c,pointers,C,Pointers,以下是C语言的代码: #define ALLOCSIZE 1000 /* size of available space */ static char allocbuf[ALLOCSIZE]; /* storage for alloc */ static char *allocp = allocbuf; /* next free position */ char *alloc(int n) /* return pointer to n characters */ { if (allo

以下是C语言的代码:

#define ALLOCSIZE 1000 /* size of available space */

static char allocbuf[ALLOCSIZE]; /* storage for alloc */
static char *allocp = allocbuf; /* next free position */

char *alloc(int n) /* return pointer to n characters */
{
    if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */
        ...
    }
}
我不明白以下表达式中发生了什么:

allocbuf + ALLOCSIZE - allocp >= n
allocbuf + ALLOCSIZE - allocp >= n
我知道allocbuf作为数组名相当于指向第一个元素&allocbuf[0]的指针,显然allocp是一个指针,最后ALLOCSIZE是一个简单的int。因此,将ALLOCSIZE添加到allocbuff中会得到allocbuff的ALLOCSIZE索引元素,它也是一个指针。但是从指针&allocbuf[ALLOCSIZE]中减去指针allocp就是我丢失的地方。我甚至不确定是否可以在C中添加指针

请告诉我我错在哪里,或者我在这个解释中遗漏了什么


这个程序的目的是存储字符

从指针中减去指针将得到它们之间的元素数(如果它们兼容的话)(大小由指针指向的类型决定)

因此:

指针指向allocbuf的最后一个元素之后

allocbuf + ALLOCSIZE - allocp
allcobuf(+1)的最后一个元素和allocp之间剩余的元素量

在这种情况下:

allocbuf + ALLOCSIZE - allocp >= n
确定
allocbuf
中是否有足够的元素来容纳
n
元素

编辑:

您可以将其与阵列进行比较: 如果您有指向第一个元素的指针(它将被索引为
0
)和第二个指针,它将指向元素大小的4倍(它将指向索引为4的第五个元素),那么当您减去这两个元素时,您将在它们之间得到4个元素(就像从索引4中减去索引0)。但它只有在指针指向同一内存缓冲区(如数组)时才有意义

因此:

int array[5] = {1, 2, 3, 4, 5, 6};
int a* = &array[0] //equivalent to array
int b* = &array[4]
这是:

int *array = malloc(6 * sizeof(int));
//set array values
int *a = array;
int *b = array + 5;

(几乎)是相同的。

表达式
allocbuf+ALLOCSIZE-allocp
将给出指针
&allocbuf[ALLOCSIZE]
和指针
allocp
之间的元素数
allocbuf+ALLOCSIZE-allocp>=n
只需检查
n
是否小于指针之间的元素
&allocbuf[ALLOCSIZE]
allocp

注意

C11:6.5.6加法运算符(第9页): 当减去两个指针时,两个指针都应指向同一数组对象的元素,或指向数组对象最后一个元素之后的元素结果是两个数组元素的下标之差。[…]。
换句话说,如果表达式
P
Q
分别指向数组对象的
i
-th和
j
-th元素,表达式
(P)-(Q)
具有值
i−j
如果值适合类型为
ptrdiff\u t
的对象


代码是一个固定的缓冲区分配器,正在检查以确保您至少还有
n
字节。它有助于以图像方式查看事物,我所说的图像方式是指MSPaint:

因此,分解表达式:

allocbuf + ALLOCSIZE - allocp >= n
allocbuf + ALLOCSIZE - allocp >= n
allocbuf+ALLOCSIZE
是数组的结尾。end和
allocp
之间的差异是剩余的字节。所以我们只需检查以确保差异至少为
n

减去两个指针,只要它们指向同一数组中的元素(或超过末尾的元素),就可以定义为它们之间的元素数。作为一个简单的例子,
allocbuf
allocbuf+ALLOCSIZE
都是指针(类型为
char*
),它们之间的
(allocbuf+ALLOCSIZE)-allocbuf==ALLOCSIZE
,元素数量(在本例中为
char

我甚至不确定是否可以在C中添加指针

减去两个指针将返回它们之间的距离:它们之间的元素数(而不是字节大小或其他任何值)

正如您所说,这个子表达式首先经过最后一个元素:

allocbuf + ALLOCSIZE
然后,通过减去
allocp
,它返回经过最后一个元素指针的这个指针与存储在
allocp
中的下一个自由位置之间的距离

(allocbuf + ALLOCSIZE) - allocp

如果该距离优于n,则意味着allocbuf中至少还有n个元素的空间。

最后,将
allocbuf
allocp
视为数字:

现在,我们不知道是哪个数字,但假设我们知道
allocp''指向
allocbuf``的某个元素

然后,
allocp-allocbuf
allocp
指向的元素的索引(请记住,将它们视为数字-至少只要它们指向相同的内存对象)

因此,总之,
allocbuf+ALLOCSIZE-allocp
是allocp指向的allocbuf索引。 换句话说,剩余元素的数量

allocbuf + ALLOCSIZE - allocp >= n
然后,条件检查是否有足够的剩余元素

allocbuf + ALLOCSIZE - allocp >= n
可以扩展到

(allocbuf + ALLOCSIZE) - allocp >= n
展示正在发生的事情

(allocbuf+ALLOCSIZE)
在where
allocbuf
点之后返回内存中的指针
ALLOCSIZE
元素。例如,由于
allocbuf
指向第一个元素,并且
ALLOCSIZE
为1000,因此该操作将返回
allocbuf
之后的元素(指针)1000个元素(这实际上是未定义的内存;它是最后一个分配的元素之后的一个元素,因此如果取消引用此指针,则会发生未定义的行为)

一旦推导出
(allocbuf+ALLOCSIZE)
,一旦指针
allocp
从中取出,它将返回类似
size\t
(无符号)的类型,该类型给出
(allocbuf+ALLOCSIZE)之间的元素数量
allocp
。例如,如果
allocp
指向第403个元素,并且有人希望从函数alloc分配637个元素,它将执行以下操作:

allocbuf+ALLOCSIZE-allocp
-获取备用元件的数量