0

Suppose I have the global variables:

char *min_ptr, *max_ptr;

and the function:

void f(int *p)
{
    if(min_ptr > p)
        min_ptr = p;
    if(max_ptr < p)
        max_ptr = p;
}

If C does not guarantee that addresses are stored the same way as unsigned long, I guess I can't initialize my variables as follows:

char *min_ptr = ULONG_MAX, *max_ptr = 0;

How can I initialize min_ptr and max_ptr to the smallest and largest addresses respectively? And is it even valid to use the <, >, <=, or >= operators with pointers?

4

4 回答 4

4

<使用, <=,>或的指针减法或指针比较>=具有未定义的行为,除非两个指针都指向同一个数组对象的元素,或者刚刚超过它的末尾。(为此,单个对象被视为单元素数组。)关系运算符比较数组索引,减法产生元素的差异(&arr[5] - &arr[2] == 3例如)。

它可能在大多数系统上“起作用”(即,给你或多或少一致的结果),尽管如果存在对齐问题,减法仍然可能给出无意义的结果。

您可以将任何指向对象的值转换为intptr_tuintptr_t(在 中定义<stdint.h>)然后再转换回来,而不会丢失信息。由于intptr_tuintptr_t是整数类型,因此它们的减法和比较是明确定义的——但这并不意味着比较对于指针值有任何意义。当然减法也会溢出。

您可以接受您的代码行为不是由标准定义的事实(尽管它可能恰好在您的系统上工作),或者您可以找到一种不同的方法来解决您的问题。对于后者,如果您能告诉我们您要解决的问题,我们可能会提供帮助。

于 2013-10-28T01:13:43.110 回答
3

比较运算符可以使用。

对于限制,使用

INTPTR_MIN
INTPTR_MAX

stdint.h.

而且,仅供参考,我相信有更好的方法来做你想做的事情。

于 2013-10-28T00:24:06.363 回答
1

0不是一个有效的地址,这就是为什么它被用来表示空指针常量。所以你可以这样做:

char * min_ptr = NULL;
char * max_ptr = NULL;

/*  Other stuff  */

void f(int *p) {
    if( min_ptr == NULL || min_ptr > p )
        min_ptr = p;
    if( max_ptr == NULL || max_ptr < p )
        max_ptr = p;
}

没有弄乱其他的东西。

于 2013-10-28T00:37:51.967 回答
1

C99 中的头文件<stdint.h>定义了一些有用的东西。uintptr_t是可以包含指针的普通整数类型。stdint.h定义所有类型的最大值和最小值。

所以这应该有效

void *ptr_max = UINTPTR_MAX;

UINTPTR_MIN未定义为指针是无符号的,它们的最小值总是0

是的,您可以比较指针。它在数组的东西中很有用。例如检查基于数组的环形缓冲区未满:

// This code has some bugs. Eg, it does not handle wrap arround.
if (ring_buff_back + 1 < ring_buff_front) {...

请注意,指针上的减法返回ptrdiff_t类似于intptr_t.

于 2013-10-28T00:46:14.557 回答