2009-12-07 21 views
7

मैं एक उद्देश्य-सी पृष्ठभूमि से आ रहा हूं और सी में अपना ज्ञान विस्तार करने की कोशिश कर रहा हूं। एक बात मुझे उलझन में डाल चुकी है, और सी और ओबज- सी। जैसा कि आप नीचे दिए गए उदाहरणों में देख सकते हैं, चीजें दोनों भाषाओं के बीच थोड़ा अलग व्यवहार करती प्रतीत होती हैं, और मैं सोच रहा था कि क्या आप समझाने में मदद कर सकते हैं?सी पॉइंटर्स बनाम उद्देश्य-सी पॉइंटर्स

सी कोड ठीक काम करता है:

void myFunction() 
{ 
    int x, *pointerX; 
    pointerX = &x; 
    *pointerX = 5; 

    // Prints: "x is 5" 
    printf("x is: %i", x); 
} 

Obj सी कोड में विफल रहता है:

- (void)myMethod 
{ 
    NSString *string = @"Caramel coffee", *stringPointer; 
    stringPointer = &string;     // Warning: Assignemnt from incompatible pointer type 
    *stringPointer = @"Chocolate milkshake"; // Exception: Incompatible types in assignment 

    NSLog(@"string is: %@", string); 
} 

प्रश्न: क्यों मैं स्ट्रिंग की स्मृति पते पर stringPointer असाइन नहीं कर सकते (stringPointer = &string;), और मैं सी के तहत *pointerX = 5; प्रदर्शन करने में सक्षम क्यों हूं, लेकिन मैं ऑब्जेक्टि के तहत *stringPointer = @"Chocolate milkshake"; निष्पादित नहीं कर सकता ve-सी?

मुझे एहसास है कि ओब्जे-सी ऑब्जेक्ट्स और सी के साथ सौदा करता है, लेकिन मुझे पीछे के दृश्यों का विवरण नहीं दिख रहा है कि यह ओब्जे-सी में क्यों काम नहीं करता है। कोई भी मदद बहुत ही सराहनीय होगी। धन्यवाद! :)

+0

क्या आप सी भाग या उद्देश्य-सी भाग को समझने की कोशिश कर रहे हैं? आपके प्रश्न से ऐसा लगता है कि आप सी सीखना चाहते हैं लेकिन आप उद्देश्य-सी कोड लिख रहे हैं जो सी की तरह दिखता है ... – stefanB

+0

सी भाग। भ्रम के बारे में खेद है। मेरी पृष्ठभूमि है मैंने कुछ उद्देश्य-सी किताबें पढ़ी हैं, और अब मैं सी किताबें पढ़ रहा हूं। मुझे उलझन में आया कि सी में पॉइंटर्स कैसे काम करते थे, जो थोड़ा अलग लग रहा था (भले ही ओबज-सी सी के शीर्ष पर बनाया गया हो)। –

+0

मुझे पूरा यकीन है कि पॉइंटर्स सी और ऑब्जेक्टिव-सी में समान काम करते हैं, मुझे लगता है कि कोको कक्षाओं का उपयोग करते समय आप उन्हें भ्रमित कर रहे हैं, बिना समझने के। उदाहरणों को देखने के लिए सबसे आसान बात यह है कि कैसे कोको कक्षाएं आम तौर पर उपयोग की जाती हैं जो समस्याओं को दूर कर देती हैं, क्योंकि मैंने कहा था कि यह मुद्दा क्लास पेड़ के साथ हो सकता है जो इंटरफ़ेस कक्षाओं के पीछे छिपा हुआ है। – stefanB

उत्तर

18

अपने पहले उदाहरण में, x और pointerX विभिन्न प्रकार ((int) और (int *) क्रमशः) की है। आपके दूसरे उदाहरण में, string और stringPointer में समान प्रकार (NSString *) है। बजाय का प्रयास करें:

NSString *string = @"Caramel coffee", **stringPointer; 
3

&string, टाइप NSString ** है, जबकि stringPointer टाइप NSString *, इस प्रकार की चेतावनी है। फिर आप NSString प्रकार के एक चर के लिए एनएसएसटींग (NSString * टाइप के साथ) का एक उदाहरण असाइन करने का प्रयास करते हैं, इस प्रकार त्रुटि।

10

आपका NSString *string स्वयं ही एक सूचक है। इसलिए, इसे इंगित करने के लिए, आपको stringPointer को पॉइंटर के सूचक के रूप में घोषित करने की आवश्यकता है। जो है, की घोषणा stringPointer इस तरह:

NSString **stringPointer; 

तो सब कुछ काम करना चाहिए। ध्यान दें कि वही पॉइंटर अर्थशास्त्र सी और उद्देश्य-सी में लागू होता है।

2

प्रत्येक चर को अपनी लाइन पर परिभाषित करना हमेशा अच्छा विचार है। जब आप अपना प्रारंभिक उद्देश्य-कोड कोड

NSString* string = @"Caramel coffee"; 
NSString* stringPointer; 

कई चीजें स्पष्ट हो जाती हैं।

+1

-1 अभी भी समस्या को ठीक नहीं करता है, क्योंकि सूचक प्रकार असंगत हैं। –

+0

@ क्विन: एक पल में जब मैंने अपना संदेश लिखा था तो समस्या पहले ही हल हो चुकी थी।टिप्पणियों में इस तरह के स्टाइल से संबंधित संदेशों को लिखना बेहतर होगा, लेकिन फिर कोड स्वरूपण की कोई क्षमता नहीं है। – Wildcat

1

सवाल यह है कि - क्या आपके तारों का आधार है या नहीं?
पहला उदाहरण शायद काम करेगा।
गैर-उद्देश्य सी कंपाइलरों में भी, शाब्दिक तारों को लिंकर/कंपाइलर विकल्पों के माध्यम से कॉन्स मेमोरी में रखा जा सकता है।

इस लाइन पर: stringPointer = & string; आप पॉइंटर के पते को स्ट्रिंग poitner में कॉपी कर रहे हैं। स्पष्ट रूप से असंगत।

और इस लाइन पर:
* stringPointer = @ "चॉकलेट मिल्कशेक";

आप पॉइंटर में एक स्ट्रिंग लिखने की कोशिश कर रहे हैं (सूचक 4 बाइट पता है)। इसके ऊपर एक पूरी स्ट्रिंग कॉपी करने के लिए एक अच्छा विचार नहीं है।

0

आप क्या करने की कोशिश कर रहे हैं?

सुनिश्चित नहीं है कि यह आपके इरादे के अनुसार काम करेगा या नहीं।

आप सी से अवधारणाएं ले रहे हैं और इसे कोको कक्षाओं में लागू करते हैं, मैंने सोचा था कि आप सी सीख रहे थे। क्या आपने ऑब्जेक्टिव-सी कोड किसी ऑब्जेक्ट का पता लेने में कहीं भी देखा है?

कोको कक्षाएं Class clusters का उपयोग करके लागू की गई हैं जिसका अर्थ है कि वे एक ही इंटरफेस साझा करते हैं लेकिन आपको विशिष्ट विस्तारित कक्षा मिल जाएगी जो आप छेड़छाड़ करते हैं।

अपने मामले में आप संभावित रूप से कक्षा का पता ले रहे हैं जो NSString बढ़ाता है और इसे NSString पर पॉइंटर को असाइन करता है।

उदाहरण:

NSString * str = @"Caramel coffee"; 
NSString * str2 = [NSString stringWithString:@"all"]; 

NSLog(@"%@", [[str class] className]); 
NSLog(@"%@", [[str class] className]); 

आउटपुट (GNUStep linux):

2009-12-08 10:49:29.149 x[25446] GSCInlineString 
2009-12-08 10:49:29.149 x[25446] NSConstantString 

... अलग स्पष्ट सूचक परिभाषा समस्याओं से दूसरों के द्वारा कहा।

+0

एनएसईआरआरआर पैटर्न शायद सबसे आम मामला है जहां हम ऑब्जेक्टिव-सी: "एनएसईआरआर * त्रुटि में किसी ऑब्जेक्ट का पता लेते हैं; [[NSFileManager defaultManager] contentOfDirectoryAtPath: @" foo "त्रुटि: और त्रुटि]; –

+0

हाँ, लेकिन हम पास करते हैं स्थानीय चर का पता एक विधि में है क्योंकि हम मूल्य वापस लौटने की उम्मीद करते हैं। लेकिन आप आम तौर पर 'NSString * str = और someotherNSStringObject जैसे सामान नहीं देख पाएंगे;' – stefanB

5

बात यह है कि जब आप कोई वस्तु बनाते हैं, तो आप वास्तव में इसे हमेशा एक सूचक के माध्यम से इसे कुशल बनाते हैं, इसलिए (एनएसएसटींग *)। बिल्कुल उसी तरह

void myFunction() 
{ 
    char *string = "this is a C string!"; 
    char **ptr=&string; 


    // Prints: "this is a c string" 
    printf("ptr points to %s: \n", *ptr); 
} 

आप देख सकते हैं, संकेत काम के रूप में वे उद्देश्य-सी में कार्य करें:

ही (एक स्ट्रिंग के साथ काम कर) सी में बात कर प्रयास करें, शायद यह स्पष्ट हो जाता है। ध्यान रखें कि उद्देश्य-सी में बहुत कम प्राइमेटिव हैं (int सबसे स्पष्ट है)। अधिकांश समय आप टाइप ऑब्जेक्ट एक्स (एनएसएसटींग कहते हैं) का पॉइंटर बना रहे हैं, और उसके बाद मेमोरी का एक हिस्सा आवंटित कर रहे हैं ([[ऑब्जेक्ट ऑलोक] init] के माध्यम से) और उस पॉंक के उस पते के प्रारंभ पते को अपने सूचक में जोड़ना। ठीक उसी तरह जैसा हमने सी में अपनी स्ट्रिंग के साथ किया है।

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