লুপের বাইরে ভেরিয়েবল ঘোষণা করা এবং লুপের অভ্যন্তরে স্থির ঘোষণার মধ্যে পার্থক্য কী?


9

এই দুটি উপায় আমি লুপ (বা যে কোনও ফাংশন) এর বাইরে চলক ধরে রাখতে পারি।

প্রথমত, আমি লুপের বাইরে বৈশ্বিক সুযোগ নিয়ে এটি ঘোষণা করতে পারি:

void setup()
{
    Serial.begin(9600);
}

int count = 0;

void loop()
{
    Serial.println(count);
    count++;

    delay(250);
}

আমি এটিকে লুপের ভিতরে স্থির ঘোষণা করতে পারি:

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    static int count = 0;

    Serial.println(count);
    count++;

    delay(250);
}

কোন পার্থক্য, যদি কোন, এই কি করতে হবে?

উত্তর:


10

সর্বাধিক প্রাথমিক পার্থক্যটি সুযোগের।

প্রথম ক্ষেত্রে, আপনি একটি বৈশ্বিক চলক ঘোষণা করছেন। এটি একটি পরিবর্তনশীল যা এর সংজ্ঞা অনুসারে প্রতিটি স্কোপে অ্যাক্সেসযোগ্য।

void setup()
{
    Serial.begin(9600);
}

void inc();
int count = 0;

void loop()
{
    Serial.println(count);
    count++;

    inc();

    delay(500);
}

void inc() //Can edit the value of count
{
  count=count+1;
};

দ্বিতীয় ক্ষেত্রে, আপনি স্থানীয় সুযোগের সাথে একটি স্ট্যাটিক ভেরিয়েবল ঘোষণা করছেন। পুরো প্রোগ্রামটি বৈশ্বিক ভেরিয়েবলের মতো চলার জন্য চলকটি বহাল থাকবে, তবে এটি ঘোষিত কোড ব্লকটিতে কেবল অ্যাক্সেসযোগ্য হবে only এটি একই উদাহরণ, শুধুমাত্র একটি পরিবর্তন সহ। countএখন ভিতরে স্ট্যাটিক ভেরিয়েবল হিসাবে ঘোষিত হয়েছে loop

void inc();

void loop()
{
    static int count = 0;
    Serial.println(count);
    count++;

    inc();

    delay(500);
}

ফাংশনটির inc()অ্যাক্সেস না থাকায় এটি সংকলন করবে না count

গ্লোবাল ভেরিয়েবলগুলি যদিও আপাতদৃষ্টিতে কার্যকর, কিছু সমস্যা নিয়ে আসে। শারীরিক পারিপার্শ্বিকের সাথে ইন্টারঅ্যাক্ট করতে পারে এমন প্রোগ্রামগুলি লেখার ক্ষেত্রে এগুলি এমনকি ক্ষতির কারণ হতে পারে। প্রোগ্রামগুলির বৃহত্তর হওয়া শুরু হওয়ার সাথে সাথে এমন কিছু ঘটনার খুব সম্ভবত এটি একটি প্রাথমিক উদাহরণ। একটি ফাংশন অসাবধানতাবশত একটি বৈশ্বিক চলকের অবস্থার পরিবর্তন করতে পারে।

void setup()
{
    Serial.begin(9600);
}
void another_function();
int state=0;

void loop()
{
    //Keep toggling the state
    Serial.println(state);
    delay(250);
    state=state?0:1;

    //Some unrelated function call
    another_function();
}

void another_function()
{
  //Inadvertently changes state
  state=1;

}

এই ধরনের মামলাগুলি ডিবাগ করা খুব কঠিন। এই ধরণের সমস্যাটি কেবল স্ট্যাটিক ভেরিয়েবল ব্যবহার করে সহজেই সনাক্ত করা যায়।

void setup()
{
    Serial.begin(9600);
}
void another_function();

void loop()
{
    static int state=0;

    //Keep toggling the state
    Serial.println(state);
    delay(250);
    state=state?0:1;

    //Some unrelated function call
    another_function();
}

void another_function()
{
  //Results in a compile time error. Saves time.
  state=1;

}

5

কার্যকরী দৃষ্টিকোণ থেকে, উভয় সংস্করণ একই ফলাফল উত্পন্ন করে, যেহেতু উভয় ক্ষেত্রেই countএর মৃত্যুদন্ড কার্যকর করার মধ্যে এর মান সংরক্ষণ করা loop()হয় (হয় কারণ এটি একটি বিশ্বব্যাপী পরিবর্তনশীল বা এটি হিসাবে চিহ্নিত হয়েছে staticএবং তাই এর মান রাখে)।

সুতরাং যে সিদ্ধান্তটি বেছে নেবেন তা নিম্নলিখিত যুক্তিগুলিতে নেমে আসে:

  1. সাধারণত, কম্পিউটার বিজ্ঞানে, আপনার ক্ষেত্রগুলিকে সুযোগের ক্ষেত্রে যতটা সম্ভব স্থানীয় রাখতে উত্সাহ দেওয়া হয় । এটি সাধারণত কম পার্শ্ব-প্রতিক্রিয়া সহ অনেক স্পষ্ট কোডের ফলাফল দেয় এবং অন্য যে কেউ বৈশ্বিক পরিবর্তনশীল আপনার যুক্তি স্ক্রু ব্যবহার করে ব্যবহার করার সম্ভাবনা হ্রাস করে)। যেমন আপনার প্রথম উদাহরণে, অন্যান্য যুক্তিযুক্ত ক্ষেত্রগুলি countমান পরিবর্তন করতে পারে, অন্যদিকে, কেবলমাত্র সেই নির্দিষ্ট ফাংশনটি loop()এটি করতে পারে)।
  2. গ্লোবাল এবং স্ট্যাটিক ভেরিয়েবলগুলি সর্বদা স্মৃতি ধারণ করে , যেখানে স্থানীয় লোকেরা কেবল যখন তাদের ক্ষেত্রের মধ্যে থাকে তখনই ঘটে। আপনার উপরের উদাহরণগুলিতে কোনও পার্থক্য নেই (যেহেতু একটিতে আপনি বিশ্বব্যাপী ব্যবহার করেন, অন্যটিতে স্থিতিশীল পরিবর্তনশীল), তবে বৃহত্তর এবং আরও জটিল প্রোগ্রামগুলিতে এটি হতে পারে এবং আপনি অ স্থিতিশীল স্থানীয় ব্যবহার করে স্মৃতি সংরক্ষণ করতে পারেন। তবে : যদি আপনার প্রায়শই প্রায়শই কার্যকর করা হয় এমন যুক্তিযুক্ত অঞ্চলে কোনও পরিবর্তনশীল থাকে তবে এটি স্থিতিশীল বা বৈশ্বিক তৈরির বিষয়টি বিবেচনা করুন, অন্যথায় আপনি প্রতিবার যুক্তিযুক্ত অঞ্চলটি প্রবেশ করার সময় সামান্য কিছুটা পারফরম্যান্স আলগা করে ফেলেন, যেহেতু এতে কিছুটা সময় লাগে এই নতুন পরিবর্তনশীল উদাহরণের জন্য মেমরি বরাদ্দ করুন। আপনাকে মেমরি লোড এবং পারফরম্যান্সের মধ্যে ভারসাম্য খুঁজে নিতে হবে।
  3. স্থায়ী বিশ্লেষণের জন্য আরও ভাল বিন্যাস বা সংকলক দ্বারা অপ্টিমাইজেশনের মতো অন্যান্য পয়েন্টগুলিও কার্যকর হতে পারে।
  4. কিছু বিশেষ পরিস্থিতিতে, স্থিতিশীল উপাদানগুলির অবিশ্বাস্য সূচনা আদেশের সাথে সমস্যা থাকতে পারে (সেই পয়েন্ট সম্পর্কে নিশ্চিত নয়, যদিও এই লিঙ্কটি তুলনা করুন )।

উত্স: আরডুইনো.সি.সি. তে অনুরূপ থ্রেড


পুনরায় প্রবেশ করানো আরডুইনোতে কখনই সমস্যা হওয়া উচিত নয় কারণ এটি সম্মতি সমর্থন করে না।
পিটার ব্লুমফিল্ড 11

সত্য। এটি সাধারণ বিষয় ছিল বেশি, তবে আরডুইনোর পক্ষে আসলেই প্রাসঙ্গিক নয়। আমি কিছুটা সরিয়েছি।
ফিলিপ অলগায়ার

1
একটি সুযোগের ভিতরে ঘোষিত একটি স্ট্যাটিক ভেরিয়েবল সর্বদা উপস্থিত থাকবে এবং একই স্থানটি বিশ্বব্যাপী ভেরিয়েবল হিসাবে ব্যবহার করবে! ওপি কোডে, কেবলমাত্র তফাতটি হ'ল কোডটি ভেরিয়েবল অ্যাক্সেস করতে পারে। স্কাইপ স্থিরভাবে একই সুযোগের মধ্যে অ্যাক্সেসযোগ্য হবে।
jfpoil ব্যাখ্যা

1
@ jfpoil ব্যাখ্যা অবশ্যই এটি সত্য এবং আমি দেখতে পাচ্ছি যে আমার উত্তরের সংশ্লিষ্ট অংশটি কিছুটা বিভ্রান্তিকর ছিল। স্থির।
ফিলিপ অলগায়ার

2

উভয় ভেরিয়েবল স্থিতিশীল - তারা পুরো সম্পাদন সেশনের জন্য স্থির থাকে। গ্লোবাল কোনও ক্রিয়াকলাপের কাছে দৃশ্যমান যদি এটি ঘোষণা করে - সংজ্ঞায়িত করে না - গ্লোবাল, অথবা যদি ফাংশন একই সংকলন ইউনিটে সংজ্ঞাটি অনুসরণ করে (ফাইল + অন্তর্ভুক্ত)।

countউভয় একটি ফাংশনের অভ্যন্তরে সংজ্ঞা স্থানান্তর {}করাকে এএসের নিকটস্থ এনকোলেসিং সেটটিতে তার দৃশ্যমানতার পরিধি সীমাবদ্ধ করে এবং এটিকে ফাংশন প্রার্থনা আজীবন দেয় (ফাংশনটি প্রবেশ করা এবং বেরিয়ে আসার সাথে সাথে এটি তৈরি ও ধ্বংস হয়)। এটির staticপাশাপাশি এটি ঘোষণার ফলে এটি কার্যকর করা সেশনের আজীবন দেয় যা কার্য সম্পাদনের অনুরোধ জুড়ে অব্যাহতি রেখে কার্যকর করা অধিবেশনটির শুরু থেকে শেষ অবধি বিদ্যমান।

বিটিডাব্লু: কোনও ফাংশনের মধ্যে প্রাথমিক স্ট্যাটিক্স ব্যবহার সম্পর্কে সতর্ক থাকুন, কারণ আমি দেখেছি যে gnu সংকলকটির কয়েকটি সংস্করণ ভুল হয়ে গেছে। একটি ইনিশিয়ালাইজার সহ একটি স্বয়ংক্রিয় পরিবর্তনশীল তৈরি করতে হবে এবং প্রতিটি ফাংশন এন্ট্রিতে প্রাথমিক করা উচিত। প্রাথমিক () যেমন একটি গ্লোবাল হবে তেমন নিয়ন্ত্রণ প্রদানের আগে, এক্সিকিউশন সেটআপ চলাকালীন, একটি ইনিশিয়ালাইজার সহ একটি স্ট্যাটিক একবারই শুরু করা উচিত। আমার কাছে স্থানীয় স্ট্যাটিকগুলি প্রতিটি ফাংশন এন্ট্রিগুলিতে পুনরায় পুনর্নিযুক্ত করা হয়েছিল যেন সেগুলি অটোমেটিকস, যা ভুল। নিশ্চিত হওয়ার জন্য আপনার নিজের সংকলকটি পরীক্ষা করুন।


আমি নিশ্চিত নই যে গ্লোবাল ঘোষণা করার কোনও ফাংশন সম্পর্কে আপনি কী বোঝাতে চেয়েছিলেন আমি তা বুঝতে পেরেছি। আপনি একটি হিসাবে মানে extern?
পিটার ব্লুমফিল্ড

@ পিটারআর ব্লুমফিল্ড: আমার পোস্টের কোন অংশটি সম্পর্কে আপনি জিজ্ঞাসা করেছেন তা আমি নিশ্চিত নই, তবে আমি ওপি'র দুটি উদাহরণের কথা উল্লেখ করছিলাম - প্রথমটি, একটি স্বভাবগতভাবে বৈশ্বিক সংজ্ঞা এবং দ্বিতীয়টি, স্থানীয় স্থিতিশীল।
জে রবার্ট

-3

আটমেলের ডকুমেন্টেশন অনুসারে: "যদি কোনও বৈশ্বিক চলক ঘোষণা করা হয় তবে এসআরএমে একটি অনন্য ঠিকানা প্রোগ্রাম লিংক সময় এই চলকটির জন্য বরাদ্দ করা হবে।"

সম্পূর্ণ ডকুমেন্টেশনটি এখানে (গ্লোবাল ভেরিয়েবলের জন্য টিপ # 2): http://www.atmel.com/images/doc8453.pdf


4
দুটি উদাহরণই কি এসআরএমে কোনও অনন্য ঠিকানা দিয়ে শেষ হতে চলেছে না? তাদের উভয়ই জেদ করা দরকার।
সাইবার্বিবনস

2
হ্যাঁ বাস্তবে আপনি সেই তথ্যটি একই নথিতে টিপ # 6 এ সন্ধান করতে পারেন
jfpoil ব্যাখ্যা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.