2009-09-13 8 views
6

फ़ंक्शन पॉइंटर द्वारा समर्थित सभी ऑपरेशन कच्चे सूचक से अलग हैं? है>, <, < =,> = कच्चे पॉइंटर्स द्वारा समर्थित ऑपरेटर यदि ऐसा है तो उपयोग क्या है?सी/सी ++ में कच्चे सूचक और फ़ंक्शन पॉइंटर द्वारा समर्थित ऑपरेशंस क्या हैं?

उत्तर

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 मूल्य, संचालन के pointee प्रकार से काम नहीं चलेगा 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

+1

सामान्य रूप से महान स्पष्टीकरण जैसे फ़ंक्शन पॉइंटर्स द्वारा समर्थित सभी संचालन सूचीबद्ध करता है :-), धन्यवाद Litb – yesraaj

+0

धन्यवाद, खुशी है कि यह आपकी मदद करता है :) –

1

# 1: फ़ंक्शन पॉइंटर्स को बुलाया जा सकता है।

# 2: संबंधपरक ऑपरेटर संकेत के लिए समर्थित हैं, क्योंकि उन पर सूचक arithmetics में इस्तेमाल करते हैं और एक दूसरे के पतों की तुलना कर सकते हैं। व्यावहारिक उदाहरण: एक सरणी

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

आप संकेत तुलना कर सकते हैं अगर वे एक ही आवंटन में इंगित Traversing। उदाहरण के लिए, यदि आपके पास एक ही सरणी के तत्वों पर इंगित करने वाले दो पॉइंटर्स हैं, तो आप उन पॉइंटर्स पर असमानता तुलना ऑपरेटर का उपयोग कर सकते हैं। दूसरी तरफ, यदि आपके पास अलग-अलग ऑब्जेक्ट्स पर इशारा करते हुए दो पॉइंटर्स हैं, तो तुलना "अनिर्धारित" है, हालांकि, अभ्यास में, अधिकांश कंपाइलर्स शायद पते की तुलना करेंगे।

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

और सी ++ में, std :: कम उसी प्रकार के पॉइंटर्स की तुलना करने के लिए कम इस्तेमाल किया जा सकता है, भले ही वे एक ही आवंटन में हों या नहीं। –

1

ऑपरेटरों <,>, < =,> = संकेत के लिए समर्थन कर रहे हैं, लेकिन केवल विश्वसनीय परिणाम प्राप्त होने की अगर दो संकेत तुलना की जा रही गारंटी दी जाती है एक ही स्मृति आवंटन (करने के लिए दो संकेत की तुलना की तरह का हिस्सा रहे हैं सरणी आवंटन में अनुक्रमणिका)। इनके लिए, यह आवंटन में सापेक्ष स्थिति इंगित करता है (यानी, यदि < बी, तो ए बी की तुलना में सरणी में निचली अनुक्रमणिका को इंगित कर रहा है)। पॉइंटर्स जो एक ही आवंटन में नहीं हैं, परिणाम कार्यान्वयन परिभाषित किया गया है (और कुछ आर्किटेक्चर में, मानचित्रों के लिए आवश्यक संगतता से सख्त कम उल्लंघन कर सकते हैं। उदाहरण के लिए, 64-बिट पॉइंटर की तुलना < या> केवल निम्न के उपयोग से की जा सकती है 32 बिट्स, यदि एक एकल आवंटन 32-बिट पॉइंटर के लिए आकार के आकार से अधिक नहीं हो सकता है)। ये फ़ंक्शन पॉइंटर्स के संदर्भ में वास्तव में समझ में नहीं आता है क्योंकि वे निरंतर स्मृति आवंटन को संबोधित नहीं करते हैं।

अन्य कच्चे सूचक ऑपरेटर: == पॉइंटर्स एक ही ऑब्जेक्ट को इंगित कर रहे हैं तो सही हो जाता है। - दो पॉइंटर्स के बीच बाइट्स की संख्या उत्पन्न करता है (मुझे लगता है कि केवल उसी आवंटन के लिए अच्छा है?)। + संकलित नहीं करता है, क्योंकि यह अर्थहीन होगा।

फ़ंक्शन पॉइंटर्स के लिए, उन्हें * द्वारा संदर्भित किया जा सकता है और कहा जाता है।

सूचक-टू-सदस्य-कार्यों के लिए, वहाँ ऑपरेटरों कर रहे हैं -।> * और *

0

एक सूचक एक सामान्य पूर्णांक मान के रूप में प्रतिनिधित्व कर रहा है। आप पॉइंटर्स के साथ सबकुछ कर सकते हैं जिसे अन्य सभी संख्यात्मक प्रकारों पर भी अनुमति दी जाती है। + - */< < >> ==! =^& | ! ~% मुझे आशा है कि मैं कुछ भी नहीं भूल गया।

एक फ़ंक्शन पॉइंटर इस तरह से अलग है कि इसे() ऑपरेटर के साथ बुलाया जा सकता है।

संबंधित मुद्दे