Forum: Mikrocontroller und Digitale Elektronik Code Optimiereung AVR C


von der_muck (Gast)


Lesenswert?

Hallo,
ich habe ein Projekt für RC Modelle Realisiert in C, es funktioniert 
auch alles soweit, nur finde ich den Code nicht sonderlich "schön". Wie 
optimiert man am besten einen Code....

als Beispiel

DDRB = 0b11111111; -> ist es eleganter 0xFF zu schreiben oder alle 
einzeln mit (1<<PBX)

in der FH merkt man im Praktia das man in Java als Student relativ viel 
Programmiert und der Prof. dann alles in einer Zeile umsetzt ;). Das ist 
in C sicherlich ähnlich und mit der zeit kommen die kniffe...

Gibt es aber irgend wo beispiele, oder eine art Festlegung wie man den 
Code gestaltet. Hardware nahe C Programmierung fängt jetzt erst an aber 
das Projekt wollen einige in ihren Modellen einsetzen und da will ich es 
sauber umgesetzt haben. Ich setze mich immer mal wieder dran und 
überarbeite einige stellen, aber viele Wege führen nach Rom ;).

Es geht mir um grundlegende Regeln, inoffizielle Festlegungen die 
wichtig werden wenn die Programme größer werden...

lg

von ... .. (docean) Benutzerseite


Lesenswert?

Viel wichtiger als schöner code... sind schöne Kommentare...

also z.B. kann man ruhig

DDRB = 0xff;

schreiben, sollte dann aber darüber "Alle Pins an Port B als Ausang" 
schreiben...

von P. S. (Gast)


Lesenswert?

Wenn die Pins eine spezielle Bedeutung haben, wuerde ich auf jeden Fall 
defines dafuer definieren und auch verwenden. Kuerzer ist meist nicht 
besser, sondern nur schlechter lesbar.

Alte Regel:

"Code is written once, but read many times."

von Der Neugierige (Gast)


Lesenswert?

>schreiben, sollte dann aber darüber "Alle Pins an Port B als Ausang"
>schreiben...

Viel wichtiger ist aber eine Erklärung, warum alle Pins als Ausgang 
gesetzt werden.

von Hmm... (Gast)


Lesenswert?

Nur ein paar Tipps, die sich für mich bewährt haben:

1. Bestimmte Werte wie z.B. die Anzahl von Schleifendurchläufen bei der
   Bearbeitung von Tabellen oder bei Timeouts, etc sollten im Header der
   betreffenden C-Datei per #define hinterlegt werden.

   #define C_MAX_PACKET_LENGTH 12
   #define C_MAX_BUS_TIMEOUT   100

2. Prototypen, neu angelegte Datentypen/Strukturen, Defines usw gehören 
in
   die Headerdatei (sofern sie Modulübergreifend verwendet werden 
sollen).
   Variablen werden hingegen in der .C Datei angelegt. Genauso wie die
   Funktionen. Kurz, alles was Code/Daten erzeugt kommt in die .C-Datei,
   alles was diese nur beschreibt in den Header.

3. Versuch aussagekräftige Variablennamen zu verwenden, die auch schon
   einen Hinweis auf den Datentypen geben. Dann muss man später nicht
   rätseln, ob die Variable nun ein Pointer, ein Integer, ein... ist.

   unsigned char ucMyChar;
   signed int    uiMyInt;
   char          szMyString[] = "Hallo Welt";

4. Versuch so wenig globale Variablen wie möglich zu verwenden. Und wenn 
es
   UNBEDINGT sein muss, versuch den Gültigkeitsbereich einzuschränken. 
Also
   zunächst über 'static'-Variablen in der Funktion (sofern diese nicht
   rekursiv aufgerufen wird). Falls das nicht ausreicht, beschränke die
   Gültigkeit wenigstens auf das Modul, in dem sie benötigt wird. Wenn 
du
   z.B. für einen UART-Treiber einen Ringpuffer brauchst, muss dieser
   ausserhalb uart.c nicht sichtbar sein.

5. Kennzeichne Funktionen, die nur im aktuellen Modul verwendet werden 
mit
   einem Unterstrich am Anfang:

   unsigned int _calcCrc(unsigned char pucBuffer);

6. Versuch Funktionsnamen mit dem Modul in Verbindung zu bringen:

   void  uart_initDriver(void);
   void  spi_sendCharacter(unsigned char ucData);

7. Trenne innerhalb eines Moduls getrennte Bereiche ruhig durch aus-
   kommentierte Trennlinien:

   /* Variablen *********************************************/
   unsigned char _aucRingBuffer[C_MAX_RINGBUFFER_LENGTH];
   unsigned char _ucWritePtr;
   unsigned char _ucReadPtr;

   /* Funktionen ********************************************/
   void uart_initDriver(
       unsigned char uiBaudrate,  /* Baudrate             */
       unsigned char ucParityFlag /* Paritäts-Einstellung */
     )
   {
    ...
   }

8. Rücke alle Blöcke vernünftig ein. Leerzeichen sind Tabs immer vorzu-
   ziehen. Am besten im Editor gleich alle Tabs durch 2 oder 4 
Leerzeichen
   ersetzen lassen.

9. Gute Kommentare sind wichtig. Sie sollten nicht den Code wiederholen,
   sondern den Sinn der Zeile wiedergeben:

Schlecht:
   ucReadPtr++;   /* Variable ucReadPtr inkrementieren      */

Besser:
   ucReadPtr++;   /* Lesezeiger auf nächstes Element setzen */

10. Scheue dich nicht davor, auch mal 2,3 Zeilen Kommentar über
    den Sinn bzw. die Funktion eines Algorithmus zu schreiben. Gerade
    bei komplizierterern Funktionen muss man dann einige Wochen später
    nicht erst den Code reverse-engeneeren um dahinter zu kommen, was
    genau er macht.

11. Versuch den Quellcode stets bündig zu kommentieren. Es liest sich
    angenehmer, wenn ein Block eingerückt an einer festen Stelle beginnt
    und eine Zeile einheitlich z.B. max. 100 Zeichen lang ist. An dieser
    Länge kann man dann auch festmachen, wo man Kommentare schliesst.

  /* Variablen für Ringpuffer-Handling 
**********************************/
  unsigned char     _ucReadPtr;          /* Lesezeiger im Ringpuffer 
*/
  unsigned char     _ucWritePtr;         /* Schreibzeiger im Ringpuffer 
*/
  unsigned char     _pRingBuffer;        /* Zeiger auf Ringpuffer 
*/

  /* Prototypen für lokale Funktionen 
***********************************/
  void      _clearRingBuffer(void);      /* Löscht den Ringpuffer 
*/
  void      _sendCrc(void);              /* Sendet CRC für akt. Packet 
*/

von P. S. (Gast)


Lesenswert?

Ganz sicher keine Typpraefixes, die sind grauenhaft zu lesen und bringen 
wenig.

von Hmm... (Gast)


Lesenswert?

Seh gerade das die Zeile im Antwort-Feld hier  etwas länger ist als die
tatsächlich dargestellte. arrg

Alle Kommentare in den Beispiel-Codes enden in der selben Zeile in
der sie eröffnet wurden. Kommentare in aufeinander folgenden Zeilen
enden ebenfalls in der selben Spalte.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter Stegemann wrote:
> Ganz sicher keine Typpraefixes, die sind grauenhaft zu lesen und bringen
> wenig.

Ungarische Notation halt.  Alle Microsoft-Jünger lieben sie, alle
anderen hassen sie wie die Pest...  Ich habe mich früher immer
gefragt, warum die Programme alle mit dem Drucker reden wollen
(Variablennamen, die mit "lp" anfangen :-).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hmm... wrote:
> Seh gerade das die Zeile im Antwort-Feld hier  etwas länger ist als die
> tatsächlich dargestellte. *arrg*

Siehste, wenn du dich anmeldest, darfst du deine Postings nachher
sogar noch (ein Weilchen) editieren.  Aber auch sonst gibt's dafür
die Vorschau.

> Alle Kommentare in den Beispiel-Codes enden in der selben Zeile in
> der sie eröffnet wurden. Kommentare in aufeinander folgenden Zeilen
> enden ebenfalls in der selben Spalte.

Dafür wiederum gibt's die [c]-Markierungen.

von Hmm... (Gast)


Lesenswert?

@Peter:

Es gibt verschiedene Stile und Notationen. Die vorgeschlagene ist EINE 
von denen, die in der Praxis gut funktionieren. K&R-Notation (siehe 
Linux-Kernel) ist eine andere, aber die finde ich persönlich ein wenig 
umständlich zu lesen.

Typ-Prefixe können aber bei der späteren Pflege des Codes durch einen 
anderen Entwickler eine große Hilfe darstellen, wenn sie konsequent 
eingesetzt werden. Oder weißt du sofort, welchen Datentyp ein Variable 
wie
"act_pump_pressure" hat? Ist das ein Integer oder ein Float? 
Vorzeichenbehaftet, weil kein negativer Druck möglich ist, oder 
vielleicht mit Vorzeichen weil später damit gerechnet wird?

von der_muck (Gast)


Lesenswert?

danke für die Tips :) genau das meinte ich. Mir fehlen nur die Ansätze, 
kommentiert habe ich eigentlich alles aber mit der Define Funktion kaum 
gearbeitet :(. auch arbeite ich zuviel mit Globalen variablen wie
int count;
int result;

es fehlt noch die Code sicherheit aber ich bin froh das das 1 Programm 
schon mal Funktioniert... na ja aber mit den Tips komme ich schon mal ne 
ecke weiter :)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Hmm... wrote:

> Oder weißt du sofort, welchen Datentyp ein Variable
> wie
> "act_pump_pressure" hat?

Der Datentyp der einzelnen Variablen ist als allererstes für das
Verständnis unwichtig.  Wichtiger ist, dass der gesamte Algorithmus
in einem Kommentar kurz beschrieben wird, und dort wäre auch Platz,
sich über die Typenwahl auszulassen, warum man vielleicht den
eingelesenen uint16_t aus dem ADC anschließend lieber als float
weiter verarbeiten möchte.

von Hmm... (Gast)


Lesenswert?

> Wichtiger ist, dass der gesamte Algorithmus
> in einem Kommentar kurz beschrieben wird, und dort wäre auch Platz,
> sich über die Typenwahl auszulassen

Und mit entsprechenden Doku-Tools (Doxygen, etc) hat man dann auch eine 
schöne Code-Doku zum nachschlagen. ;)


> Ungarische Notation halt.  Alle Microsoft-Jünger lieben sie, alle
> anderen hassen sie wie die Pest...

Meine Windows-Codingzeit ist schon eine Weile her, aber manches wird man 
wohl nie los...


Aber nochmal kurz zum Thema zurück, die Sache mit den Datentypen ist mir 
letztens erst in der Atmel-Appnote zu den AT90USBxxx aufgefallen. Dort 
wird im Beispiel USB-Stack eine 8-Bit Variable "data_to_transfer" 
verwendet, welche an einigen Stellen überlaufen kann. Wenn man dann mal 
einen größeren Descriptor (Report-Deskriptor,etc) schicken möchte, geht 
dieser dann auf einmal nicht mehr korrekt zum Host, obwohl der Stack ja 
eigentlich den Deskriptor korrekt in kleine Packete zerlegt, die in den 
Endpoint passen.

Hier werden an einigen Stellen munter Werte in die Variable geschrieben, 
die schnell größer als 255 werden können. Ein entsprechender Hinweis 
fehlt, allerdings denke ich das es sich hier eher um einen Bug den als 
um ein Feature handelt. ;)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Den coding style der USB-Appnotes würde ich auch alles andere denn
als vorbildlich bezeichnen.  Die Teile erinnern eher an einen riesigen
Teller voller Spaghetti...

von P. S. (Gast)


Lesenswert?

Besonders witzig wird ungarische Notation, wenn der Autor dann lustig 
zwischen a fuer Array und p fuer Pointer wechselt. Am besten ist dann 
noch ein pa fuer Strings...

von Michael K. (mmike)


Lesenswert?

Pädagogisch wertvoll ??

Schlecht:
   ucReadPtr++;   /* Variable ucReadPtr inkrementieren      */

Besser:
   ucReadPtr++;   /* Lesezeiger auf nächstes Element setzen */


Grüße,
Michael

von P. S. (Gast)


Lesenswert?

Weder noch, denn beides steht schon da.

Immer dokumentieren, warum, nicht was.

von Michael K. (mmike)


Lesenswert?

Stimmt. Mein Fehler !

Hab nur auf die Anweisung geachtet ...

von Sven P. (Gast)


Lesenswert?

