2009-07-23 15 views
10

मैं सिर्फ सीखने उद्देश्य सी शुरू कर दिया है और तारांकन मुझे कुछ परेशानी दे रहा है। जैसा कि मैं नमूना कोड देखता हूं, कभी-कभी इसका उपयोग तब होता है जब एक चर घोषित किया जाता है और कभी-कभी यह नहीं होता है। इसका उपयोग कब किया जाना चाहिए इसके लिए "नियम" क्या हैं। मैंने सोचा कि यह चर के डेटा प्रकार के साथ कुछ करने के लिए था। (ऑब्जेक्ट डेटा प्रकारों के लिए आवश्यक तारांकन, int जैसे साधारण डेटा प्रकारों के लिए आवश्यक नहीं है) हालांकि, मैंने ऑब्जेक्ट डेटा प्रकारों को देखा है जैसे सीजीपॉइंट तारांकन के बिना घोषित किया गया है? क्या कोई निश्चित उत्तर है या क्या आपको इसके साथ चर और उपयोग करने के लिए क्या करना है?जब उद्देश्य सी में एक चर घोषित आप तारांकित (*) का उपयोग नहीं करना चाहिए जब

उत्तर

17

इसका उपयोग कब किया जाना चाहिए इसके लिए "नियम" क्या हैं।

आप पॉइंटर घोषित करने के लिए तारांकन का उपयोग करते हैं।

एक कोको वस्तु के लिए, आप हमेशा एक सूचक की घोषणा कर रहे हैं, ताकि आप हमेशा एक तारक का उपयोग करें। आप वस्तु को चर में नहीं डाल सकते हैं; आप हमेशा वस्तु के लिए एक सूचक को संभालते हैं।

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

आप पॉइंटर को पॉइंटर भी दे सकते हैं; जैसा कि आप उम्मीद कर सकते हैं, इसमें कई तारांकन शामिल हैं। उदाहरण के लिए, NSRect ** एक एनएसआरईक्ट (जो एक संरचना है, कोको वस्तु नहीं) के सूचक के लिए एक सूचक है।

मैंने सोचा कि इसका डेटा प्रकार के चर के साथ कुछ करना है। (ऑब्जेक्ट डेटा प्रकारों के लिए आवश्यक तारांकन, int जैसे साधारण डेटा प्रकारों के लिए आवश्यक नहीं)

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

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

हालांकि, मैंने ऑब्जेक्ट डेटा प्रकारों को देखा है जैसे CGPoint तारांकन के बिना घोषित किया गया है?

CGPoint एक संरचना है, कोको वस्तु नहीं है। इस प्रकार, आप एक वेरिएबल घोषित कर सकते हैं जिसमें एक CGPoint है और किसी और को पॉइंटर नहीं है।

+0

एक (मोटे तौर पर ऐतिहासिक) ध्यान दें: नहीं ऑब्जेक्टिव-सी के सभी जायके की आवश्यकता 'वस्तुओं की ओर इशारा'। कुछ ने आपको 'NSObject ऑब्जेक्ट 'के रूप में स्टैक पर ऑब्जेक्ट्स बनाने की अनुमति भी दी है। – johne

+0

मोटे तौर पर, शायद नहीं, बल्कि पूरी तरह से ऐतिहासिक: GNUstep, IIRC पर, आप अभी भी ढेर पर एक वस्तु घोषणा कर सकते हैं। –

+1

एर, नहीं। GNUstep, सभी व्यावहारिक उद्देश्यों के लिए, एक पुस्तकालय अनिवार्य रूप से साझा किया जाता है AppKit.framework और Foundation.framework (यानी, 'OpenStep' विनिर्देश) का क्लोन। जीएनयूस्टेप का अपना रनटाइम भी है (libobjc)। "क्लासिक" उद्देश्य-सी, जिसे मैं एप्पल ऑब्जेक्टिव-सी 1.0 के रूप में परिभाषित करता हूं, एक अद्भुत भाषा है। यह कुछ सरल प्राइमेटिव्स और थोड़ा डरावना प्रदान करता है कि आपको उनका उपयोग कैसे करना चाहिए, जो इसकी विरासत पर विचार करने में कोई आश्चर्य नहीं है। अधिकांश इसे सी के "सख्त सुपरसेट" मानते हैं, यह शीर्ष पर स्तरित है। ऐसा नहीं है ओबीजेसी 2 (यानी, जीसी और 'शून्य *' पॉइंटर्स, उदाहरण के लिए)। – johne

6

तारांकन इंगित करता है चर एक डेटाप्रकार के लिए सूचक है।

अधिक जानकारी के लिए pointers ध्यान देना चाहिए। वे प्रोग्रामिंग का एक बहुत ही महत्वपूर्ण और मौलिक पहलू हैं।

+0

मैं समझता हूँ कि इसका मतलब है कि यह एक सूचक है। लेकिन मेरे प्रश्न तब होते हैं जब आपको सूचक का उपयोग करना चाहिए या नहीं? – Jason

+0

यह पूरी तरह से स्थिति पर निर्भर करता है। यदि आप किसी फ़ंक्शन से कोई मान वापस करना चाहते हैं, तो आपको ढेर-आवंटित स्मृति का उपयोग करने की आवश्यकता है, उदाहरण के लिए, अन्यथा यह फ़ंक्शन से बाहर निकलने पर पुनः दावा किया जाएगा। रेफरेंसिंग सरणी के लिए पॉइंटर्स भी आवश्यक हैं। जवाब देने के लिए यह एक आसान सवाल नहीं है, जेसन। जब से तुम स्मृति के बारे में के रूप में ज्यादा है, लेकिन सिर्फ ढेर-आवंटित वस्तुओं का उपयोग कर मतलब यह नहीं है कि आप संकेत के साथ सौदा करने की जरूरत नहीं है चिंता करने की ज़रूरत नहीं है ढेर आवंटन उपयोगी है। लेकिन मूल रूप से यदि आपका प्रकार छोटा और छोटा रहता है, तो पॉइंटर्स से परेशान न हों। यदि यह बड़ा या लंबा रहता है, तो पॉइंटर्स का उपयोग करें। – Welbog

7

मुझे लगता है कि आपको पहले सी प्रोग्रामिंग पर थोड़ा सा पढ़ना चाहिए। उद्देश्य-सी सी का सुपरसैट है जिसका कारण आप CGPoint घोषित करने के लिए * का उपयोग नहीं करते हैं क्योंकि CGPoint एक संरचना है, CGGeometry.h शीर्षलेख फ़ाइल में एक नज़र डालें।

+1

यह असली कुंजी है। प्रश्न के प्रकार के लिए, .h फ़ाइल पर जाएं जहां इसे परिभाषित किया गया है, और यह देखने के लिए देखें कि यह एक संरचना या कक्षा है या नहीं। यदि यह एक वर्ग है, तो आपको * की आवश्यकता है; यदि यह एक संरचना है, तो आपको सामान्य उपयोग के लिए इसकी आवश्यकता नहीं है, हालांकि आप चाहें तो कर सकते हैं - लेकिन यह एक और अधिक उन्नत विषय है। – Amagrammer

+0

हां, यह मेरी गलती है। मुझे झूठा माना जाता है कि CGPoint एक ऑब्जेक्ट डेटा प्रकार था और इससे मेरे बिंदु पर लगभग सभी भ्रम पैदा हुए। क्या यह कुछ विशिष्ट है जो मुझे यह जानने के लिए है कि यह है और ऑब्जेक्ट है। क्या यह देखना आसान है कि सुपरक्लास क्या है? – Jason

+0

@Amagrammer, +1 उस टिप्पणी के लिए धन्यवाद। –

0

लगता है कि आपने नियम पता लगा है: सूचक के लिए तारांकन, कोई तारांकन अन्यथा। समस्या यह है कि यह तय करने के लिए कोई नियम नहीं है कि सीजीपॉइंट जैसे कुछ को हेडर फ़ाइल को देखे बिना पॉइंटर की आवश्यकता होगी या नहीं। जैसा कि वेल्बोग ने कहा, पॉइंटर का उपयोग/उपयोग करने के बीच वास्तविक भेद यह है कि क्या आप ढेर या ढेर पर आवंटित कर रहे हैं, हालांकि अधिकांश समय आपको केवल यह निर्धारित करने की आवश्यकता होगी कि आप किसी ऑब्जेक्ट के साथ काम कर रहे हैं या नहीं (तारांकन) या एक आदिम (कोई तारांकन)।

