2009-09-13 41 views

回答

14

对于这两种功能和对象指针,它们编译,但其结果只保证一致为地址来分同一个完整对象的对象(你可以比较一个类或数组的两个成员的地址),如果你比较一个函数或对象本身。

使用std::less<>std::greater<>等将与任何指针类型的工作,并提供一致的结果,即使结果各自内置的操作是不确定的:

void f() { } 
void g() { } 

int main() { 
    int a, b; 

    ///// not guaranteed to pass 
    assert((&a < &b) == (&a < &b)); 

    ///// guaranteed to pass 
    std::less<int*> lss1; 
    assert(lss1(&a, &b) == lss1(&a, &b)); 
    // note: we don't know whether lss1(&a, &b) is true or false. 
    //  But it's either always true or always false. 

    ////// guaranteed to pass 
    int c[2]; 
    assert((&c[0] < &c[1]) == (&c[0] < &c[1])); 
    // in addition, the smaller index compares less: 
    assert(&c[0] < &c[1]); 

    ///// not guaranteed to pass 
    assert((&f < &g) == (&f < &g)); 

    ///// guaranteed to pass 
    assert((&g < &g) == (&g < &g)); 
    // in addition, a function compares not less against itself. 
    assert(!(&g < &g)); 

    ///// guaranteed to pass 
    std::less<void(*)()> lss2; 
    assert(lss2(&f, &g) == lss2(&f, &g)); 
    // note: same, we don't know whether lss2(&f, &g) is true or false. 

    ///// guaranteed to pass 
    struct test { 
    int a; 
    // no "access:" thing may be between these! 
    int b; 

    int c[1]; 
    // likewise here 
    int d[1]; 

    test() { 
     assert((&a < &b) == (&a < &b)); 
     assert((&c[0] < &d[0]) == (&c[0] < &d[0])); 

     // in addition, the previous member compares less: 
     assert((&a < &b) && (&c[0] < &d[0])); 
    } 
    } t; 
} 

一切都应该编译尽管(尽管编译器可以自由地警告它想要的任何代码片断)。


由于功能类型没有sizeof价值,在的指针对象类型将无法正常工作sizeof条款中定义的操作,其中包括:

void(*p)() = ...; 
// all won't work, since `sizeof (void())` won't work. 
// GCC has an extension that treats it as 1 byte, though. 
p++; p--; p + n; p - n; 

一元+任何指针类型的作品,并只会返回它的值,函数指针没有什么特别之处。

+ p; // works. the result is the address stored in p. 

最后请注意,一个指向函数指针不是一个函数指针了:

void (**pp)() = &p; 
// all do work, because `sizeof (void(*)())` is defined. 
pp++; pp--; pp + n; pp - n; 
+0

你有没有任何参考,列出所有的功能指针支持像++,+ n, - n, - ,+ – yesraaj 2009-09-13 16:41:37

+1

像往常一样很好的解释:-),谢谢Litb – yesraaj 2009-09-13 16:57:59

+0

谢谢,很高兴它可以帮助你:) – 2009-09-13 17:10:52

1

#1:函数指针可以被调用。

#2:指针支持关系运算符,因为您可以在指针运算中使用它们并将地址互相比较。实践示例:遍历数组

int data[5] = { 1, 2, 3, 4, 5 }; 

// Increment pointer until it reaches the end-address. 
for (int* i = data; i < data + 5; ++i) { 
    std::cout << *i << endl; 
} 
2

如果指针指向相同的分配,则可以比较指针。例如,如果您有两个指向同一数组元素的指针,则可以在这些指针上使用不等式比较运算符。另一方面,如果你有两个指向不同对象的指针,那么比较是“未定义的”,但实际上,大多数编译器可能只是比较地址。

char *text[] = "hello"; 
const char *e_ptr = strchr(text, 'e'); 
const char *o_ptr = strchr(text, 'o'); 
if (e_ptr < o_ptr) { ... } // this is legal 
char *other_text[] = "goodbye"; 
const char *b_ptr = strchr(other_text, 'b'); 
if (b_ptr > o_ptr) { ... } // not strictly legal 
+0

而在C++中,std :: less可用于比较相同类型的指针,无论它们是否在相同的分配中。 – 2009-09-13 16:25:54

1

运算符<,>,< =,> =都支持指针,但只能保证如果进行比较的两个指针来产生可靠的结果在相同的存储器分配(如两个指针比较的一部分数组分配中的索引)。对于这些,它表示在分配中的相对位置(即,如果a是< b,则a指向数组中比b更低的索引)。对于不在同一分配中的指针,结果是实现定义的(在某些体系结构中,可能违反严格性低于映射所需的兼容性,例如,可以比较一个64位指针的<或>只使用较低32位,如果单个分配不能超过32位指针允许的大小)。这些在函数指针的上下文中没有意义,因为它们不涉及连续的内存分配。

其他原始指针操作:==如果指针指向同一个对象,则返回true。 - 产生两个指针之间的字节数(我认为只用于相同的分配?)。 +不会编译,因为它没有意义。

对于函数指针,它们可以通过*进行取消引用并被调用。

对于指针到部件的功能,有操作员 - > *和*

0

的指针被表示为正常整数值。你可以用所有其他数字类型都允许的指针来做所有事情。 + - */< < >> ==!=^& | ! 〜%。我希望我什么也不会忘记。

函数指针的不同之处在于它可以用()运算符调用。