जब एक पिन के लिए एक int वैरिएबल का उपयोग किया जाता है जब const int, Enum या #define अधिक समझ में आता है


24

जब पिन कोड के निष्पादन के दौरान बदलने की संभावना नहीं है, तो लोग पिन नंबर निर्दिष्ट करने के लिए चर का उपयोग क्यों करते हैं?

कई बार मुझे intपिन परिभाषा के लिए इस्तेमाल किया जा रहा है,

int led = 13;

जब एक का उपयोग करें const int

const int led = 13;

या enum, या#define

#define LED 13

बहुत अधिक समझ में आता है।

यह Arduino साइट पर ट्यूटोरियल में भी है, उदाहरण के लिए, पहला ट्यूटोरियल जो ज्यादातर लोग चलाते हैं, ब्लिंक

मैंने कहीं पढ़ा है जिसे const intप्राथमिकता दी जाती है #define। शुरुआत से ही लोगों को बुरी आदतों को विकसित करने की अनुमति देने के बजाय इसे शुरू से ही प्रोत्साहित क्यों नहीं किया जाता है? मैंने इसे कुछ समय पहले देखा था, लेकिन हाल ही में इसने मुझे परेशान करना शुरू कर दिया है, इसलिए यह सवाल है।

मेमोरी / प्रसंस्करण / बुद्धिमान कंप्यूटिंग है एक const int, enumया उस बात के लिए #define, एक सादे से बेहतर int, यानी कम स्मृति, में संग्रहीत पर विभिन्न स्मृति (फ़्लैश, EEPROM, SRAM), तेजी से निष्पादन, तेज संकलित करने के लिए?


यह एक डुप्लिकेट प्रतीत हो सकता है कि क्या # कॉन्स्टेंट के लिए #define या कॉन्स्टेंट इंट का उपयोग करना बेहतर है? , लेकिन मैं इस सवाल को संबोधित कर रहा हूं कि लोग चर का उपयोग क्यों करते हैं, और प्रदर्शन में सुधार कैसे होता है जब वे नहीं करते हैं, बजाय इसके कि किस प्रकार का निरंतर बेहतर है।


9
क्योंकि भयानक भयानक भयानक होता है। अधिकांश हॉबीस्ट को अनुभवी प्रोग्रामर नहीं बनाया जाता है और इसलिए अन्य हॉबीस्ट को बुरी आदतें सिखाते हैं।
इग्नासियो वाज़क्वेज़-अब्राम्स

1
विशेष रूप से पिंस के साथ, डिजिटल एरिटाइट जैसे बुनियादी आर्कडीनो एपीआई कार्यों का सरलीकृत रूप उचित एम्बेडेड डिज़ाइन को प्रोत्साहित नहीं करता है, अर्थात पूरे पोर्ट के लिए मास्क और एकल मेमोरी एड्रेस का उपयोग करना
crasic

जवाबों:


20
const int led = 13;

यह सही तरीका है। या और भी:

const byte led = 13;

आपके पास कितने पिन हैं?

कुछ ट्यूटोरियल काफी गुणवत्ता नियंत्रण के माध्यम से नहीं गए थे, क्योंकि वे हो सकते हैं।

प्रदर्शन बेहतर होगा const byte, तुलना करें, intहालांकि कंपाइलर स्मार्ट हो सकता है यह महसूस करने के लिए कि आप क्या कर रहे हैं।

आप जो कर सकते हैं, वह लोगों को अपने कोड में उपयोग करके अधिक कुशल तकनीकों का उपयोग करने के लिए धीरे से प्रोत्साहित करना है।


टिप्पणियों के लिए प्रतिक्रियाएँ

  1. एक टिप्पणीकार ने सुझाव दिया है कि byteमानक सी नहीं है। यह सही है, हालांकि यह एक Arduino StackExchange साइट है, और मेरा मानना ​​है कि Arduino IDE द्वारा आपूर्ति किए गए मानक प्रकारों का उपयोग स्वीकार्य है।

    Arduino.h में यह रेखा है:

    typedef uint8_t byte;

    ध्यान दें कि यह बिल्कुल वैसा नहीं है जैसा कि है unsigned char। देखें बनाम अहस्ताक्षरित चार uint8_t और जब uint8_t ≠ अहस्ताक्षरित चार है?

  2. एक अन्य टिप्पणीकार ने सुझाव दिया है कि बाइट का उपयोग करने से प्रदर्शन में सुधार जरूरी नहीं होगा, क्योंकि इससे छोटी संख्या intको बढ़ावा दिया जाएगा int(यदि आप इस पर अधिक चाहते हैं तो इंटीगर प्रमोशन रूल्स देखें)।

    हालांकि एक कास्ट आइडेंटिफ़ायर के संदर्भ में , कंपाइलर किसी भी मामले में कुशल कोड उत्पन्न करेगा। उदाहरण के लिए, "ब्लिंक" को अलग करने से यह मूल रूप में मिलता है:

    00000086 <loop>:
      86:   8d e0           ldi r24, 0x0D   ; 13
      88:   61 e0           ldi r22, 0x01   ; 1
      8a:   1b d1           rcall   .+566       ; 0x2c2 <digitalWrite>

    वास्तव में यह एक ही कोड उत्पन्न करता है 13:

    • शाब्दिक है
    • एक है #define
    • एक है const int
    • एक है const byte

