Forum: Compiler & IDEs Lauflicht in C


von Walter (Gast)


Lesenswert?

Guten Abend.

Mache gerade meine ersten Versuche mit C. Ich probiere jetzt schon ne 
ganze Zeit herum, ein Lauflicht auf Portb auszugeben (nur im AVR 
Studio,--> daher kein delay),aber ich kann den Fehler nicht entdecken.

Könnte mal jemand kurz draufschauen?

#include <avr/io.h>

int main (void)

 {
  int x,y;

   DDRB  = 0b11111111;
   PORTB = 0b00000000;
loop1:
     x = 7;y=1;
 {
      while (x >= 0)
      {
          PORTB = y;
        y=y*2;
          x--;
    }
  {
  x = 7;y=64;
    while (x >= 0)
        PORTB = y;
        y=y/2;
        x--;
      }}
  goto loop1;
   return 0;
}


Also die erste while Schleife funktioniert ja noch, aber bei der zweiten 
da bleibt er dann hängen. Was mach ich da falsch? Kann das daran liegen, 
das man zu viele geschwungene Klammern hat?

Gruß Walter

von uwegw (Gast)


Lesenswert?

Rück das Zeug mal vernünftig ein, dann wirst du schon bemerkren, wo da 
die geschweiften Klammern falsch sitzen.

von Walter (Gast)


Lesenswert?

Habs jetzt mal so gemacht, geht aber doch noch nicht. Ist da wirklich ne 
Klammer schuld, oder was anderes?



#include <avr/io.h>

int main (void)

 {
    int x,y;

     DDRB  = 0b11111111;
     PORTB = 0b00000000;
loop1:
  {
     x = 7;y=1;
     {
        while (x >= 0)
      {
            PORTB = y;
          y=y*2;
            x--;
      }
      }
  x = 7;y=64;
    {
      {
      while (x >= 0)
        PORTB = y;
        y=y/2;
        x--;
      }
    }
  }
  goto loop1;
   return 0;
}

von guro (Gast)


Lesenswert?

Walter schrieb:
--------------------
while (x >= 0)
        PORTB = y;
--------------------

wird da irgendwo 'x' verändert?
schätze, du musst noch mal ein c-tutorial durcharbeiten.

von Walter (Gast)


Lesenswert?

Habs jetzt geschafft. Falls ein Anfänger es brauchen kann, hier mein 
Anfänger Code:

#include <avr/io.h>

int main (void)

{
    int x,y;

     DDRB  = 0b11111111;
     PORTB = 0b00000000;
loop1:
  {
     x = 7;y=1;
     {
        while (x >= 0)
       {
            PORTB = y;
          y=y*2;
            x--;
      }
    }


  x = 5;y=64;
    {
      while (x >= 0)
      {
          PORTB = y;
          y=y/2;
          x--;
      }
    }
  }
  goto loop1;
   return 0;
}


Danke für Eure Antworten.

Gruß Walter

von Walter (Gast)


Lesenswert?

Wow, das geht auch mit weniger Klammern...
#include <avr/io.h>

int main (void)

{
    int x,y;
     DDRB  = 0b11111111;
     PORTB = 0b00000000;

loop1:

     x = 7;y=1;
      while (x >= 0)
       {
            PORTB = y;
          y=y*2;
            x--;
      }

   x = 5;y=64;
    while (x >= 0)
      {
          PORTB = y;
          y=y/2;
          x--;
      }

   goto loop1;
return 0;
}

von Thomas^ (Gast)


Lesenswert?

Die Anfänger sollten das:

> loop1:
> {
> ...
> }
> goto loop1;

am Besten durch ein

for (;;)
{
...
}

ersetzen.
In meinem C-Buch wird ein goto auch nur ganz zum Ende erwähnt.

von Michael (Gast)


Lesenswert?

oder durch ein

do{
.
.
.
}while(1);

Da mit goto ein komplexeres Orogramm sehr unübersichtlich wird!
Habe für ein goto eine auf den Deckel bekommen von meinem Prof!!!

von Thomas^ (Gast)


Lesenswert?

Es gibt Fälle wo ein goto sicher sinnvoll oder einfach 
praktischer/übersichtlicher ist.

Aber gerade eine Endlosschleife lässt sich mit einem for(;;) oder 
while(1) sofort erkennen, was bei einem goto nicht der Fall ist.

von Walter (Gast)


Lesenswert?

Hab da jetzt noch ein Programm probiert. Das gleich hab ich damals vor 
15 Jahren mit meinem C64 in Basic angestellt. Einen Zapfenrechner..

Also ich hab da jetzt statt dem goto eine for schleife am Anfang 
eingebunden. Stimmt das so, das ich dann i einfach nie mit ++ 
incrementiere?

Hier das Beispiel:

#include <cstdlib>
#include <iostream>

using namespace std;

int main ()
{
    int zapfen,n,i,ergebnis;

for (i=0;i=1;i)       //loop: Anfang ohne ++
    {
         cout << "\nWelchen Zapfen willst du berechnen? ";
         cin >> zapfen;



         for (n=2;n<12;n++)
             {
                       ergebnis = zapfen*n;
                       cout << " \n\t" << ergebnis;
                       zapfen = ergebnis;

             }



         for (n=2;n<12;n++)
             {
                       ergebnis = zapfen/n;
                       cout << " \n\t" << ergebnis;
                       zapfen = ergebnis;

             }
    }

    //goto loop; Ende und wieder zum Anfang

    return 0;
}


Gruß Walter

von Walter (Gast)


Lesenswert?

Ups...

for (n=2;n<12;n++)

soll eigentlich

for (n=2;n<10;n++)

heißen.

von Karl H. (kbuchegg)


Lesenswert?

> for (i=0;i=1;i)       //loop: Anfang ohne ++

Na ja.
Das ist eine eher unübliche Schreibweise.
Zuächst mal ist  i = 1  nicht das was du denkst das
es ist. Das ist eine Zuweisung und kein Vergleich!

Die Syntax einer for Schleife ist:

  for( Initialisierungsteil;
       Schleifenabbruchbedingung;
       Anweisung die am Ende eines jeden Schleifendurchgangs
       durchgeführt wird )

Nun. Du willst eine Endlosschleife. Dazu brauchst du aber
keine Variable. Daher brauchst du auch nichts zu initialisieren
und du brauchst auch die keine Anweisung am Ende jedes
Schleifendurchlaufs. Daher können die beiden Teile auch
leer sein.

Alles was du brauchst ist die Schleifenabbruchbedingung.
Das ist irgendein Ausdruck, der logisch wahr ergibt. In
C ist aber jeder arithmetische Ausdruck auch gleichzeitig
ein logischer Ausdruck, wobei 0 als logisch falsch gewertet
wird und alles was nicht 0 ist als logisch wahr gewertet wird.
Das heist aber auch: Ein simples 1 ist bereit logisch wahr.

Eine for-Schleife für eine Endlosschleife schreibt man
daher so:

   for( ; 1; ) {
   }

ABer auch das würde man so nicht machen. Zum einen ist das
viel zu viel Schreibaufwand, zum anderen sieht das etwas
seltsam aus. Daher das sehr viel einleuchtendere:

    while( 1 ) {
    }

von AVR-Jünger (Gast)


Lesenswert?

>Eine for-Schleife für eine Endlosschleife schreibt man
>daher so:

>   for( ; 1; ) {
>   }

for(;;) sollte sogar reichen (je nach Compiler...).

von Walter (Gast)


Lesenswert?

Vielen Dank für die ersten Schritte.

Es funktioniert beides.

2 letzte Fragen noch.

