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

时间:2015-08-24 13:17:29

标签: 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 (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */
        ...
    }
}

我不明白以下表达式中发生了什么:

allocbuf + ALLOCSIZE - allocp >= n

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

请告诉我我错在哪里或在此解释中我缺少什么。

该程序的目的是存储字符。

6 个答案:

答案 0 :(得分:11)

代码是固定缓冲区分配器,并且正在检查以确保至少剩下n个字节。它有助于以图形方式查看内容,并且通过图形方式我的意思是MSPaint:

allocator

所以打破表达:

allocbuf + ALLOCSIZE - allocp >= n

allocbuf + ALLOCSIZE是数组的结尾。结束与allocp之间的差异是剩余字节。因此,我们只需检查以确保差异至少为n

减去两个指针,只要它们指向同一个数组中的元素(或者一个接一个的结尾),就可以很好地定义它们之间的元素数量。作为一个更简单的示例,allocbufallocbuf + ALLOCSIZE都是指针(类型char*)和(allocbuf + ALLOCSIZE) - allocbuf == ALLOCSIZE,元素数量(类型char),这种情况)他们之间。

答案 1 :(得分:7)

从指针中减去指针将为您提供(如果它们是兼容的)元素数量(大小由指针指向的类型确定)。

所以:

allocbuf + ALLOCSIZE

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

allocbuf + ALLOCSIZE - allocp

在allcobuf(+ 1)的最后一个元素和allocp

之间留下的元素数量

在哪种情况下:

allocbuf + ALLOCSIZE - allocp >= n

确定allocbuf中是否留有足够的元素以适合n元素。

编辑:

您可以将它与数组进行比较: 如果你有指向第一个元素(用0索引)和第二个指针的指针,它指向元素大小的4倍(这将指向用4索引的第5个元素),那么当你减去这些两个你将在它们之间得到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;

(几乎)是相同的。

答案 2 :(得分:4)

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

请注意

C11:6.5.6加法运算符(p9):

  

当减去两个指针时,两者都指向同一个数组对象的元素,或者指向数组对象的最后一个元素的元素; 结果是两个数组元素的下标差异。 [...]。
  换句话说,如果表达式Qi分别指向数组对象的j - 和(P)-(Q) - 元素,表达式如果值适合i−j类型的对象,则ptrdiff_t的值为public IEnumerable<Employee> GetEmployees() { //code and return } public Employee GetSingleEmployee(int Id) { //code and return }

答案 3 :(得分:1)

  

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

减去两个指针返回它们之间的距离:它们之间的元素数量(不是以字节为单位的大小或其他任何东西)。

正如你所说,这个子表达式首先超越了最后一个元素:

allocbuf + ALLOCSIZE

然后,通过减去allocp,它返回这个过去最后一个元素指针与allocp中存储的下一个空闲位置之间的距离

(allocbuf + ALLOCSIZE) - allocp

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

答案 4 :(得分:1)

最后,将allocbufallocp视为数字:

现在,我们不知道哪个号码,但我们知道allocp'' points to some element of allocbuf``。

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

总而言之,allocbuf + ALLOCSIZE - allocpALLOCSIZE - "the index of allocbuf that allocp is pointing to"。 换句话说,剩余元素的数量。

然后条件检查是否有足够的剩余元素。

答案 5 :(得分:1)

plotOptions.series.dataLabels

可以扩展到

 plotOptions: {
          series: {
              colorByPoint: true,
              dataLabels: {
                  allowOverlap: true
              }
          },
          /* ... */
}

显示正在发生的事情。

allocbuf + ALLOCSIZE - allocp >= n 点之后,

(allocbuf + ALLOCSIZE) - allocp >= n 会在内存中返回指针(allocbuf + ALLOCSIZE)元素。例如,当ALLOCSIZE指向第一个元素,allocbuf为1000时,操作返回allocbuf之后的元素(指针)1000个元素(这实际上是未定义的内存;它是一个在最后一个已分配元素之后的元素,因此如果要取消引用此指针,则会发生未定义的行为。)

推断出ALLOCSIZE后,一旦指针allocbuf被取消,它将返回类似(allocbuf + ALLOCSIZE)(无符号)的类型,它会给出{之间的元素数量{1}}和allocp。例如,如果size_t指向403rd元素,并且有人想从函数alloc中分配637个元素,它将执行以下操作:

(allocbuf + ALLOCSIZE) - 获取备用元素的数量

allocp查看它是否大于或等于n。如果是这样,它可以分配。