লুপের জন্য কি বিভিন্ন ধরণের দুটি ভেরিয়েবল ঘোষণা করা সম্ভব?


240

সি ++ এ লুপের জন্য একটি প্রারম্ভিককরণের বডিটিতে বিভিন্ন ধরণের দুটি ভেরিয়েবল ঘোষণা করা সম্ভব?

উদাহরণ স্বরূপ:

for(int i=0,j=0 ...

দুটি পূর্ণসংখ্যা সংজ্ঞায়িত করে আমি কি সূচনা শরীরে একটি intএবং একটি সংজ্ঞা দিতে পারি char? কিভাবে এই কাজ করা হবে?


3
এটি g ++ - 4.4 ( -std=c++0x) আকারে for(auto i=0, j=0.0; ...সম্ভব, তবে এই সম্ভাবনাটি g ++ - 4.5 তে সরানো হয়েছে সি ++ 0x পাঠ্যের সাথে মিলে যাওয়ার জন্য।
রাফাক

উত্তর:


133

সি ++ 17 : হ্যাঁ! আপনার একটি কাঠামোগত বাধ্যবাধকতা ঘোষণা ব্যবহার করা উচিত । সিনট্যাক্সটি কয়েক বছর ধরে জিসিসি এবং জঞ্জাল (জিসিসি -7 এবং ঝনঝন -২.০) থেকে সমর্থিত হয়েছে ( ঝাঁকুনির সরাসরি উদাহরণ )। এটি আমাদেরকে এর মতো একটি টুপল আনপ্যাক করতে দেয়:

for (auto [i, f, s] = std::tuple{1, 1.0, std::string{"ab"}}; i < N; ++i, f += 1.5) {
    // ...
}

উপরেরটি আপনাকে দেবে:

  • int i সেট 1
  • double f সেট 1.0
  • std::string s সেট "ab"

#include <tuple>এই ধরণের ঘোষণার জন্য নিশ্চিত হন ।

আপনি টাইপটির সাথে সঠিক টাইপগুলি নির্দিষ্ট করে নির্দিষ্ট tupleকরে লিখতে পারেন যেমন আমার সাথে রয়েছে std::string, আপনি যদি কোনও প্রকারের নাম বলতে চান। উদাহরণ স্বরূপ:

auto [vec, i32] = std::tuple{std::vector<int>{3, 4, 5}, std::int32_t{12}}

এটির একটি নির্দিষ্ট অ্যাপ্লিকেশন হ'ল মানচিত্রের পুনরাবৃত্তি, কী এবং মান পাওয়া,

std::unordered_map<K, V> m = { /*...*/ };
for (auto& [key, value] : m) {
   // ...
}

এখানে একটি সরাসরি উদাহরণ দেখুন


সি ++ 14 : আপনি টাইপ-ভিত্তিক সংযোজন দিয়ে সি ++ 11 (নীচে) এর মতোই করতে পারেন std::get। সুতরাং std::get<0>(t)নীচের উদাহরণের পরিবর্তে , আপনি থাকতে পারেন std::get<int>(t)


সি ++ 11 : std::make_pairআপনাকে এটি করতে পাশাপাশি std::make_tupleদুটিরও বেশি অবজেক্টের জন্য অনুমতি দেয়।

for (auto p = std::make_pair(5, std::string("Hello World")); p.first < 10; ++p.first) {
    std::cout << p.second << std::endl;
}

std::make_pairএকটিতে দুটি যুক্তি ফিরিয়ে দেবে std::pair। উপাদানগুলির সাথে .firstএবং অ্যাক্সেস করা যায় .second

দুটিরও বেশি অবজেক্টের জন্য আপনাকে একটি ব্যবহার করতে হবে std::tuple

for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
        std::get<0>(t) < 10;
        ++std::get<0>(t)) {
    std::cout << std::get<1>(t) << std::endl; // cout Hello world
    std::get<2>(t).push_back(std::get<0>(t)); // add counter value to the vector
}

std::make_tupleহ'ল একটি বৈকল্পিক টেম্পলেট যা কোনও সংখ্যক যুক্তি (কোর্সের কিছু প্রযুক্তিগত সীমাবদ্ধতা সহ) এর একটি গঠন তৈরি করবে। উপাদানগুলি সূচক দ্বারা অ্যাক্সেস করা যেতে পারেstd::get<INDEX>(tuple_object)

লুপ জন্য মৃতদেহ মধ্যে আপনি যা করতে পারেন সহজে বস্তু ওরফে, আপনি কি এখনও ব্যবহার করতে হবে যদিও .firstবা std::getলুপ শর্ত এবং আপডেট অভিব্যক্তি জন্য

for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
        std::get<0>(t) < 10;
        ++std::get<0>(t)) {
    auto& i = std::get<0>(t);
    auto& s = std::get<1>(t);
    auto& v = std::get<2>(t);
    std::cout << s << std::endl; // cout Hello world
    v.push_back(i); // add counter value to the vector
}

সি ++ 98 এবং সি ++ 03 আপনি স্পষ্টভাবে a এর প্রকারের নাম বলতে পারেন std::pair। এটি দুটি ধরণের বেশি সাধারণ করার কোনও মানক উপায় নেই যদিও:

for (std::pair<int, std::string> p(5, "Hello World"); p.first < 10; ++p.first) {
    std::cout << p.second << std::endl;
}

5
আপনি যদি সি ++ 17 করছেন, আপনি এমনকি ড্রপ make_এবং লিখতে পারেন std::pair(1, 1.0)
মার্ক গ্লিস

লোমশ সি ++ 14 স্টাইলের টিপল / জুটির ব্যবসা - সব ভাল (সম্ভবত, উন্নত) তবে উদ্ভট
লাগছে

3
সংক্ষেপে: হ্যাঁ এটি সম্ভব, তবে সুন্দর হতে যাচ্ছে না।
কিছু প্রোগ্রামার

হ্যাঁ সুন্দর নয়, তবে এটি ডপ! একেবারে টিপল-ইশটি উপভোগ করেছেন। :) তবে সত্যিকার অর্থে এটি সি ++ এর লুপগুলির জন্য একটি অত্যন্ত অপ্রচলিত সিনট্যাকটিক মানের এবং
শেষমেশ গুগলড

@ অ্যাডারচক্স যদি আপনি আপনার ভুল বোঝাবুঝি পরিষ্কার করতে পারেন তবে আমি উত্তরটি আপডেট করতে পারি
রায়ান হেইনিং

276

না - তবে প্রযুক্তিগতভাবে একটি কাজের আশেপাশে রয়েছে (এটি বাধ্যতামূলক না হলে আমি আসলে এটি ব্যবহার করতাম না):

for(struct { int a; char b; } s = { 0, 'a' } ; s.a < 5 ; ++s.a) 
{
    std::cout << s.a << " " << s.b << std::endl;
}

3
এটি ভিএস ২০০৮-এ সংকলন করে না, তবে অনলাইনে
কমোউতে করে

7
@ জেআরএল: ওহ, ভিএস2005ও করে না। ভিসি ++ এ তবুও অন্য একটি না-মেনে চলার বৈশিষ্ট্য gu
জর্জি ফ্রিত্শে

3
আমি পার্ল সমতুল্য কাজ করেছি। যদিও আমি সি ++ তে কোড পর্যালোচনার মাধ্যমে এ জাতীয় কিছু ছিনিয়ে নেওয়ার চেষ্টা করিনি।
জন

21
সি ++ 11 দিয়ে আপনি ডিফল্ট মান ব্যবহার করে এই উদাহরণটি আরও ছোট করতে পারেনstruct { int a=0; char b='a'; } s;
রায়ান হেইনিং

1
এই উত্তরটি উত্তরের প্রয়োজনীয়তাগুলি পূরণ করে, তবে একটি পঠনযোগ্যতা পিওভির থেকে আমি @ এমকেকে পছন্দ করি। এর উত্তর। এমকে-র সমাধান এমনকি কোঁকড়ানো ধনুর্বন্ধনী সংযোজন যোগ করে স্কোপিংয়ের ঠিকানা দেয়।
ট্রেভর বয়ড স্মিথ

221

সম্ভব নয়, তবে আপনি এটি করতে পারেন:

float f;
int i;
for (i = 0,f = 0.0; i < 5; i++)
{
  //...
}

অথবা, স্পষ্টভাবে করার সুযোগ সীমিত fএবং iঅতিরিক্ত বন্ধনী ব্যবহার করছে:

{
    float f; 
    int i;
    for (i = 0,f = 0.0; i < 5; i++)
    {
       //...
    }
}

আমি জানি এটি একটি খুব পুরানো প্রশ্ন, তবে আপনি কী ব্যাখ্যা করতে পারেন কেন কেউ কেউ আপনার দ্বিতীয় উদাহরণের মতো এটির চারপাশের অতিরিক্ত বন্ধনী দিয়ে এটি করবে?
ফোরড

13
@ ফিফিজিস্ট স্পষ্টভাবে f এবং i এর ব্যাপ্তি সীমাবদ্ধ করতে কেবল কোডের এমন কিছু অংশে ব্যবহার করতে পারেন যেখানে তারা ব্যবহৃত হয়।
এমকে

1
@MK। ধন্যবাদ, এটাই আমার সন্দেহ হয়েছিল। আমি আপনার উত্তর সম্পাদনা করে তা ব্যাখ্যা করতে।
ফোরড

কেবল একটি প্রশ্ন: কেন এমন? : ও
রোহন-প্যাটেল

কারণ এটি 'int a = 0, b = 4' এর মতো কাজ করে, আমি ধরে নিই। বলা হচ্ছে, স্ক এবং স্কোপিং সম্ভবত কেবলমাত্র সেই নামগুলি পুনরায় ব্যবহার (যা একটি ন্যায্য কারণ) প্রতিরোধ করতে কার্যকর হবে তবে উত্পন্ন কোডটি সাধারণত আধুনিক সংকলকটিতে (একই ক্ষেত্রে) একই রকম হবে।
আসু

14

আপনি আদিতে একাধিক প্রকারের ঘোষণা করতে পারবেন না, তবে আপনি একাধিক প্রকারের EG নির্ধারণ করতে পারেন

{
   int i;
   char x;
   for(i = 0, x = 'p'; ...){
      ...
   }
}

এগুলি কেবল তাদের নিজস্ব স্কোপে ঘোষণা করুন।


3

আমি মনে করি সেরা পন্থা জিয়ান এর উত্তর

কিন্তু ...


# লুপের জন্য নেস্টেড

এই পদ্ধতির নোংরা, তবে এটি সমস্ত সংস্করণে সমাধান করতে পারে।

সুতরাং, আমি প্রায়শই ম্যাক্রো ফাংশনে এটি ব্যবহার করি।

for(int _int=0, /* make local variable */ \
    loopOnce=true; loopOnce==true; loopOnce=false)

    for(char _char=0; _char<3; _char++)
    {
        // do anything with
        // _int, _char
    }

অতিরিক্ত 1।

এটি ব্যবহার করা যেতে পারে declare local variablesএবং initialize global variables

float globalFloat;

for(int localInt=0, /* decalre local variable */ \
    _=1;_;_=0)

    for(globalFloat=2.f; localInt<3; localInt++) /* initialize global variable */
    {
        // do.
    }

অতিরিক্ত 2।

ভাল উদাহরণ: ম্যাক্রো ফাংশন সহ।

(যদি সেরা পদ্ধতির ব্যবহার করা না যায় কারণ এটি একটি লুপ-ম্যাক্রো)

#define for_two_decl(_decl_1, _decl_2, cond, incr) \
for(_decl_1, _=1;_;_=0)\
    for(_decl_2; (cond); (incr))


    for_two_decl(int i=0, char c=0, i<3, i++)
    {
        // your body with
        // i, c
    }

# যদি বিবৃতি কৌশল

if (A* a=nullptr);
else
    for(...) // a is visible

আপনি যদি আরম্ভ করতে চান 0বা nullptr, আপনি এই কৌশলটি ব্যবহার করতে পারেন।

তবে কঠোর পড়ার কারণে আমি এটির প্রস্তাব দিচ্ছি না

এবং এটি বাগের মতো মনে হচ্ছে।


কিছু লোক অন্যদের থেকে কীভাবে ভিন্ন চিন্তা করে তা আমাকে অবাক করে দেওয়া কখনই থামে না। আমি কখনও এই ধরনের বিজোড়তা সম্পর্কে চিন্তা করতে হবে না। আকর্ষণীয় ধারণা।
ডাঃ ব্যক্তি ব্যক্তি দ্বিতীয়

1

দেখুন " একটা লুপ দুই ধরনের ভেরিয়েবল সংজ্ঞায়িত করার জন্য একটি উপায় আছে কি? Loops জন্য পাখির একাধিক জড়িত অন্য উপায় জন্য"। জর্জের "স্ট্রাকট ট্রিক" এর অন্য উপকারের সুবিধাটি হ'ল এটি (1) আপনাকে স্থিতিশীল এবং অ-স্থিতিশীল স্থানীয় ভেরিয়েবলগুলির মিশ্রণ করতে দেয় এবং (2) এটি আপনাকে অনুলিপিযোগ্য ভেরিয়েবলগুলি রাখার অনুমতি দেয়। অবক্ষয়টি হ'ল এটি অনেক কম পাঠযোগ্য এবং কম দক্ষ হতে পারে।


-2

ম্যাক্রো সংজ্ঞা দিন:

#define FOR( typeX,x,valueX,  typeY,y,valueY,  condition, increments) typeX x; typeY y; for(x=valueX,y=valueY;condition;increments)

FOR(int,i,0,  int,f,0.0,  i < 5, i++)
{
  //...
}

কেবল মনে রাখবেন, আপনার পরিবর্তনশীল স্কোপগুলি এইভাবে লুপের মধ্যে থাকবে না।


আপনি সহজেই ব্যবহার করে একটি পৃথক সুযোগ ম্যাক্রো কোড মোড়কে যে সীমাবদ্ধতা কাটিয়ে পারে {এবং }
নাথান ওসমান

4
না সে পারল না। তার ম্যাক্রো লুপের দেহটি মোড়ায় না। তিনি অতিরিক্ত খোলার ব্র্যাকেট যুক্ত করতে পারতেন, তবে ম্যাক্রো ব্যবহার করার জন্য এটি "অতিরিক্ত" বন্ধকরণ বন্ধনী প্রয়োজন।
জন

3
এটি একটি আকর্ষণীয় ধারণা, তবে আমি এটি বিবেচনা করার আগে খুব শীঘ্রই অন্য যে কোনও উত্তর ব্যবহার করব।
গ্রেগন 3

-2

এছাড়াও আপনি সি ++ তে নীচের মত ব্যবহার করতে পারেন।

int j=3;
int i=2;
for (; i<n && j<n ; j=j+2, i=i+2){
  // your code
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.