Hmm... wrote:
> 1. Bestimmte Werte wie z.B. die Anzahl von Schleifendurchläufen bei der
>    Bearbeitung von Tabellen oder bei Timeouts, etc sollten im Header der
>    betreffenden C-Datei per #define hinterlegt werden.
In kleiner Umgebung ja, ansonsten definitiv die falsche Methode. Der 
C-Präprozessor ist doof wie Stroh, deshalb, wenn möglich, immer mit dem 
Compiler arbeiten:
1
const int meine_konstante = 5;
2
/* anstelle von */
3
#define meine_konstante 5

> 3. Versuch aussagekräftige Variablennamen zu verwenden, die auch schon
>    einen Hinweis auf den Datentypen geben. Dann muss man später nicht
>    rätseln, ob die Variable nun ein Pointer, ein Integer, ein... ist.
Glaubenssache. Der Typenpräfix ist meiner Ansicht nach blödsinnig und 
macht die Sache weder übersichtlicher noch lesbarer.
Kurze Variablennamen sind in Standardkonstrukten legitim:
1
for (int i = 0; i < 5; i++) { }
2
/* und ja, mit C99 geht das */

Überhaupt: nicht das Rad neu erfinden, sondern Mut zu eingängigen 
Konstruktionen. Das For oben liest sich zehnmal eingängiger (weil schon 
hundertmal gelesen), als sowas:
1
for (int zeichenZaehler = 0; zeichenZaehler < 5; zeichenZaehler++) {}

> 4. Versuch so wenig globale Variablen wie möglich zu verwenden. Und wenn
> es UNBEDINGT sein muss, versuch den Gültigkeitsbereich einzuschränken.
Gleiches gilt für Funktionen, die können und sollten auch, wenn möglich, 
statisch sein. Unter Umständen kanns trotzdem sinnvoll sein, komplexere 
Hilfsvariablen mit Static außerhalb von Funktionen zu definieren, je 
nach Compiler. Nicht immer ist der beschränkteste auch der effizienteste 
Gültigkeitsbereich, das ist aber dann Compiler-Magie...

> Falls das nicht ausreicht, beschränke die Gültigkeit wenigstens auf
> das Modul, in dem sie benötigt wird.
Und zwar auch mit Static.

> 5. Kennzeichne Funktionen, die nur im aktuellen Modul verwendet werden
> mit einem Unterstrich am Anfang:
Dabei allerdings vorsichtig sein, denn Unterstricherei kann mit den 
Namensräumen Standardbibliothek kollidieren. Und modulinternes Zeugs 
statisch machen:
1
static unsigned int _calcCrc(unsigned char pucBuffer);

Und nach Möglichkeit "unsigned char" vermeiden. Für Zeichen ok, zum 
Rechnen sind die Typen aus <stdint.h> zu verwenden (uint8_t ...).

> 6. Versuch Funktionsnamen mit dem Modul in Verbindung zu bringen:
Und versuch, Matschenamen zu vermeiden. EntwederDurchgehendCamelCase 
oder durchgehend_mit_unterstrichen. Aber auch wieder Glaubenssache... 
Hauptsache systematisch.

> 7. Trenne innerhalb eines Moduls getrennte Bereiche ruhig durch aus-
>    kommentierte Trennlinien:
Auch wieder Glaubenssache. Nach Variablen und Funktionen zu trennen, ist 
m.E.n. blödsinn, viel wichtiger wärs zu wissen, wo Funktionseinheiten 
sind.
Dass da Variablen kommen, seh ich auch selber.

Und bitte durchgängig:
>        unsigned char uiBaudrate,  /* Baudrate             */
>        unsigned char ucParityFlag /* Paritäts-Einstellung */
Warum zeigt der eine Präfix einen "ui", der andre aber einen "uc"?

> 8. Rücke alle Blöcke vernünftig ein. Leerzeichen sind Tabs immer vorzu-
>    ziehen. Am besten im Editor gleich alle Tabs durch 2 oder 4
>    Leerzeichen ersetzen lassen.
Bloß nicht, was Schlimmeres gibts ja kaum noch... doch, und zwar Tabs 
und Leerzeichen gemischt.
Meine Meinung: IMMER TABS benutzen. Dann kannst DU dir einstellen, wie 
breit ein Tab sein soll. Passts mir dann nicht, stell ich die Breite 
halt größer. Einmal mit Leerzeichen gearbeitet macht es anderen 
unmöglich, die Darstellung anzupassen.
Immer schön dran denken: du bist nicht der einzige, der den Code liest, 
und du bist vorallem nicht derjenige, nach dessen Vorliebe beim 
Bearbeiten sich alle richten müssen.
Nen guter Einrückungsstil zeichnet sich dadurch aus, dass er bei 2 
Spalten breiten Tabs genausogut lesbar ist, wie bei 4 Spalten breiten 
Tabs. Ergo: ASCII-Diagramme und Ähnliches sauber mit Leerzeichen, den 
Rest mit Tabs.

> 10. Scheue dich nicht davor, auch mal 2,3 Zeilen Kommentar über
>     den Sinn bzw. die Funktion eines Algorithmus zu schreiben. Gerade
>     bei komplizierterern Funktionen muss man dann einige Wochen später
>     nicht erst den Code reverse-engeneeren um dahinter zu kommen, was
>     genau er macht.
Aber Vorsicht dabei: Wenn zu fünf Zeilen Algo fünfzehn Zeilen Kommentar 
nötig sind, die erklären, warum wo eine Schleife und wo kein Break 
steht, ist das in vielen Fällen ein Anzeichen davon, dass der Code 
unnötig kompliziert ist. Lieber nochmal überdenken.


> 11. Versuch den Quellcode stets bündig zu kommentieren. Es liest sich
>     angenehmer, wenn ein Block eingerückt an einer festen Stelle beginnt
>     und eine Zeile einheitlich z.B. max. 100 Zeichen lang ist. An dieser
>     Länge kann man dann auch festmachen, wo man Kommentare schliesst.
Codezeilen werden so lang, wie es nötig ist, um sie SAUBER zu 
formulieren. Erzwungene Umbrüche wegen der 100 Zeichen sind ebenso 
blöde. Kommentare zu wichtigen Dingen schreiben sich übrigens noch 
besser in der Zeile davor. Dann kann man auch gleich Doxygen-Kommentare 
benutzen und sich nachher ne schöne Dokumentation erstellen lassen.
Bei Kommentaren in derselben Zeile merk ich selbt immer, wie ich zu 
Stummeleien neige, um noch unter die 100 Zeichen zu kommen und so. Mag 
aber wieder mal subjektiv sein.

Soviel zu meinen persönlichen Eindrücken aus der Praxis :-}

von Mathias O. (m-obi)


Lesenswert?

was ist denn der Unterschied zwischen den beiden Zeilen?
1
const int meine_konstante = 5;
2
/* anstelle von */
3
#define meine_konstante 5

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Mathias Obetzhauser wrote:
> was ist denn der Unterschied zwischen den beiden Zeilen?
>
>
1
const int meine_konstante = 5;
2
> /* anstelle von */
3
> #define meine_konstante 5
Im erstenfall kann die Konstante nur integer Zahlen annehmen, im 
zweitenfall kannst du da auch blabla oder sonstwas reinschreiben...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Im ersten Fall ist es in C aber leider auch noch eine Variable, bei
denen der Compiler lediglich Änderungsversuche monieren wird.  (Er
kann sie aber auch inline expandieren, muss aber nicht.)

In C funktioniert aber stattdessen auch:
1
enum {
2
   meine_konstante = 5,
3
};

von Hmm... (Gast)


Lesenswert?

> > 8. Rücke alle Blöcke vernünftig ein. Leerzeichen sind Tabs immer vorzu-
> >    ziehen. Am besten im Editor gleich alle Tabs durch 2 oder 4
> >    Leerzeichen ersetzen lassen.
> Bloß nicht, was Schlimmeres gibts ja kaum noch... doch, und zwar Tabs
> und Leerzeichen gemischt.
> Meine Meinung: IMMER TABS benutzen.

Wenn wir schon beim Thema sind... ;)

Mit welcher Zeichenkodierung erstellt ihr eure Quellen? Hatte schon 
etliche Fälle wo jeder Kollege einen anderen Editor mit anderer 
Kodierung nutzte. Erstelt wurde da in Unicode, dann mit UTF8 nochmal 
nachgebessert und das Bugfix wurde dann mit einem Linux-Editor 
eingepflegt. Als Resultat waren dann sämtliche Umlaute/Sonderzeichen aus 
den Kommentaren getilgt und einige Tabs automatisch in 8 Leerzeichen, 
andere hingegen zu 4 oder 2 Leerzeichen mutiert, je nach dem verwendeten 
Editor...

Die Module mit Leerzeichen statt Tabs haben wenigstens ihre Formatierung 
behalten.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Kleinster gemeinsamer Nenner: ASCII.  Schreibst du alles in Englisch,
dann hast du sowieso keinen Stress mit den Umlauten. ;-)  Aus dem
Jörg einen Joerg zu machen, stört mich in dem Zusammenhang auch nicht
nennenswert.

von NixChecker (Gast)


Lesenswert?

1. #define möglichst nicht benutzen. Wenn du Konstanten brauchst dann 
halt mit const definieren. #define ist eigentlich nicht für Konstanten 
gedacht.

2. Für Variablen- und Funktionsnamen bitte keine Unterstrichei. Es macht 
die Namen unnötig lang.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

NixChecker wrote:
> 1. #define möglichst nicht benutzen. Wenn du Konstanten brauchst dann
> halt mit const definieren.

Siehe oben.  In dieser Allgemeinheit mag die Aussage für C++ OK
sein, für C aber nicht: dort belegen mit const deklarierte Objekte
in erster Linie erst einmal Speicherplatz (falls der Optimierer
sie nicht doch noch inlinen kann/möchte).

> #define ist eigentlich nicht für Konstanten
> gedacht.

<Lorio>Ach!</Loriot>

Wofür ist es deiner Meinung nach denn gedacht?

Ja, ich weiß, bei C++ sind sie dank "echten" const und Templates
mittlerweile ziemlich entbehrlich geworden, bei C sieht die Sache
aber immer noch anders aus.

> 2. Für Variablen- und Funktionsnamen bitte keine Unterstrichei. Es macht
> die Namen unnötig lang.

Naja.  Bei 20 Zeichen langen Namen machen 2 oder 3 Unterstriche das
Kraut fett?  Persönlich_finde_ich_sie_besser_lesbar (da es mehr dem
normalen Satzfluss entspricht) alsWennManZwischendrinGrossbuchstaben
einfügt.  Das ist aber sicher Geschmackssache und daher, wiederum
siehe oben, ist es das Wichtigste, dass man sich auf einen Stil
einigt und den dann durchzieht.

von NixChecker (Gast)


Lesenswert?

>> #define ist eigentlich nicht für Konstanten
>> gedacht.

><Lorio>Ach!</Loriot>

>Wofür ist es deiner Meinung nach denn gedacht?

Na ja "#define c a+b" geht aber "#define a 7" ist doch bescheuert.

von NixChecker (Gast)


Lesenswert?

oder gleich eine inline Funktion benutzen...

von Hmm... (Gast)


Lesenswert?

Und was ist mit Dingen wie

#define F_CPU         8000000L
#define BAUDRATE      19200
#define HYSTERESE_MAX 1200
#define HYSTERESE_MIN 1000

Wenn ich auf meinem AVR nicht für jede Konstante eine Variable im Flash 
oder gar RAM haben möchte, sind solche Sachen doch als #define ganz gut 
aufgehoben...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

NixChecker wrote:

> Na ja "#define c a+b" geht aber "#define a 7" ist doch bescheuert.

Gerade das erste fällt eher unter die Kategorie "bescheuert".  Wenn
du es nämlich in einem Ausdruck benutzt wie:
1
result = 5 * c;

...dann wunderst du dich hinterher ziemlich lange, warum da nicht
das Gewünschte rauskommt.

Was wären denn für reine Konstanten deine Alternativvorschläge?
"const" ist in C nicht wirklich der Bringer, da es trotzdem ein
Objekt im RAM bleibt.  enum hilft auch nur begrenzt, da es per
definitionem auf den Datentyp int beschränkt ist.  Die Konstante
pi kannst du damit also schon einmal nicht definieren.

Der C-Standard selbst schreibt übrigens auch eine Reihe von Makros
vor, die auf Kontanten definiert sind, ERANGE beispielsweise.

von P. S. (Gast)


Lesenswert?

Defines sind voellig in Ordnung. Typsicherheit wird oft gar nicht 
gebraucht, wozu dann mit Variablen um sich schmeissen? Man muss eben, 
wie immer, auch wissen wo der Sinn einer Regel ist - dann weiss man 
auch, wann sie anzuwenden ist.

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.