कंपाइलर जानता है कि यह एक नंबर को एक रजिस्टर में कब फिट कर सकता है और कब नहीं। हालांकि यह कोडिंग का उपयोग करने के लिए अच्छा अभ्यास है जो आपके इरादे को इंगित करता है । इसे बनाने constसे यह स्पष्ट होता है कि संख्या नहीं बदलेगी, और इसे बनाने byte(या uint8_t) यह स्पष्ट करता है कि आप एक छोटी संख्या की उम्मीद कर रहे हैं।


भ्रामक त्रुटि संदेश

#defineयदि आप गलती करते हैं तो आपको मिलने वाले त्रुटि संदेशों से बचने का एक और प्रमुख कारण है । इस "पलक" स्केच पर विचार करें जिसमें एक त्रुटि है:

#define LED = 13;

void setup() {
  pinMode(LED, OUTPUT);      // <---- line with error
}

void loop() {
  digitalWrite(LED, HIGH);   // <---- line with error 
  delay(1000);             
  digitalWrite(LED, LOW);    // <---- line with error
  delay(1000);              
}

सतह पर यह ठीक दिखता है, लेकिन यह इन त्रुटि संदेशों को उत्पन्न करता है:

Blink.ino: In function ‘void setup()’:
Blink:4: error: expected primary-expression before ‘=’ token
Blink:4: error: expected primary-expression before ‘,’ token
Blink:4: error: expected `;' before ‘)’ token
Blink.ino: In function ‘void loop()’:
Blink:8: error: expected primary-expression before ‘=’ token
Blink:8: error: expected primary-expression before ‘,’ token
Blink:8: error: expected `;' before ‘)’ token
Blink:10: error: expected primary-expression before ‘=’ token
Blink:10: error: expected primary-expression before ‘,’ token
Blink:10: error: expected `;' before ‘)’ token

आप पहली हाइलाइट की गई लाइन (पंक्ति 4) को देखते हैं और "=" चिन्ह भी नहीं देखते हैं । इसके अलावा, लाइन ठीक लग रहा है। अब यह पूरी तरह से स्पष्ट है कि समस्या यहाँ क्या है ( = 13इसके लिए प्रतिस्थापित किया जा रहा है LED), लेकिन जब कोड में 400 रेखाएं और नीचे हो जाती हैं, तो यह स्पष्ट नहीं है कि समस्या एलईडी के परिभाषित होने के तरीके के साथ है।

मैंने लोगों को कई बार इसके लिए (अपने सहित) गिरते देखा है।


आपके पास कितने पिन हैं? एक बहुत अच्छा बिंदु निक है, जैसा कि अधिकांश बोर्डों में केवल दसियों की सीमा में होता है, सैकड़ों नहीं (यानी 255 से अधिक), इसलिए एक intओवरकिल है ... यानी, जब तक कि Arduino अंत में तेरा बोर्ड के साथ बाहर आ जाता है ... :-)
ग्रीनलाइन

2
C के पास एक byteप्रकार नहीं है । आपका मतलब है unsigned char
केविन

जरूरी नहीं कि प्रदर्शन के byteबजाय बेहतर हो int, क्योंकि ज्यादातर संदर्भों में, छोटे प्रकार के साथ पूर्णांक मान intको बढ़ावा दिया जाता है int
पीट बेकर

1
C doesn't have a byte type. You mean unsigned char.- मेरा जवाब Arduino संदर्भ में था, जिसमें यह है typedef uint8_t byte;। तो एक Arduino के लिए, का उपयोग byteकरना ठीक है।
निक गैमन

Performance won't necessarily be better with byte instead of int- संशोधित पोस्ट देखें।
निक गैमन

19

जैसा कि इग्नासियो में ठीक-ठीक बताया गया है, यह मूल रूप से है क्योंकि वे बेहतर नहीं जानते हैं। और वे बेहतर नहीं जानते क्योंकि जो लोग उन्हें सिखाते थे (या सीखने के समय वे संसाधनों का उपयोग करते थे) बेहतर नहीं जानते थे।

Arduino कोड और ट्यूटोरियल में से अधिकांश ऐसे लोगों द्वारा लिखे गए हैं, जिनके पास प्रोग्रामिंग में कभी कोई प्रशिक्षण नहीं है और वे बहुत ही "सेल्फ सिखाए गए" संसाधनों से ऐसे लोग हैं, जो स्वयं बहुत ज्यादा स्वयं सिखाया जाता है, जो प्रोग्रामिंग में कोई उचित प्रशिक्षण नहीं है।

ट्यूटोरियल कोड के कई स्निपेट मैं उस जगह के आसपास देख रहा हूं (और विशेष रूप से वे जो केवल YouTube वीडियो के भीतर उपलब्ध हैं --- urgh) एक असफल चिह्न होगा यदि मैं उन्हें एक परीक्षा में चिह्नित कर रहा था।

हां, constगैर-कास्ट पर पसंद किया जाता है, और यहां तक ​​कि #define, क्योंकि:

  • A const(जैसे #define, नॉन-कांस्ट के विपरीत) कोई भी RAM आवंटित नहीं करता है
  • const(एक गैर-कास्ट की तरह, लेकिन इसके विपरीत #define) मूल्य को एक स्पष्ट प्रकार देता है

दूसरा बिंदु विशेष रुचि का है। जब तक कि विशेष रूप से अन्यथा टाइप-कास्टिंग ( (long)3) या एक प्रकार के प्रत्यय ( 3Lया दशमलव बिंदु की उपस्थिति) के साथ नहीं बताया गया हो 3.0, #defineएक संख्या का एक हमेशा एक पूर्णांक होगा और उस मूल्य पर किया गया सभी गणित ऐसा होगा जैसे कि यह एक था पूर्णांक। ज्यादातर समय यह एक समस्या नहीं है, लेकिन आप दिलचस्प परिदृश्यों में भाग ले सकते हैं जब आप #defineएक ऐसे मूल्य पर प्रयास करते हैं जो पूर्णांक से बड़ा हो सकता है, जैसे कि स्टोर करना #define COUNT 70000और फिर intउस पर अन्य मूल्यों के साथ एक गणितीय ऑपरेशन करना। उपयोग करने से constआपको संकलक को यह बताने के लिए मिलता है "यह मान इस चर प्रकार के रूप में माना जाता है" - इसलिए आप इसके बजाय उपयोग करेंगे: const long count = 70000;और सभी अपेक्षा के अनुरूप काम करेंगे।

इसका नॉक-ऑन प्रभाव भी है कि यह उस स्थान के चारों ओर मूल्य पारित करते समय प्रकार की जांच करता है। const longएक फ़ंक्शन के पास जाने की कोशिश करें जो एक की अपेक्षा करता है intऔर यह चर रेंज को कम करने के बारे में शिकायत करेगा (या यहां तक ​​कि परिदृश्य के आधार पर संकलन करने में पूरी तरह से विफल हो सकता है)। उस के साथ करो #defineऔर यह चुपचाप तुम्हें गलत परिणाम देने पर ले जाएगा और तुम घंटे के लिए अपना सिर खरोंच कर देंगे।


7
यह ध्यान देने योग्य है कि एक constचर को संदर्भ के आधार पर रैम की आवश्यकता हो सकती है, उदाहरण के लिए, यदि इसे गैर-कॉन्स्टैक्स फ़ंक्शन से वापसी मान का उपयोग करके आरंभ किया जाता है।
पीटर ब्लूमफील्ड

इसी तरह, const int foo = 13; bar(&foo);निश्चित रूप से संकलक के लिए वास्तविक मेमोरी आवंटित करने की आवश्यकता होगी foo
इल्मरी करोनन

3
यदि आप एक ऐसे मैक्रो को परिभाषित करते हैं जो एक ऐसे मान को विस्तारित intकरता है जो एक संकलक में फिट नहीं होगा, तो उस मूल्य को सबसे छोटा प्रकार माना जाता है जिसमें यह फिट होगा (हस्ताक्षरित बनाम अहस्ताक्षरित के बारे में नियम)। यदि आप एक ऐसी प्रणाली पर हैं जहाँ int16 बिट्स हैं, तो #define count 70000यह देखने में परिणाम होगा countजैसे longकि इसे परिभाषित किया गया है const long count = 70000;। इसके अलावा, यदि आप countकिसी फ़ंक्शन के उन संस्करणों में से किसी से अपेक्षा करते हैं int, तो कोई भी संकलक उनके साथ ऐसा ही व्यवहार करेगा।
पीट बेकर

1
मैं @ पेबैक के साथ सहमत हूं - एक निर्माण की तरह #define COUNT 70000एक इंट में नहीं काटता है , लेकिन कंपाइलर इसे उस नंबर को धारण करने के लिए एक बड़े प्रकार के रूप में मानता है। यह सच है कि यह स्पष्ट नहीं हो सकता है जब आप उपयोग करते हैं COUNTकि यह एक इंट नहीं है, लेकिन आप किसी const longभी चीज के बारे में एक ही बात कह सकते हैं ।
निक गैमन

2
"# adefine हमेशा एक पूर्णांक होगा" यह सच नहीं है। आप पूर्णांक शाब्दिक के नियम ले रहे हैं और उन्हें प्रीप्रोसेसर मैक्रोज़ पर लागू कर रहे हैं। यह सेब और पॉप संगीत की तुलना करने जैसा है। अभिव्यक्ति COUNTअपने उदाहरण में अभिव्यक्ति के साथ संकलन से पहले बदल दिया जाता है 70000, जो एक प्रकार शाब्दिक के नियमों के द्वारा परिभाषित किया गया है, जैसे 2या 13Lया 4.0शाब्दिक के नियमों से परिभाषित कर रहे हैं। तथ्य यह है कि आप #defineउन अभिव्यक्तियों का उपयोग करने के लिए अप्रासंगिक हैं। आप #defineसी कोड के मनमाने ढंग से विखंडन का उपयोग कर सकते हैं , यदि आप चाहें।
मोनिका

2

Arduino के लिए 2-सप्ताह की नौसिखिया के रूप में, मैं Arduino के सामान्य विचार पर गैर-प्रोग्रामर द्वारा कब्जा कर लिया जा रहा था। अधिकांश रेखाचित्रों की मैंने जांच की है, जिनमें Arduino साइट पर शामिल हैं, आदेश की कुल कमी दिखाते हैं, उन रेखाचित्रों के साथ जो काम नहीं करते हैं और मुश्किल से दृष्टि में सुसंगत टिप्पणी करते हैं। फ्लो चार्ट गैर-मौजूद हैं, और "लाइब्रेरी" एक गैर-मॉडरेट जंबल हैं।


0

मेरा जवाब है ... वे ऐसा करते हैं क्योंकि यह काम करता है। मुझे अपने उत्तर में एक प्रश्न न करने का कठिन समय मिल रहा है जैसे कि "इसे 'गलत' क्यों करना पड़ता है?"


3
एक अच्छे प्रोग्रामर की एक बानगी यह है कि कोड हमेशा उनके इरादों को दर्शाता है।
इग्नासियो वाज़केज़-अब्राम्स

1
हम अभी भी Arduinos के बारे में बात कर रहे हैं, है ना? ;)
linhartr22

3
Arduino पहले से ही बड़े ईई समुदाय में एक बुरा प्रतिनिधि है क्योंकि समुदाय द्वारा किए गए औसत दर्जे के भयानक हार्डवेयर डिजाइन। क्या हमें किसी चीज़ के बारे में श * टी देने की कोशिश नहीं करनी चाहिए ?
इग्नासियो वाज़केज़-अब्राम्स

2
"अधिकांश परियोजनाओं में जीवन या वित्त का जोखिम शामिल नहीं है ..." कोई आश्चर्य की बात नहीं है। कौन Arduino शामिल करना चाहेगा, जहां बड़े पैमाने पर समुदाय को देखने के बाद जोखिम का कोई मौका है।
इग्नासियो वाज़क्वेज़-अब्राम्स

2
यह 'गलत' नहीं है क्योंकि यह एक विशेष स्थिति में काम नहीं करता है, लेकिन क्योंकि यह 'सही' करने की तुलना में, ऐसी अधिक परिस्थितियां हैं जिनमें यह काम नहीं करता है। यह कोड को नाजुक बनाता है; कोड में परिवर्तन रहस्यमय विफलताएं पैदा कर सकता है जो डीबगिंग समय को खाते हैं। कंपाइलर के प्रकार की जाँच और त्रुटि संदेश आपको पहले के बजाय उन प्रकार की त्रुटियों को पकड़ने में मदद करने के लिए हैं।
कर्ट जे। सैम्पसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.