简体   繁体   English

C中最大和最小的指针地址

[英]Largest and smallest pointer addresses in C

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: 如果C不保证地址的存储方式与unsigned long相同,则我想我无法按如下方式初始化变量:

char *min_ptr = ULONG_MAX, *max_ptr = 0;

How can I initialize min_ptr and max_ptr to the smallest and largest addresses respectively? 如何将min_ptr和max_ptr分别初始化为最小和最大地址? And is it even valid to use the <, >, <=, or >= operators with pointers? 并且将<,>,<=或> =运算符与指针一起使用甚至有效吗?

Pointer subtraction or pointer comparison using < , <= , > , or >= has undefined behavior unless both pointers point to elements of the same array object, or just past the end of it. 使用<<=>>=指针减法或指针比较具有未定义的行为,除非两个指针均指向同一数组对象的元素,或者仅指向其末尾。 (For this purpose, a single object is treated as a single-element array.) The relational operators compare the array indices, and subtraction yields the difference in elements ( &arr[5] - &arr[2] == 3 , for example). (为此,将单个对象视为一个单元素数组。)关系运算符比较数组索引,并且相减得出元素之差(例如, &arr[5] - &arr[2] == 3 ) 。

It's likely to "work" (ie, give you more or less consistent results) on most systems, though subtraction may still give nonsensical results if there are alignment problems. 在大多数系统上,它都可能“起作用”(即,为您提供或多或少的一致结果),但是如果存在对齐问题,则减法仍会产生无意义的结果。

You can convert any pointer-to-object value to intptr_t or uintptr_t (defined in <stdint.h> ) and back again without loss of information. 您可以将任何指针到对象的值转换为intptr_tuintptr_t (在<stdint.h>定义)并再次返回,而不会丢失信息。 Since intptr_t and uintptr_t are integer types, subtractions and comparisons on them are well defined -- but that doesn't mean that the comparison means anything with respect to the pointer values. 由于intptr_tuintptr_t是整数类型,因此对它们的减法和比较进行了很好的定义-但这并不意味着比较对指针值没有任何意义。 And of course subtraction can overflow. 当然,减法会溢出。

You can either live with the fact that your code's behavior is not defined by the standard (though it may happen to work on your system), or you can find a different way to solve your problem. 您可以忍受代码的行为不是由标准定义的事实(尽管它可能会在您的系统上运行),或者您可以找到其他解决问题的方法。 For the latter, we might be able to help if you'll tell us what problem you're trying to solve. 对于后者,如果您能告诉我们您要解决的问题,我们可能会提供帮助。

The comparison operators are valid to use. 比较运算符可以使用。

For the limits, use 对于极限,使用

INTPTR_MIN
INTPTR_MAX

from stdint.h . 来自stdint.h

And, FYI, I believe there is a better way to do what you are trying to do. 而且,仅供参考,我相信有一种更好的方法来做您想做的事情。

0 is not a valid address, that's why it's used to represent the null pointer constant. 0不是有效地址,这就是为什么它用于表示空指针常量的原因。 So you can just do: 因此,您可以执行以下操作:

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;
}

without messing about with that other stuff. 而不用弄乱其他东西。

The header file <stdint.h> in C99 has some useful things defined. C99中的头文件<stdint.h>定义了一些有用的东西。 uintptr_t is a normal integer type that can contain a pointer. uintptr_t是可以包含指针的普通整数类型。 stdint.h defines Maximum and Minimum on all it's types. stdint.h定义所有类型的最大值和最小值。

So this should work 所以这应该工作

void *ptr_max = UINTPTR_MAX;

UINTPTR_MIN is not defined as pointer's are unsigned their smallest value is always 0 . UINTPTR_MIN未定义为指针是无符号的,其最小值始终为0

Yes you can compare pointers. 是的,您可以比较指针。 It's useful in array stuff. 在数组中很有用。 Eg checking a array based ring buffer is not full: 例如,检查基于数组的环形缓冲区未满:

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

Note the subtraction on pointers return a ptrdiff_t which is similar to intptr_t . 注意,指针的减法返回一个ptrdiff_t ,它类似于intptr_t

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM