2010-05-31 23 views
6

मैं इसे देख लूंगा, लेकिन ईमानदारी से मुझे नहीं पता कि कहां से शुरू करना है क्योंकि मुझे नहीं पता कि इसे क्या कहा जाता है। मैं इस तरह के कार्यों के लिए पारित चर देखा है:सी में क्या मतलब है (शून्य **)?

myFunction((void**)&variable); 

कौन सा मुझे से बाहर बिल्ली confuses कारण उन सभी मेरे लिए परिचित लग; मैंने उन्हें पहले कभी ऐसा नहीं देखा है।

इसका क्या अर्थ है? मैं एक नया हूँ इसलिए कम शब्दकोष, बेहतर, धन्यवाद!

उत्तर

4

यह void पॉइंटर पर सूचक के लिए एक कलाकार है।

आप इसे विंडोज सिस्टम पर CoCreateInstance() जैसे कार्यों के साथ अक्सर देखते हैं। ताकि CoCreateInstance() कोई मान्य मान को ifaceptr सेट कर सकते हैं

ISomeInterface* ifaceptr = 0; 
HRESULT hr = ::CoCreateInstance(CLSID_SomeImplementation, NULL, CLSCTX_ALL, 
    IID_ISomeInterface, (void**)&ifaceptr); 
if(SUCCEEDED(hr)) 
{ 
    ifaceptr->DoSomething(); 
} 

डाली एक void सूचक के लिए सूचक में एक ISomeInterface सूचक को सूचक बदल देता है।

चूंकि यह void पॉइंटर के लिए सूचक है, तो फ़ंक्शन इंटरफ़ेस आईडी (जैसे IID_ISomeInterface) के आधार पर किसी भी प्रकार के आउटपुट पॉइंटर्स कर सकता है।

+0

यह समझ में आता है। लेकिन मैंने कभी अज्ञात डेटाटाइप के एक चर को संभालने के बारे में नहीं सुना। CoCreateInstance ifaceptr को कैसे संभालेगा, अगर यह नहीं जानता कि यह किस प्रकार है। दूसरी बात, मूल डेटाटाइप के आकार के विपरीत मनमान आकार है। – numerical25

+0

CoCreateInstance हमेशा COM ऑब्जेक्ट में पॉइंटर बनाता है, और इसे 'शून्य **' पैरामीटर के माध्यम से देता है। आप इसे 'IID_ISomeInterface' पैरामीटर के रूप में बताते हैं कि आप किस प्रकार टाइप करना चाहते हैं, और आप 'void **' को उस चीज़ में बदलने के लिए टाइपकास्ट का सही उपयोग करने के लिए ज़िम्मेदार हैं जिसका आप उपयोग कर सकते हैं। –

+0

'CoCreateInstance() '" जानता है "आउटपुट पॉइंटर इंटरफ़ेस आईडी के अनुसार क्या होना चाहिए (उदाहरण के लिए' IID_ISomeInterface' है)। इसके अलावा, ** सभी ** पॉइंटर्स एक दिए गए आर्किटेक्चर के लिए समान आकार हैं (उदाहरण के लिए 32-बिट सिस्टम पर सभी पॉइंटर्स 4 बाइट्स हैं, जबकि 64-बिट सिस्टम पर सभी पॉइंटर्स 8 बाइट हैं)। 'शून्य 'प्रकार जैसी कोई चीज़ नहीं है, लेकिन आपके पास' शून्य 'पॉइंटर्स हो सकते हैं। यह मूल रूप से किसी भी प्रकार के सूचक का मतलब है। –

1

जो &variable को void** (यानी void पर पॉइंटर के लिए सूचक) पर रहता है।

उदाहरण के लिए, यदि आप के

void myFunction(void** arg); 

int* variable; 

यह variable का पता गुजरता पंक्तियों के साथ कुछ है myFunction() करने के लिए (कि क्या unary- & करता है यह पता ले जाता है,)।

3

यह एक अनिर्धारित प्रकार के साथ एक चर के लिए सूचक के लिए एक सूचक है। सभी पॉइंटर्स एक ही आकार के हैं, इसलिए void* का अर्थ है "कुछ के लिए एक सूचक लेकिन मुझे नहीं पता कि यह क्या है"। एक void** अनिर्दिष्ट प्रकार की 2 डी सरणी भी हो सकती है।

+0

"* सभी पॉइंटर्स एक ही आकार हैं *" जरूरी नहीं है। लेकिन आप अधिक सही ढंग से कह सकते हैं, "शून्य के लिए एक पॉइंटर किसी भी प्रकार के ऑब्जेक्ट को पॉइंटर स्टोर करने के लिए काफी बड़ा है"। –

7

void* "किसी भी चीज़ के लिए सूचक" है। void ** संकेत का एक और स्तर है - "पॉइंटर टू पॉइंटर टू कुछ"। असल में, जब आप फ़ंक्शन को किसी भी प्रकार के पॉइंटर को वापस करने की अनुमति देना चाहते हैं तो आप इसे पास करते हैं।

&variable चर का पता लेता है। variable काम करने के लिए पहले से ही किसी प्रकार का सूचक होना चाहिए, लेकिन शायद यह void * नहीं है - यह int * कह सकता है, इसलिए इसका पता लेना int ** होगा। यदि फ़ंक्शन void ** लेता है तो आपको उस प्रकार पर डालना होगा।

(बेशक, यह है, वास्तव में सही प्रकार का ऑब्जेक्ट वापस जाने के लिए की जरूरत है अन्यथा कोड बुला ट्रैक नीचे असफल हो जायेगी जब यह इसे गलत तरीके से उपयोग करने के लिए कोशिश करता है।)

+0

