2009-09-13 11 views

答えて

14

機能とオブジェクトポインタの両方のために、彼らはコンパイルが、その結果はアドレスのみがサブするために一貫性が保証されます(クラスまたは配列の2つのメンバのアドレスを比較することができます)、また、関数またはオブジェクトをそれ自身と比較する場合は、同じ完全オブジェクトのオブジェクトを使用します。

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; 

任意のポインタ型の単項+作品、その値を返すだけで、関数ポインタのために特別なことはありません。

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

++、+ n、 - n、 - 、+ – yesraaj

+1

のような関数ポインタでサポートされているすべての操作をリストする参照がありますか:-)、Thanks Litb – yesraaj

+0

ありがとう、 –

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

ポインタが同じ割り当てを指している場合は、ポインタを比較できます。たとえば、同じ配列の要素を指すポインタが2つある場合、そのポインタに対して不等式比較演算子を使用できます。一方、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を使用して同じ型のポインタを比較することができます。同じ型かどうかは関係ありません。 –

1

オペレータ<、>、< =、> =への2つのポインタを比較するように同じメモリ割り当て(の一部であるポインタに支持されているが、2つだけのポインタが比較される場合に信頼性のある結果を生成することが保証されています配列割り当てのインデックス)。これらは、割り当て内の相対位置を示します(つまり、< bの場合、aはbよりも配列内の低いインデックスを指しています)。同じ割り振りにないポインターの場合、結果はインプリメンテーションで定義されます(いくつかのアーキテクチャーでは、マップに必要な互換性に厳密に違反する可能性があります)。例えば、64ビットポインターを<または>単一の割り当てが32ビットポインタに許容されるサイズを超えることができない場合は32ビット)。これらは、連続したメモリ割り当てに対処しないため、実際には関数ポインタのコンテキストで意味をなさない。

他の未加工のポインタ操作:==は、ポインタが同じオブジェクトを指している場合はtrueを返します。 - 2つのポインタの間のバイト数を生成します(私は同じ割り振りに対してのみ良いと思います)。 +は意味がないので、コンパイルしません。

ファンクションポインタの場合、*によって参照解除され、呼び出すことができます。

へのポインタメンバ関数については、事業者がある - 。> *と*

0

ポインタは通常の整数値として表される。

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

最後に関数へのポインタポインタもう関数ポインタではないことに注意してください。他のすべての数値型でも許可されているポインタですべてを行うことができます。 + - */< < >> ==!=^& | ! 〜%。私は何も忘れてはいけないと思う。

関数ポインタは、()演算子で呼び出すことができるという点でのみ異なります。

関連する問題