Ist es möglich, zwei Variablen unterschiedlichen Typs in einer for-Schleife zu deklarieren?

Lesezeit: 7 Minuten

Ist es moglich zwei Variablen unterschiedlichen Typs in einer for Schleife
Nathan Osmann

Ist es möglich, zwei Variablen unterschiedlichen Typs im Initialisierungskörper einer for-Schleife in C++ zu deklarieren?

Zum Beispiel:

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

definiert zwei ganze Zahlen. Kann ich ein definieren int und ein char im Initialisierungskörper? Wie würde dies geschehen?

  • Es ist möglich in g++-4.4 (-std=c++0x) in Form von for(auto i=0, j=0.0; ...aber diese Möglichkeit wurde in g++-4.5 entfernt, um mit den c++0x-Texten übereinzustimmen.

    – Rafak

    9. Mai 2010 um 11:11 Uhr


  • Da diese Frage für viele zuerst auftaucht, die beabsichtigen, nach derselben Frage in C zu suchen, ist hier das C-Äquivalent.

    – RobertS unterstützt Monica Cellio

    25. Juli 2020 um 17:10 Uhr


  • Hinweis für mich selbst: Lesen Sie stackoverflow.com/a/2687427/5290519.

    – Regen

    20. Februar 2021 um 9:51 Uhr

Nein – aber technisch gesehen gibt es eine Problemumgehung (nicht, dass ich sie tatsächlich verwenden würde, wenn ich nicht dazu gezwungen wäre):

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

  • Mit c++11 I können Sie dieses Beispiel mit Standardwerten verkürzen struct { int a=0; char b='a'; } s;

    – Ryan Haining

    27. Juli 2015 um 6:26 Uhr

  • @TrevorBoydSmith: Das ist so hässlich, Variablen streuen herum.

    – Regen

    20. Februar 2021 um 7:45 Uhr

  • Danke dafür. Ich saß nur hier und lachte wahnsinnig über mich selbst: for(struct { std::vector<float>::iterator it; size_t count; } v { vec.begin(), 1 }; v.it < vec.end(); ++v.it, ++v.count) { ... }

    – Adfriedmann

    23. Februar 2021 um 7:25 Uhr

Ist es moglich zwei Variablen unterschiedlichen Typs in einer for Schleife
MK.

Nicht möglich, aber Sie können Folgendes tun:

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

Oder schränken Sie den Umfang von explizit ein f und i Verwendung zusätzlicher Klammern:

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

  • Ich weiß, dass dies eine sehr alte Frage ist, aber können Sie erklären, warum einige es mit den zusätzlichen Klammern tun würden, wie in Ihrem zweiten Beispiel?

    – Furt

    15. März 2013 um 19:32 Uhr

  • @fizzisist, um den Geltungsbereich von f und i explizit nur auf Teile des Codes zu beschränken, in denen sie verwendet werden.

    – MK.

    15. März 2013 um 20:15 Uhr

  • @ MK. Danke, das hatte ich vermutet. Ich habe Ihre Antwort bearbeitet, um das zu erklären.

    – Furt

    16. März 2013 um 15:58 Uhr

  • Nur eine Frage: Warum so? :Ö

    – rohan-patel

    5. Oktober 2013 um 6:46 Uhr

  • Weil es wie ‘int a = 0, b = 4’ funktioniert, nehme ich an. Abgesehen davon ist das Scoping von f und i wahrscheinlich nur nützlich, um die Wiederverwendung dieser Namen zu verhindern (was ein triftiger Grund ist), aber der generierte Code ist auf einem modernen Compiler (in diesem Fall) normalerweise derselbe.

    – Asu

    2. Oktober 2016 um 13:02 Uhr

Ist es moglich zwei Variablen unterschiedlichen Typs in einer for Schleife
Ryan Haining

C++17: Jawohl! Sie sollten eine verwenden strukturierte verbindliche Erklärung. Die Syntax wird in gcc und clang seit gcc-7 und clang-4.0 unterstützt (Clang-Live-Beispiel). Dies ermöglicht uns, ein Tupel wie folgt zu entpacken:

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

Das Obige gibt Ihnen:

  • int i einstellen 1
  • double f einstellen 1.0
  • std::string s einstellen "ab"

Stellen Sie sicher, dass #include <tuple> für diese Art von Erklärung.

Sie können die genauen Typen innerhalb der angeben tuple indem ich sie alle austippe, wie ich es mit dem gemacht habe std::string, wenn Sie einen Typ benennen möchten. Zum Beispiel:

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

Eine spezifische Anwendung davon ist das Iterieren über eine Karte, um den Schlüssel und den Wert zu erhalten,

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

Sehen Sie sich ein Live-Beispiel an Hier


C++14: Sie können dasselbe wie C++11 (unten) tun, indem Sie typbasiert hinzufügen std::get. Also statt std::get<0>


C++11: std::make_pair ermöglicht Ihnen dies zu tun, sowie std::make_tuple für mehr als zwei Objekte.

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

std::make_pair gibt die beiden Argumente in a zurück std::pair. Auf die Elemente kann mit zugegriffen werden .first und .second.

Für mehr als zwei Objekte müssen Sie a verwenden std::tuple

for (auto t = std::make_tuple(0, std::string("Hello world"), std::vector<int>{});
        std::get<0>
        ++std::get<0>
    std::cout << std::get<1>
    std::get<2>
}

std::make_tuple ist eine variadische Vorlage, die ein Tupel aus einer beliebigen Anzahl von Argumenten erstellt (natürlich mit einigen technischen Einschränkungen). Auf die Elemente kann per Index mit zugegriffen werden std::get<INDEX>(tuple_object)

Innerhalb der for-Schleifenkörper können Sie die Objekte leicht mit Aliasnamen versehen, obwohl Sie immer noch verwenden müssen .first oder std::get für die Bedingung der for-Schleife und den Update-Ausdruck

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

C++98 und C++03 Sie können die Typen von a explizit benennen std::pair. Es gibt jedoch keine Standardmethode, um dies auf mehr als zwei Typen zu verallgemeinern:

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

  • Wenn Sie mit C++17 arbeiten, können Sie sogar die make_ und schreibe std::pair(1, 1.0).

    – Marc Glisse

    12. Oktober 2016 um 22:46 Uhr

  • Das haarige Tupel/Paar-Geschäft im C++14-Stil – alles gut (wahrscheinlich positiv bewertet), sieht aber bizarr aus 🙂

    – mlvljr

    5. Juli 2017 um 11:14 Uhr

  • Kurz gesagt: Ja, es ist möglich, aber es wird nicht schön.

    – Irgendein Programmierer-Typ

    10. Dezember 2019 um 14:28 Uhr

Sie können bei der Initialisierung nicht mehrere Typen deklarieren, aber Sie können mehreren Typen EG zuweisen

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

Deklarieren Sie sie einfach in ihrem eigenen Bereich.

1646897411 46 Ist es moglich zwei Variablen unterschiedlichen Typs in einer for Schleife
mgkation

Ich denke, der beste Ansatz ist xians Antwort.

aber...


# Verschachtelte for-Schleife

Dieser Ansatz ist schmutzig, kann aber in jeder Version gelöst werden.

Daher verwende ich es oft in Makrofunktionen.

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
    }