ठीक है इसलिए कॉलिंग फ़ंक्शन को मेरे ऑब्जेक्ट को शून्य के रूप में डालने के लिए एक विवाद के रूप में टाइप शून्य को अनुरोध करना है। लेकिन मुझे लगता है कि अनुवर्ती प्रश्न यह है कि डाटाटाइप शून्य को क्या पेशकश करना है जो समारोह के लिए फायदेमंद होगा?यदि शून्य एक अज्ञात डेटाटाइप का प्रतिनिधित्व करता है, तो इसका मतलब है कि गुण और मान भी अज्ञात हैं। – numerical25

+0

यह आपको सामान्य प्रकार की जांच के प्रकार के आसपास जाने की अनुमति देता है; आप (उदाहरण के लिए) एक ऐसा फ़ंक्शन कर सकते हैं जो फ़ंक्शन में पॉइंटर लेता है, और उसे कॉल करने का तर्क होता है, फिर परिणाम देता है। यदि आपको प्रकार निर्दिष्ट करना था (उदा। Char *, int *, आदि) तो आपको प्रत्येक तर्क प्रकार के लिए एक फ़ंक्शन होना होगा; शून्य का उपयोग करके * आप वास्तविक प्रकार के कारों की देखभाल किए बिना डेटा का उपयोग कर सकते हैं। –

0

चर कुछ करने के लिए एक सूचक है अपरिभाषित (शून्य) प्रकार का। & ऑपरेटर उस चर के पते को लौटाता है, इसलिए अब आपके पास किसी सूचक के लिए सूचक है। इसलिए सूचक द्वारा संदर्भ में पॉइंटर को पारित किया जाता है। फ़ंक्शन का दुष्प्रभाव हो सकता है जो उस पॉइंटर द्वारा संदर्भित स्मृति को बदलता है। दूसरे शब्दों में, इस फ़ंक्शन को कॉल करने से मूल पॉइंटर संदर्भित हो सकता है।

1

यह टुकड़ा द्वारा टुकड़ा अलग ले लो ...

myfunction प्रकार शून्य का एक सूचक के लिए सूचक ले जाता है (जो बहुत बहुत मायने रखता है वह किसी पर पॉइंट सकता है)। इसे कुछ इस तरह घोषित किया जा सकता है:

myFunction(void **something); 

जो कुछ भी आप पास करते हैं वह उस प्रकार के पास होना चाहिए। तो आप एक सूचक का पता लेते हैं, और इसे एक शून्य सूचक बनाने के लिए (शून्य **) के साथ डालें। (मूल रूप से क्या यह के लिए अंक के बारे में किसी भी विचार की यह अलग करना -। जो संकलक के बारे में अन्यथा कराहना सकता है)

इसका मतलब है कि & चर पता है (& इस करता है) एक सूचक की - तो चर सूचक है। किसका? कौन जाने!

Address:0x601020 Value:1 
Address:0x601024 Value:2 

:

#include <stdio.h> 

int myInteger = 1; 
int myOtherInt = 2; 
int *myPointer = &myInteger; 

myFunction(void **something){ 
    *something = &myOtherInt; 
} 

main(){ 
    printf("Address:%p Value:%d\n", myPointer, *myPointer); 
    myFunction((void**)&myPointer); 
    printf("Address:%p Value:%d\n", myPointer, *myPointer); 
} 

आप संकलन और इस चलाते हैं, यह उत्पादन की इस तरह देना चाहिए:

यहाँ एक और अधिक पूरा टुकड़ा, यह कैसे एक साथ फिट बैठता है की एक विचार दे रहा है आप देख सकते हैं कि मेरे फ़ंक्शन ने मेरे पॉइंटर के मान को बदल दिया - जो केवल यह कर सकता था क्योंकि यह सूचक का पता पारित कर दिया गया था।

+0

ओउओ, ठीक है। तो अगर मैं गलत हूं तो मुझे सही करो। एक शून्य सूचक केवल किसी भी प्रकार के डेटाटाइप को पकड़ने के लिए है। एक बार एक विशिष्ट डेटाटाइप शून्य सूचक को डाला जाता है, तो शून्य सूचक उस डेटाटाइप का हो जाता है। और निश्चित रूप से, मैं एक फ़ंक्शन में एक शून्य पॉइंटर को पास नहीं कर सकता जब तक कि इसके लिए फ़ंक्शन अनुरोध न हो। – numerical25

+0

एक सूचक सिर्फ एक मान है - स्मृति में एक पता। इसका प्रकार संकलक के लिए एक संकेत है कि यह किस प्रकार की बात बताता है। एक शून्य पॉइंटर कंपाइलर को बताने जैसा है कि आप यह बताने वाले नहीं हैं कि पॉइंटर किस प्रकार इंगित कर सकता है। पैरामीटर पारित करते समय, आपको हमेशा उस प्रकार से मेल खाना पड़ेगा जिसे फ़ंक्शन स्वीकार करने के लिए घोषित किया गया है। तो यदि फ़ंक्शन एक शून्य ** चाहता है और आपके पास int ** है, तो आपको यह कार्य करने की आवश्यकता है कि कार्य क्या अपेक्षा करता है। –

0
#include <stdio.h> 
#include <iostream> 

int myInteger = 1; 
std::string myOtherInt = "Test"; 
int *myPointer = &myInteger; 

void myFunction(void **something) 
    { 
     *something = &myOtherInt; 
    } 

int main(){ 
    //printf("%d\n", *myPointer); 
    printf("Address:%p Value:%d\n", myPointer, *myPointer); 
    myFunction((void**)&myPointer); 
    printf("Address:%p Value:%d\n", myPointer, *myPointer); 
} 
संबंधित मुद्दे