3

आप जब चर प्रकार एक वर्ग है एक * का उपयोग करें।

एक उदाहरण हो सकता है।

NSNumber *number; 
NSInteger integer; 

NSNumber वैरिएबल प्रकार एक वर्ग है, जबकि NSInteger एक सामान्य सी-टाइप int के लिए सिर्फ एक और नाम है।

#if __LP64__ || NS_BUILD_32_LIKE_64 
    typedef long NSInteger; 
    typedef unsigned long NSUInteger; 
#else 
    typedef int NSInteger; 
    typedef unsigned int NSUInteger; 
#endif 

इसके अलावा, आप इस प्रकार NSNumber की तरह एक वर्ग (एक वस्तु) का एक उदाहरण घोषणा कर सकते हैं नहीं, एक सूचक का उपयोग किए बिना (: आप यहाँ देख सकते हैं, संकलक int साथ NSInteger के हर घटना की जगह आप * का उपयोग करते हैं)। इसका कारण यह है कि जब आप alloc किसी ऑब्जेक्ट के रूप में कक्षा का एक उदाहरण स्मृति पता लौटा दिया जाता है। एक सूचक एक प्रकार का चर है जो विशेष रूप से स्मृति स्थान को संदर्भित करता है। उदाहरण के लिए:

NSNumber *number = [NSNumber alloc]; 

यहाँ number के संख्यात्मक मान 0x19a30c0 की तरह एक स्मृति स्थान होगा। आप int जैसे जोड़कर और घटाकर इसे चालू कर सकते हैं। एक NSNumber सूचक के रूप में यह घोषणा की कुंजी उद्देश्य तो संकलक मदद कर सकते हैं सांकेतिक शब्दों में बदलनेवाला सत्यापित करें कि वर्ग कुछ विधियां या जाना जाता गुण का उपयोग करने की है।


एक आखिरी उदाहरण:

NSInteger integer = [NSNumber alloc]; 

क्या integer का मूल्य हो सकता है? हमारे उदाहरण में, यह 0x19a30c0 होगा। इसके साथ आप वास्तव में [integer someMethod] के माध्यम से नए आवंटित NSNumber ऑब्जेक्ट तक पहुंच सकते हैं। कंपाइलर आपको चेतावनी देगा, यद्यपि। अधिक से अधिक:

integer += 4; 

यह यह करने के लिए 4 जोड़ने और यह 0x19a30c4 बनाकर संख्यात्मक मान 0x19a30c0 पर असर पड़ेगा।


कैसे, कब और क्यों एक * ऑपरेटर का उपयोग करने के कुछ और उदाहरण के लिए C/C++ pointers पर इस विकिपीडिया लेख देखें।

+1

CGPoint बारे में अपने प्रश्न से बातचीत करते हुए आपको पता होना चाहिए कि CGPoint एक वर्ग नहीं है। यह एक संरचना है। इस प्रकार, आप स्थिर, गैर परिवर्तनशील कोड संकलन पर आवंटित CGPoints हो सकता है। दूसरा पहलू पर, यदि आप गतिशील रूप से चलाने के समय के दौरान एक CGPoint आवंटित, आप एक CGPoint सूचक का प्रयोग करेंगे (यानी: CGPoint * cgPointer) स्मृति में चर संदर्भ के लिए। मेक भावना? – Brenden

0

उत्तर बहुत आसान है: आपको हमेशा उद्देश्य-सी ऑब्जेक्ट्स का उपयोग करते समय तारांकन का उपयोग करना चाहिए।

कारण यह है कि वे ढेर पर आवंटित नहीं किया जा सकता है, तो आप क्या आप CGPoint जैसी संरचनाओं के साथ कर सकते नहीं कर सकते।

ऑब्जेक्टिव-सी के डिजाइनर क्योंकि वे अन्य सी-संकेत की तरह याद करने के लिए संकेत दिए गए हैं आप हमेशा जो एस्टरिस्क जोड़ने बनाने के लिए चुना है, मुझे लगता है,।

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