Morgen,
ich hab mal wieder eine Frage.
Wenn ich mit einer oder mehreren If-Schleife/n 15 Variablen abfragen
möchte, es kann immer nur eine Abfrage von 15 wahr sein, kann ich ja
eine If-Schleife schreiben in der alle 15 Variablen mit ODER Verknüpft
sind und ich kann 15 einzelne Schleifen schreiben in der jeweils nur
eine Variable abgefragt wird. Ich schreibe die ganze Geschichte in C.
Ich hab mir im Eclipse mal das Disassembly anzeigen lassen und komm auf
einen unterschied von 26 Befehlen, da aber nur eine Abfrage wahr werden
kann weiß ich nicht ob ich beim Programmdurchlauf eine Zeit ersparniss
habe.
Meine Frage an euch ist nun, verändert sich die Durchlaufzeit und
Speicherbedarf der main-Funktion (siehe unten) von Bsp1 zu Bsp2?
Ich dank euch mal wieder für eure Hilfe.
Gruß
Stephan
Bsp1:
Stephan schrieb:
> da aber nur eine Abfrage wahr werden> kann
Nö, es können alle 16 wahr sein, Du fragst ja 16 Variablen ab.
Das logische OR bricht nur nach der ersten ab, die wahr ist.
Peter
Stephan schrieb:
Eine Schleife heisst Schleife, weil dort etwas wiederholt wird. Bei
einem if wird nichts wiederholt, dort wird eine Auswahl getroffen. Darum
ist ein if keine Schleife, sondern eine Abfrage oder Auswahl.
> möchte, es kann immer nur eine Abfrage von 15 wahr sein, kann ich ja> eine If-Schleife schreiben in der alle 15 Variablen mit ODER Verknüpft> sind und ich kann 15 einzelne Schleifen schreiben in der jeweils nur> eine Variable abgefragt wird. Ich schreibe die ganze Geschichte in C.> Ich hab mir im Eclipse mal das Disassembly anzeigen lassen und komm auf> einen unterschied von 26 Befehlen,
logisch.
Kein Mensch sagt, dass in allen 15 Einzel-Abfragen identischer Code
stehen muss. Und ich denke da erwartest du etwas zuviel vom Optimizer,
wenn er das rausfinden und zusammenführen soll.
> Meine Frage an euch ist nun, verändert sich die Durchlaufzeit und> Speicherbedarf der main-Funktion (siehe unten) von Bsp1 zu Bsp2?
Da gibt es nur 1 Möglichkeit: ausprobieren und nachsehen, was der
Compiler daraus macht.
Die Erwarteungshaltung müsste aber sein: Die ODER Lösung ist schneller.
Schon alleine aus dem Grund, weil bei ODER eine Short-Cut Evalutation
gemacht werden muss. Sprich: Ist die erste Bedingung wahr, werden die
anderen Bedingungen gar nicht mehr ausgewertet. Bei deiner if-Lösung
hingegen, kann es je nach tatsächlichem Variableninhalt auch dazu
kommen, dass der Codeteil doppelt, dreifach etc. ausgeführt wird :-) In
diesem Sinne gleichwertig zum ODER wäre
1
if(...)
2
code;
3
4
elseif(...)
5
code;
6
7
elseif(...)
8
code;
Aber eigentlich ist das die falsche Fragestellung. Die korrekte
Fragestellung für dich sollte eigentlich lauten: Bei welcher Lösung habe
ich den geringeren Wartungsaufwand, wenn sich der von den Bedingungen
abhängige Codeteil verändert. Und bei dieser Frage steht es dann
plötzlich 15:1 für die ODER Lösung.
Und dann gäbe es da noch eine Möglichkeit, die von der Laufzeit her
etwas schlechter ist, aber deutliche Vorteile bezüglich der Codegröße
hat (z.B. 240 Bytes weniger als Beispiel 1):
Stefan Ernst schrieb:
> Und dann gäbe es da noch eine Möglichkeit, die von der Laufzeit her> etwas schlechter ist, aber deutliche Vorteile bezüglich der Codegröße> hat (z.B. 240 Bytes weniger als Beispiel 1):>
1
>unsignedchari;
2
>for(i=0;i<15&&variable[i];i++);
3
>if(i<15)
4
>test="BlaBlaBLa";
5
>
Machs doch wenigstens lesbar
1
unsignedchari;//Warum ein char für eine Zählvariable...
2
for(i=0;i<15;i++)
3
{
4
if(variable[i]!=0)
5
break;
6
}
7
8
if(i<15)
9
test="BlaBlaBla";//Wie soll das eigentlich funktionieren?
1) "Lesbarkeit" ist meist reine Geschmackssache. Ich finde meine
Variante lesbarer. Der direkte Zusammenhang von for und if wird dort
deutlicher. Bei deiner Variante sehen auf den ersten Blick for und if
wie zwei unabhängige Codeteile aus.
2) Deine Variante ist falsch.
3) Und was bitte soll das "wenigstens" bedeuten? Was gibt es denn an dem
Code noch alles auszusetzen?
4) Was hast du gegen ein unsigned char als Zählervariable?
Danke für eure schnellen Antworten. Ich hab die schnellste Möglichkeit
gefunden, ich kann die if-Abfrage/n weg lassen da ich schon die Abfrage
unbewusst vorher programmiert habe.
Dank euch.
Gruß
Stephan
Stefan Ernst schrieb:
> 1) "Lesbarkeit" ist meist reine Geschmackssache. Ich finde meine> Variante lesbarer. Der direkte Zusammenhang von for und if wird dort> deutlicher. Bei deiner Variante sehen auf den ersten Blick for und if> wie zwei unabhängige Codeteile aus.
Die Funktionsweise deines Algorithmusses liegt komplett in einer Zeile.
Ich musste zumindest zwei mal lesen um zu sehen wie es funktioniert.
M.m.n. ist es besser das etwas zu strecken über mehrere Zeilen.
> 2) Deine Variante ist falsch.
Jaja, ich nehme an du meinst den Vergleich. Der müsste auf == 0 prüfen.
> 3) Und was bitte soll das "wenigstens" bedeuten? Was gibt es denn an dem> Code noch alles auszusetzen?
Wenigstens im Sinne "Wenn du schon einen kompakten Algorithmus lieferst"
;)
> 4) Was hast du gegen ein unsigned char als Zählervariable?
char kommt von Character und das heißt Zeichen. Eine Zählvariable ist
kein Zeichen.
@Simon K.
> > 4) Was hast du gegen ein unsigned char als Zählervariable?> char kommt von Character und das heißt Zeichen. Eine Zählvariable ist> kein Zeichen.
was nimmst du denn für eine 8bit Zahl ohne vorzeichen?
> Die Funktionsweise deines Algorithmusses liegt komplett in einer Zeile.
Und er funktioniert nicht :-/
Denn schon beim ersten Durchlauf ist die erste Bedingung i<15 erfüllt,
die zweite aber nicht, wenn z.B. variable[1]!=0 ist. Weil aber im
Original eine Veroderung gefordert wird, geht das schief.
Richtig wäre:
Simon K. schrieb:
>> 4) Was hast du gegen ein unsigned char als Zählervariable?> char kommt von Character und das heißt Zeichen. Eine Zählvariable ist> kein Zeichen.
Dann verstecke halt das "Character" hinter einem uint8_t.
Wenn der OP in seiner Frage nicht die stdint-Typen verwendet, dann
verwende ich sie bei Code-Vorschlägen normalerweise auch nicht, um ihn
nicht zusätzlich zu verwirren.
Stefan Ernst schrieb:
> Simon K. schrieb:>>>> 4) Was hast du gegen ein unsigned char als Zählervariable?>> char kommt von Character und das heißt Zeichen. Eine Zählvariable ist>> kein Zeichen.>> Dann verstecke halt das "Character" hinter einem uint8_t.
Da gibt es nichts zu verstecken. Nicht mal in der stdint.h
Implementierung der avr-libc kommt ein unsigned char bei der Deklaration
von uint8_t vor.
> Wenn der OP in seiner Frage nicht die stdint-Typen verwendet, dann> verwende ich sie bei Code-Vorschlägen normalerweise auch nicht, um ihn> nicht zusätzlich zu verwirren.
Habe ich ja auch nicht. Habs nur angemerkt.
Lothar Miller schrieb:
>> Die Funktionsweise deines Algorithmusses liegt komplett in einer Zeile.> Und er funktioniert nicht :-/
Ich korrigiere mich:
der Code passt, ich hatte statt || ein && gelesen :-/
Es ist aber auch schon spät...
Simon K. schrieb:
>> Dann verstecke halt das "Character" hinter einem uint8_t.> Da gibt es nichts zu verstecken. Nicht mal in der stdint.h> Implementierung der avr-libc kommt ein unsigned char bei der Deklaration> von uint8_t vor.
Kannst du genauer ausführen, was du meinst?
Schaue ich in meine stdint.h, dann steht da
typedef unsigned char uint8_t;
In C sollte man aber auch im Hinterkopf behalten, dass char, signed char
und unsigned char anders funktionieren als in den meisten anderen
Sprachen. Tatsächlich ist in C ein char (und Konsorten) ein kleiner
Integer, der bei den Standard-IO Sachen anders behandelt wird. Das ist
per Design so und auch so beabsichtigt.
Die Argumentation, dass char (und vor allen Dingen signed char und
unsigned char) ausschliesslich für Zeichenverarbeitung reserviert sind,
ist in C bei weitem nicht gegeben.
Karl heinz Buchegger schrieb:
> Simon K. schrieb:>>>> Dann verstecke halt das "Character" hinter einem uint8_t.>> Da gibt es nichts zu verstecken. Nicht mal in der stdint.h>> Implementierung der avr-libc kommt ein unsigned char bei der Deklaration>> von uint8_t vor.>> Kannst du genauer ausführen, was du meinst?> Schaue ich in meine stdint.h, dann steht da>> typedef unsigned char uint8_t;
Das ist für die Doxygen Doku.
Guck mal drunter:
Und das Int hat auch nicht viel zu sagen:
---
The base type int is effectively ignored by the compiler, the actual
properties of the new type v4si are defined by the _attribute_. It
defines the machine mode to be used; for vector types these have the
form VnB; n should be the number of elements in the vector, and B should
be the base mode of the individual elements. The following can be used
as base modes:
---
http://www.delorie.com/gnu/docs/gcc/gcc_80.html
Simon K. schrieb:
> Stefan Ernst schrieb:>> 1) "Lesbarkeit" ist meist reine Geschmackssache. Ich finde meine>> Variante lesbarer. Der direkte Zusammenhang von for und if wird dort>> deutlicher. Bei deiner Variante sehen auf den ersten Blick for und if>> wie zwei unabhängige Codeteile aus.> Die Funktionsweise deines Algorithmusses liegt komplett in einer Zeile.
Nein, es sind zwei Zeilen. Und das ist auch der Punkt, der Algorithmus
besteht aus for und if. Bei deiner Variante hat die for-Schleife einen
Körper und ist meilenweit vom if entfernt (auch noch mit einer Leerzeile
dazwischen). Das suggeriert auf den ersten Blick, dass die Schleife
irgendetwas wiederholt ausführt und dass das if nicht direkt dazu
gehört. Bei mir ist die Schleife leer und steht direkt vor dem if. Die
Tatsache, dass for und if eine Einheit bilden und im for lediglich das i
für den Vergleich vorbereitet wird, kommt damit wesentlich deutlicher
rüber. Dass man dann bei diesem "Vorbereiten" vielleicht zweimal
hinschauen muss, finde ich eher zweitrangig, insbesondere da ich so eine
Konstruktion immer mit einem Kommentar versehen würde (if any
variable[x] equals 0).
Aber wie bereits gesagt, Lesbarkeit ist zum großen Teil Geschmackssache.
Simon K. schrieb:
>> typedef unsigned char uint8_t;>> Das ist für die Doxygen Doku.>> Guck mal drunter:
OK.
Hab ich übersehen.
Formal hast du damit recht.
Wenn allerdings die avr-libc Entwickler sich die Mühe machen, in der Dok
einen uint8_t als unsigned int erscheinen zu lassen und es im Verhalten
zu einem unsigned char keinen Unterschied gibt, dann würde ich sage:
Sieht aus wie eine Ente, quackt wie eine Ente, watschelt wie eine Ente
-> ist eine Ente.
>
Als nicht gcc-Entwickler sagt mir das nichts.
Müsste man dasselbe in Standard-C ausdrücken, so würde man wohl
typdef unsigned char uint8_t;
nehmen. Und ich denke mal, ich liege nicht allzufalsch, wenn ich sage,
dass die Mehrzahl der stdint.h Implementierungen genau das tun und auch
das ISO-Gremium nichts dagegen einzuwenden hätte.
Stefan Ernst schrieb:
> Karl heinz Buchegger schrieb:>>> Wie wärs mit>> Mit einem == statt dem != könnte ich auch mit dieser Version leben. ;-)
Ähm.
Nimms als künstlerische Freihet :-)
Danke für die Korrektur
Karl heinz Buchegger schrieb:
> OK.> Hab ich übersehen.>> Formal hast du damit recht.
Ja, nur als Beweis zu meiner obigen Aussage. Ansonsten nicht so wichtig
;)
> Wenn allerdings die avr-libc Entwickler sich die Mühe machen, in der Dok> einen uint8_t als unsigned int erscheinen zu lassen und es im Verhalten> zu einem unsigned char keinen Unterschied gibt, dann würde ich sage:> Sieht aus wie eine Ente, quackt wie eine Ente, watschelt wie eine Ente> -> ist eine Ente.
Sehe ich nicht so. Obige Aussage war, dass man einen unsigned char
hinter einem uint8_t versteckt. Daraus interpretiere ich, dass es
unerheblich ist, ob man nun unsigned char oder den "Umweg" uint8_t
nimmt.
Das ist es aber nicht. Höchstens syntaktisch.
Mit dem Datentyp gibt man ja nicht nur dem Compiler an, welcher Datentyp
benutzt werden soll, sondern man sagt auch allen indirekt im Code aus,
wofür eine Variable gedacht sein soll. Das heißt ich füge ohne große
Umwege zusätzliche nützliche und hilfreiche Informationen dem Code
hinzu. Oder etwa nicht? Darum geht's mir. Auch wenns Geschmackssache ist
und ich hier nicht versuche jemanden zu überzeugen. Wie gesagt, es war
nur angemerkt oben in einem Kommentar ;)
>>
>> Als nicht gcc-Entwickler sagt mir das nichts.
Mir auch nicht :-) War nur als Beweis zu der Aussage oben, auch wenn das
jetzt nen bisschen albern ist von mir :-)
> Müsste man dasselbe in Standard-C ausdrücken, so würde man wohl> typdef unsigned char uint8_t;> nehmen. Und ich denke mal, ich liege nicht allzufalsch, wenn ich sage,> dass die Mehrzahl der stdint.h Implementierungen genau das tun und auch> das ISO-Gremium nichts dagegen einzuwenden hätte.
Ist ja auch alles kein Problem, es ging mir gar nicht im Detail darum,
wie man sich den uint8_t Typen jetzt erzeugt, sondern wie man diesen wo
und warum einsetzt (einsetzen sollte).