কেস স্টেটমেন্টে {Using ব্যবহার করা হচ্ছে। কেন?


101

ব্যবহার করে {এবং }এ-তে কী লাভ?case বিবৃতি ? সাধারণত, caseবিবৃতিতে যতগুলি লাইন রয়েছে তা বিবেচনা না করেই সমস্ত লাইন কার্যকর করা হয়। এটি কি কেবল পুরানো / নতুন সংকলক সম্পর্কিত একটি নিয়ম বা এর পিছনে কিছু আছে?

int a = 0;
switch (a) {
  case 0:{
    std::cout << "line1\n";
    std::cout << "line2\n";
    break;
  }
}

এবং

int a = 0;
switch (a) {
  case 0:
    std::cout << "line1\n";
    std::cout << "line2\n";
    break;
}

57
কেস স্টেটমেন্টে ঘোষিত ভেরিয়েবলের পরিধি সীমাবদ্ধ করার জন্য একটি ব্যবহার হতে পারে।
অভিষেক বানসাল


1
খুব বেশি ইনডেন্টেশনও। কেসগুলি কেবল স্যুইচ স্টেটমেন্টের ব্লকের মধ্যে লেবেল: এগুলি অতিরিক্ত বাসা বাঁধার জন্য প্রবর্তন করে না, তাই তাদের switchকীওয়ার্ডের সাথে প্রান্তিককরণ করা উচিত এবং দ্বিতীয় উদাহরণে, বদ্ধ বিবৃতিগুলি কেবল একবার যুক্ত হয়েছে ented আপনার পরে কীভাবে একটি বিশ্রী চারটি স্পেস ডি-ইনডেন্ট রয়েছে তা নোট করুন break;
কাজ

দ্রষ্টব্য, জ্যাকের মন্তব্যটি উল্লেখ করেছে এবং গ্রহণযোগ্য উত্তরগুলি কেবলমাত্র আংশিকভাবে সঠিক কারণটি আমার উত্তরটিতে আমি সম্বোধন করেছি which
শফিক ইয়াঘমোর

ঠিক একটি এফওয়াইআই হিসাবে: সি (এমনকি সি 11) সি ++ এর পরিবর্তে, আপনি কোনও ঘোষণার লেবেল করতে পারবেন না; তারা সিনট্যাকটিক বিভাগে নেই statement। C ++, আপনি করতে পারেন (অন্বিত বিষয়শ্রেণীতে এক উপাদান statementহল declaration statement)।
জোনাথন লেফলার

উত্তর:


195

{}একটি নতুন ব্লক উল্লেখ করে সুযোগ

নিম্নলিখিত খুব স্বীকৃত উদাহরণ বিবেচনা করুন:

switch (a)
{
    case 42:
        int x = GetSomeValue();
        return a * x;
    case 1337:
        int x = GetSomeOtherValue(); //ERROR
        return a * x;
}

আপনি একটি সংকলক ত্রুটি পাবেন কারণ x ইতিমধ্যে সুযোগে সংজ্ঞায়িত।

এগুলিকে তাদের নিজস্ব উপ-স্কোপে পৃথক করা xস্যুইচ স্টেটমেন্টের বাইরে ঘোষণা করার প্রয়োজনীয়তা দূর করবে ।

switch (a)
{
    case 42: {
        int x = GetSomeValue();
        return a * x; 
    }
    case 1337: {
        int x = GetSomeOtherValue(); //OK
        return a * x; 
    }
}

11
প্রকৃতপক্ষে আইএমও আপনি ভেরিয়েবল এক্সের দ্বিতীয় ঘোষণাটি এড়িয়ে গেলেও আপনি একটি সংকলক ত্রুটি পাবেন।
অভিষেক বনসাল

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

2
@MatthieuM। আমি জানি যে এমএস ভিজ্যুয়াল স্টুডিও ২০১০-এর আচরণটি অভিষেকের ইঙ্গিত দেবে: এটি কোনও মামলার অভ্যন্তরে কোনও পরিবর্তনশীল ঘোষণা সংকলন করবে না (যদি না আপনি এই ক্ষেত্রে নতুন স্কোপ বোঝাতে কোঁকড়া বন্ধনী ব্যবহার করেন)। এটি মানগুলির সাথে মেলে কিনা, আমি জানি না।
কেআরয়ান

1
@ কেআরয়ান: এটি তা নয়, তবে এটি এত বেশি নিরাপদ বিকল্প যে এটি কার্যকর করার জন্য আমি তাদের খুব কমই দোষ দিতে পারি।
ম্যাথিউ এম।

6
স্ট্যান্ডার্ডের 7.7 (3) (২০০৫ খসড়ার জন্য সংখ্যায়ন) নির্দিষ্ট করে যে আপনি একটি সূচনাটি লাফাতে পারবেন না, তাই কোনও কেস ব্লকে আপনার আরম্ভ হতে পারে না।
জ্যাক এইডলি

23

টি এল; ডিআর

একমাত্র উপায় আপনি একটি intializer বা ভিতরে কিছু অ তুচ্ছ বস্তুর সঙ্গে একটি ভেরিয়েবল ডিক্লেয়ার করতে পারেন যদি একটি পরিচয় করিয়ে দিতে হয় ব্লক সুযোগ ব্যবহার {}বা অন্যান্য নিয়ন্ত্রণ কাঠামো যে এটি একটি মত নিজের সুযোগ আছে হয়েছে লুপ বা বিবৃতি যদি

গোরীর বিবরণ

আমরা দেখতে পারি যে ক্ষেত্রে শুধু হয় লেবেল বিবৃতি মত লেবেল একটি সঙ্গে ব্যবহার এতে যান বিবৃতি ( এই আচ্ছাদিত করা হয় C ++ স্ট্যান্ডার্ডের খসড়ার অধ্যায় 6.1 লেবেলযুক্ত বিবৃতি ) এবং আমরা অধ্যায় থেকে দেখতে পারেন 6.7অনুচ্ছেদ 3 যে জাম্পিং ঘোষণা পাস অনেক ক্ষেত্রে অনুমোদিত নয় যার সাথে একটি সূচনা সহ:

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

এবং এই উদাহরণ সরবরাহ করে:

void f() {
 // ...
 goto lx; // ill-formed: jump into scope of a

 ly:
  X a = 1;
 // ...
 lx:
  goto ly; // OK, jump implies destructor
          // call for a followed by construction
          // again immediately following label ly
}

দ্রষ্টব্য, এখানে কিছু সূক্ষ্মতা রয়েছে, আপনাকে কোনও স্কেলার ঘোষণাপত্রের বাইরে যাওয়ার অনুমতি দেওয়া হয়েছে যার কোনও সূচনা নেই, উদাহরণস্বরূপ:

switch( n ) 
{
    int x ;
    //int x  = 10 ; 
    case 0:
      x = 0 ;
      break;
    case 1:
      x = 1 ;
      break;
    default:
      x = 100 ;
      break ;
}

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

অতীতে আরম্ভের অনুমতি না দেওয়ার যৌক্তিক হিসাবে, ত্রুটি প্রতিবেদন 467 যদিও কিছুটা ভিন্ন ইস্যুটি আচ্ছাদন স্বয়ংক্রিয় চলকগুলির জন্য একটি যুক্তিসঙ্গত কেস সরবরাহ করে :

[...] স্বয়ংক্রিয় ভেরিয়েবলগুলি, যদি সুস্পষ্টভাবে আরম্ভ করা না হয় তবে ফাঁদগুলির উপস্থাপনা সহ অনির্দিষ্ট ("আবর্জনা") মান থাকতে পারে, [...]

আপনি একাধিক মামলার উপর স্যুইচের মধ্যে একটি ক্ষেত্র প্রসারিত করেন এমন ক্ষেত্রে সম্ভবত এটি আরও আকর্ষণীয় হবে যার সর্বাধিক বিখ্যাত উদাহরণ সম্ভবত ডাফের ডিভাইস যা দেখতে এরকম কিছু দেখাবে:

void send( int *to, const int *from, int  count)
{
        int n = (count + 7) / 8;
        switch(count % 8) 
        {
            case 0: do {    *to = *from++;   // <- Scope start
            case 7:         *to = *from++;
            case 6:         *to = *from++;
            case 5:         *to = *from++;
            case 4:         *to = *from++;
            case 3:         *to = *from++;
            case 2:         *to = *from++;
            case 1:         *to = *from++;
                        } while(--n > 0);    // <- Scope end
        }
}

6

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


4

এটি একটি প্রাথমিক সংকলক বিধিনিষেধ পরীক্ষা করুন এবং আপনি কী ঘটছে তা ভাবতে শুরু করবেন:

int c;
c=1;

switch(c)
{
    case 1:
    //{
        int *i = new int;
        *i =1;
        cout<<*i;
        break;
    //}

    default : cout<<"def";
}

এটি আপনাকে একটি ত্রুটি দেবে:

error: jump to case label [-fpermissive]
error:   crosses initialization of int* i

যদিও এটি এক করবে না:

int c;
c=1;

switch(c)
{
    case 1:
    {
        int *i = new int;
        *i =1;
        cout<<*i;
        break;
    }

    default : cout<<"def";
}

1

সুইচে ব্র্যাকেট ব্যবহার করা রোটেমের কথা অনুসারে স্কোপের একটি নতুন ব্লককে বোঝায়।

আপনি যখন পড়বেন তবে এটি পরিষ্কারতার জন্যও হতে পারে। কেসটি কোথায় থামছে তা জানতে আপনার এতে শর্তযুক্ত বিরতি থাকতে পারে।


0

কারণগুলি হতে পারে:

  1. পঠনযোগ্যতা, এটি প্রতিটি কেসকে স্কোপযুক্ত বিভাগ হিসাবে দৃষ্টিশক্তিভাবে বাড়িয়ে তোলে।
  2. বেশ কয়েকটি স্যুইচ মামলার জন্য একই নামের সাথে একটি ভিন্ন ভেরিয়েবল ঘোষণা করা।
  3. মাইক্রো অপ্টিমাইজেশান- সত্যিকারের ব্যয়বহুল সংস্থার বরাদ্দকৃত ভেরিয়েবলের সুযোগ যা আপনি কেসটির সুযোগ ছাড়ার সাথে সাথে ধ্বংস করতে চান বা "জিওটিও" কমান্ড ব্যবহারের আরও স্প্যাগেটি দৃশ্য scenario
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.