Zum programmieren für die AVR`s, sollte ich mich da auf C oder C#, <-- 
falls da ein Unterschied besteht, oder auf C++ spezialisieren?

Gehört da auch Visual C dazu?

von Karl H. (kbuchegg)


Lesenswert?

Ich würde mich auf C stürzen.

C++:  der gcc hat zwar C++ Unterstützung. Allerdings wirst du
      auf einem Mega8 oder Mega16 nur eher spärlich in
      typischer C++ Manier programmieren können. Bei den
      beschränkten Resourcen kann C++ seine Vorteile nicht
      wirklich ausspielen.
      C++ ist eher was für etwas 'größere' Maschinen

C#:   Nun ja. Die notwendige Runtime sowie die Klassenbibliothek
      haben auf einem PC schon ein paar Megabytes. Mit dem paar
      KB in einem Mega8 wird das wohl nichts.


Visual C
********
   Die Programmiersprache heist C
   Ein spezifisches Produkt eines bestimmten Herstellers, der
   unter anderem auch einen C Compiler samt Programmierumgebung
   dazu anbietet und verkauft, heist Visual C.
   Ist ein bischen so wie PKW und VW-Käfer. Ein VW-Käfer ist
   ein spezifischer PKW. Aber neben dem Käfer gibt es natürlich
   noch andere PKW.

von wulf (Gast)


Lesenswert?

Atmel hat dazu eine AppNote AVR035 ( 
http://atmel.com/dyn/resources/prod_documents/doc1497.pdf )
Efficient C Coding for AVR:

Dort steht über Endlosschleifen, dass sie mit for(;;){} den wenigsten 
Speicher verbrauchen. Könnt ihr gern ausprobieren; ein paar Byte werden 
bei AVR-GCC eingespart.

von kosmonaut pirx (Gast)


Lesenswert?

moin,

>Dort steht über Endlosschleifen, dass sie mit for(;;){} den wenigsten
>Speicher verbrauchen. Könnt ihr gern ausprobieren; ein paar Byte werden
>bei AVR-GCC eingespart.

na zeig mal bitte. kann ja jeder behaupten :)
bye kosmo

von Ulrich (Gast)


Lesenswert?

@Karl-Heinz:
Du schreibst 0 wird als logisch flasch ausgewertet. Jetzt bin ich völlig 
verwirrt. Vor ein paar Tagen habe ich gedacht jetzt habe ich es endlich 
gerafft und nun schreibst du das völlige Gegenteil. Ich dachte 0=Wahr 
und !=0 ist falsch. Was den nun jeder schreibt was anderes.....

von Karl H. (kbuchegg)


Lesenswert?

Definitiv:

0 ist 'logisch falsch'
und alles was nicht 0 ist gilt als 'logisch wahr'

von Ulrich (Gast)


Lesenswert?

  if (0)
    cout << "0 ist wahr" << endl;
  if (1)
    cout << "1 ist wahr " << endl;

Du hast recht wenn ich das compilire wird das 2. ausgegeben.
Jetzt hoffe ich das ich es mir endlich merken kann....
wobei das eigenltich auch logisch ist. Aber irgendwo wars mal anders und 
seitdem kann ichs mir nimmer merken....

von wulf (Gast)


Lesenswert?

@kosmonaut pirx:
dann öffne mal die AppNote, geh auf Seite 21 und schau unter Punkt 7.

Wenn du das nicht glaubst, dann kompilier doch mal eine Endlosschleife 
mit while(1) und einmal mit for(;;), dann wirst schon sehen, dass die 
zweite Lösung kleiner ist.

von kosmonaut pirx (Gast)


Lesenswert?

@wulf:
ich glaube dir, das das da steht. aber man muss ja nicht alles blind 
glauben :)

ein experiment gehört immer dazu. man nehme folgendes beispiel für den 
atmega32 uart:
1
#include <avr/io.h>
2
3
int main(){
4
  uint8_t __br = 25;
5
  UBRRH = __br >> 8;
6
  UBRRL = __br;
7
  UCSRB = (1 << RXEN) | (1<<TXEN);
8
  UCSRC = (1 << URSEL) | (3<<UCSZ0);
9
10
//  while(1){
11
  for(;;){
12
    loop_until_bit_is_set(UCSRA, UDRE);
13
    UDR = 0x41;
14
  }
15
}

gcc version 4.1.1, -O0 (optimierung aus)

avr-size output
mit for-loop:
text    data     bss     dec     hex
92       0       0      92      5c

mit while-loop:
text    data     bss     dec     hex
92       0       0      92      5c

auch mit optimerung -O1 oder -Os ändert sich nichts, einfach mal so 
glauben, bin nur zu unfleißig, das auch noch zu posten.

hilf mir auf die sprünge, wenn ich einen fehler gemacht habe.
bye kosmo

von wulf (Gast)


Lesenswert?

hmmm...

interessant.
ich hab mit AVR Studio 498 Build
und AVR-GCC bei Optimierung -Os
der MCU ist ein Mega8;
da hab ich (nur durch Änderung der Schleife) 2 Byte einsparen können.

Allerdings muss ich dir Recht geben, jetzt gerade ein kleines Stück Code 
kompiliert und da geht nix. Vielleicht ist das nur bei größerem Code in 
der Schleife?!?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.