Hilfe bei Beispiel

yax

Erfahrenes Mitglied
Heey :),

also ich lerne jetzt schon seit einer etwas längeren Zeit C, doch nun war in dem Buch "C/C++ Das Umfassende Lehrbuch" ein Beispiel, dass ich trotz erklärung garnicht verstanden habe :confused::confused:

Deshalb hoffe ich, das jemand vielleicht so nett wäre, und mir helfen könnte :)

Hier ist das Programm:
Code:
# include <stdio.h>
# include <stdlib.h>

/*
** Schaltung (Kap. 5.6.2)
*/

main()
    {
    int s1, s2, s3, s4, s5, s6, s7;
    int lampe;
    
    printf( "s1 s2 s3 s4 s5 s6 s7\n");
    for( s1 = 0; s1 <= 1; s1 = s1 + 1)
      {
      for( s2 = 0; s2 <= 1; s2 = s2 + 1)
        {
        for( s3 = 0; s3 <= 1; s3 = s3 + 1)
          {
          for( s4 = 0; s4 <= 1; s4 = s4 + 1)
            {
            for( s5 = 0; s5 <= 1; s5 = s5 + 1)
              {
              for( s6 = 0; s6 <= 1; s6 = s6 + 1)
                {
                for( s7 = 0; s7 <= 1; s7 = s7 + 1)
                  {
                  lampe = (s1||s2)&&((s3&&s4)||((s5||s6)&&s7));
                  if( lampe == 1)
                      printf( " %d  %d  %d  %d  %d  %d  %d\n",
                                      s1, s2, s3, s4, s5, s6, s7);
                  }
                }
              }
            }
          }
        }
      }
    getc(stdin);
    }

Grüße yax. :)
 
Hi

was genau verstehst du daran nicht?

Die Schleifen zählen jeweils 0 und 1.
Das Innerste der Schleifen wird daher für jede Mögliche Kombination von 7 Nullern bzw. Einsern (s1-s7) ausgeführt.

Im Innersten wird in lampe das Ergebnis von (s1||s2)&&((s3&&s4)||((s5||s6)&&s7)) gespeichert.
Ein Einser steht dabei für Wahr, 0 für Falsch.
Wenn das Gesamte Wahr ergibt, wird entsprechend 1 in lampe gespeichert, sonst 0.

Und wenn jetzt 1 herausgekommen ist, werden die Einser/Nuller aus s1 bis s7 ausgegeben.
Mit anderen Worten: Du bekommst alle Bitkombinationen, für die die Bedingung von lampe Wahr ist.

Gruß
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: yax
Okay, danke für die Antwort. Und tut mir leid das ich erst so spät antworte :)

Also wird bei lampe getestet ob s1 oder s2 gleich 1 ist, und ob s3 und s4, oder ob s5 oder s6 gleich 1 ist, und ob s7 gleich 1 ist, oder****

Als ich mir das vorher immer durchgelesen habe, haben mich die vielen Schleifen total durcheinander gebracht, aber ich glaube ich habe das jetzt verstanden.

Danke :)
 
Also ich finde das Beispiel mit den 7 verschachtelten for-Schleifen schon sehr sperrig. Mit zum Beispiel einem Bitfeld und nur einer for-Schleife wird's doch deutlich übersichtlicher:
C++:
# include <stdio.h>
# include <stdlib.h>
 
int main()
{
   union
    {
        unsigned char value;
        struct
        {
            unsigned char S1 : 1;
            unsigned char S2 : 1;
            unsigned char S3 : 1;
            unsigned char S4 : 1;
            unsigned char S5 : 1;
            unsigned char S6 : 1;
            unsigned char S7 : 1;
        } e;
    } s;
    
    bool lampe;
    
    for( s.value = 0;
         s.value < (1 << 7) /* Anzahl Kombinationen + 1 bei 7 Schaltern */ ;
         ++s.value )
    {
        lampe = (s.e.S1 || s.e.S2) && ((s.e.S3 && s.e.S4) || ((s.e.S5 || s.e.S6) && s.e.S7));
        
        if( lampe )
        {
            printf( "%d  %d  %d  %d  %d  %d  %d\n",
                    s.e.S1, s.e.S2, s.e.S3, s.e.S4, s.e.S5, s.e.S6, s.e.S7);
        }
    }
        
    return 0;
}
Gruß
MCoder
 
Aha... :D

@MCoder: also, das Beisiel war ja aus einem Buch, und außerdem weiß ich noch nicht wirklich etwas über unions. Und ich finde das gesmate Programm ist etwas kompliziert :)
 
Eine union ist prnzipell eine struct, aber:
Jeder Member besetzt den gleichen Speicher. Nur unterschiedliche Variablentypen.

zB ein struct mit einem int i und einem float b in Byte im Arbeitsspeicher:
i1 i2 i3 i4 f1 f2 f3 f4

Union:
i1 i2 i3 i4
f1 f2 f3 f4

Hier belegen die Variablen den gleichen Speicher, nur einmal greifst du darauf als int zu und einmal als float.
Wenn du das float änderst, ändert sich dann natürlich auch der int-Wert usw...

MCoder hat dann eine union mit
1)einem unsigned char von 0 bis 255 = 8 bit
2)Einer struct mit 7 einzelnen Bit hintereinander

c1 c2 c3 c4 c5 c6 c7 c8
b1 b2 b3 b4 b5 b6 b7

Das achte bit vom char ist unwichtig.

Gruß

PS: Das hats jetzt ziemlich verschoben...hoffentlich weißt du trotzdem, was ich meine.
 
Zuletzt bearbeitet:
Hallo yax,

sorry, wenn ich dich verwirrt habe.
Ich fand das Programm auch etwas kompliziert, da hat's mir in den Fingern gejuckt :D

Noch eine kleine Ergänzung zu sheels Erklärung:
Bei 7 Schaltern gibt es (2**7 - 1) Kombinationen. Die Potenz 2**7 läßt sich einfach mit einer Bitverschiebung berechnen:
Code:
(1 << 7)
Um alle Kombinationen durchzuzählen braucht's eigentlich nur eine Schleife. Durch die Kombination der Schleifenvariable 'value' mit einem Bitfeld 'e' in einer union wird das Bitmuster der Schleifenvariablen automatisch auch auf die einzelnen Member des Bitfeldes abgebildet. Diese wiederum stellen die Position (0 = aus, 1 = ein) der einzelnen Schalter direkt dar.

Gruß
MCoder
 
Hallo,

ich habe noch eine Alternative im Angebot, für die man allerdings Rekursion und Arrays kennen sollte:
C:
#include <stdio.h>

void eval(int *s) {
  int i;
  int lampe = (s[0]||s[1])&&((s[2]&&s[3])||((s[4]||s[5])&&s[6]));
  if (lampe) {
    for (i = 0; i < 7; ++i) printf("  %d", s[i]);
    printf("\n");
  }
}

void combinations(int *s, int i, int n) {
  if (i >= n) {
    eval(s);
  } else {
    s[i] = 0;
    combinations(s, i+1, n);
    s[i] = 1;
    combinations(s, i+1, n);
  }
}

int main() {
  int s[7];
  combinations(s, 0, 7);
  return 0;
}
Damit ist man denke ich am flexibelsten, was eine Veränderung der Lampenanzahl angeht.

Grüße,
Matthias
 
Zurück