Zusätzlich 1.

Es kann auch verwendet werden declare local variables und 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.
    }

Zusätzlich 2.

Gutes Beispiel: mit Makrofunktion.

(Wenn der beste Ansatz nicht verwendet werden kann, da es sich um ein For-Loop-Makro handelt)

#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
    }

# Trick mit If-Anweisungen

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

Wenn Sie initialisieren möchten 0 oder nullptrkönnen Sie diesen Trick anwenden.

aber ich empfehle das nicht wegen der harten Lektüre.

und es scheint wie ein Fehler.

  • Beachten Sie, dass "Break" und "Continue" hier nicht wie erwartet funktionieren.

    – Michael

    14. November 2020 um 1:17 Uhr

  • @ Michael: Warum? Würde man das Innerste nicht fortsetzen for in allen Beispielen?

    – Regen

    20. Februar 2021 um 8:45 Uhr

  • Es gibt auch: for(int i = 0; i < whatever; i++) if (A & a = get_a(i)) das geht nicht kaputt break und continue und ist durchsichtig. Der Nachteil ist, dass A einen expliziten Operator bool implementieren muss, der true zurückgibt.

    – xryl669

    13. April 2021 um 17:46 Uhr

1646897412 579 Ist es moglich zwei Variablen unterschiedlichen Typs in einer for Schleife
Gemeinschaft

Siehe "Gibt es eine Möglichkeit, Variablen zweier Typen in einer For-Schleife zu definieren?" für eine andere Möglichkeit, mehrere for-Schleifen zu verschachteln. Der Vorteil des anderen Weges gegenüber Georgs "Struct-Trick" besteht darin, dass er (1) Ihnen erlaubt, eine Mischung aus statischen und nicht statischen lokalen Variablen zu haben, und (2) Ihnen erlaubt, nicht kopierbare Variablen zu haben. Der Nachteil ist, dass es weit weniger lesbar ist und möglicherweise weniger effizient ist.

  • Beachten Sie, dass "Break" und "Continue" hier nicht wie erwartet funktionieren.

    – Michael

    14. November 2020 um 1:17 Uhr

  • @ Michael: Warum? Würde man das Innerste nicht fortsetzen for in allen Beispielen?

    – Regen

    20. Februar 2021 um 8:45 Uhr

  • Es gibt auch: for(int i = 0; i < whatever; i++) if (A & a = get_a(i)) das geht nicht kaputt break und continue und ist durchsichtig. Der Nachteil ist, dass A einen expliziten Operator bool implementieren muss, der true zurückgibt.

    – xryl669

    13. April 2021 um 17:46 Uhr

1646897413 375 Ist es moglich zwei Variablen unterschiedlichen Typs in einer for Schleife
Loyola

Sie könnten auch wie unten in C++ verwenden.

int j=3;
int i=2;
for (; i<n && j<n ; j=j+2, i=i+2){
  // your code
}

986880cookie-checkIst es möglich, zwei Variablen unterschiedlichen Typs in einer for-Schleife zu deklarieren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy