Hier wird eine kleine Tabelle mit char's angelegt, die nur lokal
gebraucht wird und deshalb nicht einmal eine Namen bekommt.
Meine Frage, wie kann man das für short oder long int schreiben?
Oder geht das vielleicht nur für char?
> Hier wird eine kleine Tabelle mit char's angelegt, die nur lokal> gebraucht wird und deshalb nicht einmal eine Namen bekommt.
Vergiss das ganz schnell wieder.
Ich kann mich an den Thread erinnern, aus dem du das raus hast.
Das ist eine auf den ersten Blick überraschende Kuriosität der C-Syntax.
Wenn du das real einsetzt, sollte man dich mit dem nassen Fetzen ein
paar mal rund ums Büro jagen.
Man muss nicht jeden 'Unfug' benutzen, nur weil er theoretisch möglich
ist.
Peter Zz schrieb:> Hier wird eine kleine Tabelle mit char's angelegt, die nur lokal> gebraucht wird und deshalb nicht einmal eine Namen bekommt.
Man darf auch lokale Tabellen anlegen, die lesbar sind, ohne diese
verrückte Schreibweise.
Außerdem verschwendet diese Schreibweise Speicherplatz, da ein 0-Byte
angefügt wird.
Und Vorsicht, je nach Compiler kann es passieren, daß die Tabelle bei
jedem Aufruf erst neu angelegt wird!
Daher werden konstante Arrays in der Regel außerhalb einer Funktion
definiert.
Peter
Karl Heinz Buchegger schrieb:> Wenn du das real einsetzt, sollte man dich mit dem nassen Fetzen ein> paar mal rund ums Büro jagen.
OK, ich werd es nicht einsetzen, Pfadfinderehrenwort :-)
Peter Zz schrieb:> Karl Heinz Buchegger schrieb:>> Wenn du das real einsetzt, sollte man dich mit dem nassen Fetzen ein>> paar mal rund ums Büro jagen.>> OK, ich werd es nicht einsetzen, Pfadfinderehrenwort :-)
ich nehme sowas gelegentlich, und schäme mich nicht mal dafür!
Klaus Wachtler schrieb:> ich nehme sowas gelegentlich, und schäme mich nicht mal dafür!
In was für ner Klitsche arbeitest Du, dass dort MISRA-C ein Fremdwort
ist? ;-)
blubb schrieb:> nur aus Interesse, wieso die VerUndung mit 0x07?>> Das führt doch nur dazu, dass für zB n=2 der selbe Eintrag genutzt wird> wie für n=10, richtig?
Ja. Da die Tabelle aber nur 8 (Nutz*-) Elemente enthält, dürfte das
Verhalten ohne die Verundung zu interessanten Nebeneffekten führen.
*) die abschließende \0 macht 9 draus, aber die bleibt hier ungenutzt.
blubb schrieb:> oder anders ausgedrückt, alle 8 Durchläufe die Tabelle von Neuem genutzt> wird.
Jep.
Im Original ging es genau darum. Das war eine Schrittmotoransteuerung
mit Halbschritten und der String sind in Wirklichkeit die Codes mit
denen die diskreten Ausgangstreiber geschaltet wurden.
(Wenn mich meine Erinnerung nicht trügt)
n war einfach nur eine Variable, die mit den Schritten erhöht bzw.
verringert wurde.
Mark Brandis schrieb:> Klaus Wachtler schrieb:>> ich nehme sowas gelegentlich, und schäme mich nicht mal dafür!>> In was für ner Klitsche arbeitest Du, dass dort MISRA-C ein Fremdwort> ist? ;-)
Meistens in meiner eigenen. Jedenfalls nie in einer Bude, in der nach
MISRA gearbeitet wird - das ist m.E. Blödsinn.
Nichts gegen ordentliches Programmieren, aber wenn man seine
Programmierer für so debil hält, daß sie nicht mit C umgehen können (was
ja sein kann), dann soll man nicht C nehmen sondern BASIC, und nicht von
C alles wegkürzen in der Hoffnung, daß BASIC rauskommt.
Eine Zeile mehr, dafür selbstdokumentierend, d.h. ggf. spart man sich
den separaten Kommentar dafür. Und man kann es auf dem AVR auf diese
Weise auch im Flash-Speicher speichern, wenn man das möchte (Stichwort
PROGMEM).
Klaus Wachtler schrieb:> Jedenfalls nie in einer Bude, in der nach> MISRA gearbeitet wird - das ist m.E. Blödsinn.> Nichts gegen ordentliches Programmieren, aber wenn man seine> Programmierer für so debil hält, daß sie nicht mit C umgehen können (was> ja sein kann), dann soll man nicht C nehmen sondern BASIC, und nicht von> C alles wegkürzen in der Hoffnung, daß BASIC rauskommt.
DANKE, DANKE, DANKE!
Klaus Wachtler schrieb:> Nichts gegen ordentliches Programmieren
Vieles, was in C möglich ist und vom Compiler akzeptiert wird, geht am
Thema "ordentlich programmiert" meilenweit vorbei. Wenn dem nicht so
wäre, gäbe es den IOCCC nicht :-)
http://www.ioccc.org/
Außerdem gilt: Da, wo mehrere Entwickler an der gleichen Software
arbeiten, sind vernünftige Programmierrichtlinien unumgänglich. Wenn
jeder seinen C oder C++ Code "frei nach Schnauze" schreiben darf, dann
gute Nacht Projekt!
In einem Code Review würde man die obige Zeile, so wie Karl Heinz
Buchegger schon bemerkt hat, um die Ohren gehauen bekommen. Und womit?
Mit Recht.
Mark Brandis schrieb:> sind vernünftige Programmierrichtlinien unumgänglich.
Jaja, aber du lobpriesest zuvor MISRA, während du jetzt von
"vernünftigen Programmierrichtlinien" schreibst.
MISRA enthält viele Dinge, die eigentlich für jedermann relativ
selbstverständlich sind. Aber es enthält auch Forderungen, die
voll und ganz in Klaus' Aussage reinpassen, dass man halt nur
solche Leute in C programmieren lassen sollte, die die Sprache
auch kennen, statt alle die zu beschneiden, die wirklich damit
umgehen können.
Beispielsweise darf laut MISRA eine Schleife höchstens ein break
und kein continue haben. Beides kann aber durchaus (bei sorgfältiger
Benutzung) sehr sinnvoll sein und helfen, Code optimal zu
formulieren. Wenn man in so einer Situation ist und dann MISRA
einhalten muss, führt es dazu, dass man für den Schleifenabbruch
eine Hilfsvariable hinzufügen muss, die im besten Fall den gleichen
Effekt wie mehrere break hat, im schlimmsten Fall zu mehr Code
führt. Übersichtlicher wird es dadurch kaum. Gleichfalls für
continue: statt die Schleife mit continue zu wiederholen, muss man
eine zusätzliche Schachtelungstiefe für ein weiteres "if not"
einfügen, um den Rest des Schleifenkörpers nicht mehr auszuführen.
Über die Unsinnigkeit derartiger Forderungen hat sich Donald Knuth
bereits 1974 in seinem Aufsatz "Structured Programming with go to
Statements" ausgelassen.
Auch über die Sinnhaftigkeit des Verbots, Gleitkommazahlen auf
Gleichheit oder Ungleichheit zu testen, kann man gut streiten: bei
allen heute üblichen Gleitkommadarstellungen hat die 0 ein genau
definiertes Bitmuster. Dieses Muster wird insbesondere garantiert
erzeugt während der Initialisierung einer Variablen. Damit ist ein
Test wie:
1
floatoffset;
2
3
...
4
voiddosomething(void)
5
{
6
...
7
if(offset==0.0){/* offset has not been assigned yet */
8
...
9
offset=calculate_soemthing();// which can never yield 0.0 again
10
}
11
}
durchaus sinnvoll und wohl definiert. In MISRA ist das aber nicht
zugelassen, da man Gleitkommazahlen generell nicht auf Gleichheit
testen darf.
p.s.: Real Programmers can write FORTRAN in any language. :-)
Im Endeffekt kann eine Firma Programmierrichtlinien festlegen, wie sie
es will. Solange sie eben als sinnvoll erachtet werden. Aber sie muss
eben auch festlegen, nach welchen Richtlinien Code erstellt werden soll
- wenn sie dies versäumt, handelt sie unprofessionell.
Jörg Wunsch schrieb:> Auch über die Sinnhaftigkeit des Verbots, Gleitkommazahlen auf> Gleichheit oder Ungleichheit zu testen, kann man gut streiten
Das Problem bei dem Vergleich auf 0.0 ist doch, dass z.B. 0.000001
hinreichend nahe an 0.0 liegt. Wenn die Differenz sehr gering ist, ist
es aber eher unsinnig, den Vergleich als "false" zu werten. Deshalb:
Nicht auf einen einzelnen Wert vergleichen, sondern ein akzeptables
Delta definieren und auf einen Bereich [Sollwert-Delta; Sollwert+Delta]
vergleichen. Das ist meines Wissens nach der Sinn hinter dieser
Forderung.
Mark Brandis schrieb:> Die Intention dahinter ist meines Erachtens nach eine andere.
Kann ja sein, aber das Verbot des Vergleichs ist "required" laut
MISRA, sodass die von mir oben geschilderte Situation dort
verboten ist. Ich muss mir also als Programmierer dann extra
noch ein Flag hinlegen, mit dem ich ermittle, ob der Wert bereits
initial gesetzt worden war oder nicht.
> Das Problem bei dem Vergleich auf 0.0 ist doch, dass z.B. 0.000001> hinreichend nahe an 0.0 liegt.
Kann ja sein. Wenn mich eine hinreichend kleine Differenz
interessiert, schreibe ich als Programmier natürlich nicht einen
Test auf != 0.0, sondern einen auf fabs(x) < epsilon. Wenn mich
aber interessiert, ob der Wert jemals bereits gesetzt worden ist,
ist das nicht die Lösung.
Ich habe mir das nur als eins von einigen sinnlosen Details aus
MISRA rausgepickt, weil es mir gerade unter die Finger kam, als ich
die Schwarte aufgeklappt habe. Es gibt ein paar solcher Dinge da
drin. Aber wie ich schon schrieb, der überwiegende Teil der MISRA-
Regeln ist durchaus sinnvoll und entspricht dem, was ordentliche
Programmierer auch von sich aus machen würden.
Mit einem style guide hat das Ding übrigens nichts zu tun: sowas
wie die Lage der Klammern, Einrückungsniveaus und dergleichen werden
darin nicht geregelt. In einer Firma will man sowas in der Regel
aber (bis zu einem nicht allzu hohen Detailgrad) auch geregelt haben.
Zur ursprünglichen Frage:
Peter Zz schrieb:> Meine Frage, wie kann man das für short oder long int schreiben?
Beispiel für short:
1
shortlookup(intn){
2
return(short[]){314,159,265,358,979,323,806}[n];
3
}
Ich würde aber von dieser Methode, Lookup-Tabellen anzulegen, ebenfalls
abraten, zumindest in C/C++.
Der Hauptgrund:
Peter Dannegger schrieb:> Und Vorsicht, je nach Compiler kann es passieren, daß die Tabelle bei> jedem Aufruf erst neu angelegt wird!
Arrays mit konstantem Inhalt lege ich deswegen grundsätzlich statisch
an.
Was die Lesbarkeit betrifft, würde ich das Konstrukt nicht völlig
verdammen. Letztendlich ist die Zeile
1
x=(short[]){314,159,265,358,979,323,806}[n];
ein C-Ausdruck von ähnlicher Komplexität wie
1
x=(short)((x11+x12+x13+x21+x22+x23+y)*n);
Wenn man das erste Beispiel so schriebe
1
staticshorttable[]={314,159,265,358,979,323,806};
2
3
x=table[n];
müsste man das zweite konsequenterweise so schreiben: