Duale Eingabe in C-Programm
-
Was ist denn heute nur los?
char binstr[SIZE]; fgets(binstr, SIZE, stdin); long zahl1 = strtol(binstr, NULL, 2); // wenn du das nochmal mit einem 'long zahl2' machst, dann geht das XOR so: long xored = zahl1 ^ zahl2;
Wenn du statt NULL noch die Adresse eines char-Zeigers mitgibst, kannst du auch noch alle möglichen Fehler abfangen.
Wenn ich später mal nen Controler Programmiere muss ich auch darauf achten den Quellcode so klein wie möglich zu halten, damit das Programm schnell und platzsparend abläuft.
War das nicht kurz genug? Btw: was hat denn die Codegrösse mit der Laufzeit zu tun?
-
damit das Programm schnell und platzsparend abläuft
Und dann holst du so ein Monster wie scanf() an Bord?
-
µngbd schrieb:
damit das Programm schnell und platzsparend abläuft
Und dann holst du so ein Monster wie scanf() an Bord?
Würde mich auf eine Erklärung freuen...
Wie ist mit 'Monster' gemeint?
-
Da ich nicht unnötig vielen Code schreiben möchte wenns auch einfach geht.
Dann nimm eine andere Sprache, C++ oder Java oder Haskell oder ... bieten sich an.
Als Alternative von scanf bietet sich vielleicht die Moeglichkeit an, deine Binaerzahlen als String per Kommandozeilenargument einzugeben. Die Umwandlung erfolgt dann von hinten nach vorne, indem entweder eine 1 oder 0 (abhaengig vom char-Wert "1" oder "0") geshiftet wird. Oder du verwendest das schon angesprochene strol().
-
sunny31 schrieb:
µngbd schrieb:
Und dann holst du so ein Monster wie scanf() an Bord?
Würde mich auf eine Eklärung freuen...
Wie ist 'Monster' gemeint?Naja, scnaf() muss die ganze Logik irgendwo bereitstellen, um die Formatstring-Syntax zu verstehen. Wenn Speicher und Laufzeit knapp sind, könnte es sich schon mal auszahlen, scanf(), printf() und ihre Brüder ganz raus zu nehmen. Die gehören sicher zu den aufwändigsten Funktionen in der ganzen Standard-Bibliothek.
Mir fällt das immer wieder ein, wenn ich sowas sehe:
char c; scanf("%c", &c); // statt getchar() // oder char s[SIZE]; scanf("%s ", s); // statt fgets()
Das ist natürlich Wahnsinn. Zahlen einlesen ist ja noch in Ordnung, aber die Standard-Formatstrings können eben keine Binärdarstellungen, obwohl manche Compiler %b (für Binärdarstellungen) kennen. Dafür gibt es im Standard aber strtol().
-
Chris12 schrieb:
Wenn ich später mal nen Controler Programmiere muss ich auch darauf achten den Quellcode so klein wie möglich zu halten, damit das Programm schnell und platzsparend abläuft.
dann mach dir doch 'ne funktion, die einen string aus nullen und einsen in eine zahl umwandeln kann, ist nicht mehr als ein drei- oder vierzeiler.
knivil schrieb:
Da ich nicht unnötig vielen Code schreiben möchte wenns auch einfach geht.
Dann nimm eine andere Sprache, C++ oder Java oder Haskell oder ... bieten sich an.
ich weiss ja nicht, ob haskell schnellen, kleinen maschinencode erzeugen kann, aber Java z.b. braucht im normalfall eine virtual machine o.ä. und c++ ...ähm, *räusper*
-
fricky schrieb:
ich weiss ja nicht, ob haskell schnellen, kleinen maschinencode erzeugen kann
Glaub ich nicht. Das Ding ist lazy. Im besten Fall kommt wahrscheinlich immer noch eine riesige Runtime-Bib. dazu (ausser man baut alles aus den Axiomen zusammen, aber das ist wiederum eine epische Laufzeitverschwendung). Und den Compiler verstehen dann sicher nur mehr drei Leute auf der Welt.
fricky schrieb:
und c++ ...ähm, *räusper*
C++ hat sicher irgendeinen Zauberspruch, den man zwischen
cin
und die Variable schreiben muss, damit die Zahl zur Basis 17 genommen wird. Fragt dann wahrscheinlich insgeheim bei strtol() nach, weil Zaubern gar nicht so einfach ist, und deshalb von einem Magier geerbt werden muss.
-
Ok erstmal Danke für die nette Diskussion.
Die anregungen haben mir geholfen mein Problem zu lösen.Leider darf ich keine andere Sprache als C nehmen. Da ich momentan im 1.Semester nur ANSI C behandele.
Bisher haben wir da irgendwie überwiegend mit scanf gearbeitet, deshalb habe ich es benutzt. Ich poste mal meine bisherige Lösung, das Programm ist noch nicht fertig aber bin damit als ersten Zwischenschritt zufrieden.
Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.
#include <stdio.h> #include <string.h> #include <stdlib.h> #define BUF 255 char HammingDistance(char Code[],char Code2[]) { int array_groese,Hamming; char i; char v[80]={' '}; array_groese =0; Hamming =0; while (Code[array_groese]!='\0'){array_groese++;}//Größe des String-Arrays bestimmen for (i=0;i<=array_groese-1;i++){if ((Code[i]^Code2[i])==1){Hamming=Hamming+1;}} printf("Haben die Hamming Distance : %d\n",Hamming); printf("\n"); return(Hamming); } void Sort(int value[],int CodewörterAnzahl) { int i,j; char buf[BUF]; char buf2[BUF]; //Vergleicht alle Codewörter mit einander for(i=0;i<=CodewörterAnzahl-1;i++) { for(j=(i+1);j<=CodewörterAnzahl-1;j++) { itoa(value[i], buf, 10); itoa(value[j], buf, 10); printf("Codewort %d & Codewort %d\n",value[i],value[j]); HammingDistance(itoa(value[i], buf, 10),itoa(value[j], buf2, 10)); } } } #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { int *value; int size, i = 0; printf("Wie viele Werte benötigen Sie : "); scanf("%d", &size); value = (int *)malloc(size*sizeof(int)); if( NULL == value ) { printf("Fehler bei malloc....\n"); return EXIT_FAILURE; } while( i < size ) { printf("Wert für value[%d] eingeben : ", i); scanf("%d", &value[i]); i++; } printf("Hier Ihre Werte\n"); for(i=0; i < size; i++){ printf("value[%d] = %d\n", i, value[i]);} Sort(value,size); return EXIT_SUCCESS; }
-
Ich habe jetzt nur noch ein Problem:
Wenn ich 0100 eingeben wird an die Funktion 100 übergeben was mir auch logisch erscheint. Wie könnte ich die führende 0 erhalten?
-
µngbd schrieb:
... ... ...
Wie immer bin ich dir dankbar für deine Erklärungen. :xmas1:
-
Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.
Warum nicht
int
's (oder sowas) für die Zahlen nehmen und das XOR den Prozessor in einem Schritt machen lassen? Dann könntest du dir den ganzen itoa()-Wahnsinn sparen. Der ist nämlich echt völlig unnötig.
-
µngbd schrieb:
Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.
Warum nicht
int
's (oder sowas) für die Zahlen nehmen und das XOR den Prozessor in einem Schritt machen lassen? Dann könntest du dir den ganzen itoa()-Wahnsinn sparen. Der ist nämlich echt völlig unnötig.
Meinst du in der Hamming Funktion ?
Wenn ja habe ich das deshalb gemacht das ich die 1 aus dem XOR Produkt zählen kann.Als Bsp.: Wenn ich die Zahlen 1010 und 1111 als int übergeben würde und diese XOR Verknüpfe bekäme ich als Return ja ne 5 (Binär 101). Da wüsste ich jetzt nicht wie ich die 1 zählen kann. Dann müsste ich ja erst wieder die 5 in ne Dualzahl mittels ner Funktion umwandeln, diese in einem String speichern und dann die Anzahl von 1en Zählen.
Deshalb dachte ich mir das ich die String umwandlung gleich am Anfang vornehme.
Nur habe ich immer noch das Problem mit der führenden 0, die dann ja abgesägt wird.
-
µngbd schrieb:
ausser man baut alles aus den Axiomen zusammen, aber das ist wiederum eine epische Laufzeitverschwendung
es gibt eine programmiersprache, die mit 'axiomen' arbeitet? wie geht das? oder bedeutet der begriff da was anderes?
µngbd schrieb:
C++ hat sicher irgendeinen Zauberspruch, den man zwischen
cin
und die Variable schreiben muss, damit die Zahl zur Basis 17 genommen wird. Fragt dann wahrscheinlich insgeheim bei strtol() nach, weil Zaubern gar nicht so einfach ist, und deshalb von einem Magier geerbt werden muss.in c++ macht man sowas mit templates, dabei rechnet der compiler die werte für alle möglichen bitmuster eines 'unsigned' im voraus aus und speichert sie in einem 4GB array *fg*
Chris12 schrieb:
Leider darf ich keine andere Sprache als C nehmen. Da ich momentan im 1.Semester nur ANSI C behandele.
C ist schon ok, für low-leveliges bitgewurschtel gibt es kaum besseres.
Chris12 schrieb:
Vielleicht hat ja der ein oder andere noch ein paar optimierungs tips.
deine hammingdistanz-funktion sieht seltsam aus. wenn sie mit strings arbeiten soll (und es sieht so aus), dann hat das XOR dort doch nichts verloren. vorschlag (ungetestet):
// geht davon aus, dass beide strings gleich lang sind int HammingDistance (char Code[],char Code2[]) { int Hamming; for (Hamming=0; *Code; Code++, Code2++) if (*Code != *Code2) Hamming++; return Hamming; }
Chris12 schrieb:
Wenn ich 0100 eingeben wird an die Funktion 100 übergeben was mir auch logisch erscheint. Wie könnte ich die führende 0 erhalten
bei der ausgabe z.b. kannste ja vorn nullen anhängen soviel du willst.
-
fricky schrieb:
deine hammingdistanz-funktion sieht seltsam aus. wenn sie mit strings arbeiten soll (und es sieht so aus), dann hat das XOR dort doch nichts verloren. vorschlag (ungetestet):
// geht davon aus, dass beide strings gleich lang sind int HammingDistance (char Code[],char Code2[]) { int Hamming; for (Hamming=0; *Code; Code++, Code2++) if (*Code != *Code2) Hamming++; return Hamming; }
Wenn ich das richtig erkenne würde dann allerdings deine Funktion nur überprüfen ob die beiden Codewörter unterschidlich sind. Ich muss allerdings die enthaltenen 1 aus dem XOR Produkt der beiden Codwörter zählen.
fricky schrieb:
bei der ausgabe z.b. kannste ja vorn nullen anhängen soviel du willst.
Ich brauche die aber nicht bei der Ausgabe sondern bei der Übergabe an die Hamming Distance.
Bsp.:
0101
1111
----
1010 Hamming Distance von 2Da der Rechner aber die 0 abschneidet kommt das raus:
101
1111
----
010 HD von 1
-
Ok hab gerade deine Funktion getestet, die funktioniert einwandfrei, ich verstehe allerdings nicht wieso.
-
fricky schrieb:
es gibt eine programmiersprache, die mit 'axiomen' arbeitet? wie geht das? oder bedeutet der begriff da was anderes?
Das ist ein lustiger Sport in funktionalen Sprachen, nämlich möglichst alle Funktionen durch andere definieren, und zwar solange, bis nur mehr eine Handvoll überbleibt. Die werden dann gerne Axiome ganannt, wahrscheinlich um damit anzugeben, dass es nur so wenige sind. Mit Sprachen die nur bei Bedarf auswerten, geht das echt wunderbar, weil zB ein
if
eine ganz normale Funktion sein kann.Chris12 schrieb:
Wenn ja habe ich das deshalb gemacht das ich die 1 aus dem XOR Produkt zählen kann.
Aber eine Lösung für int's zu finden, wäre nicht wirklich schwer gewesen:
http://en.wikipedia.org/wiki/Hamming_distance#Algorithm_example
-
Chris12 schrieb:
Wenn ich das richtig erkenne würde dann allerdings deine Funktion nur überprüfen ob die beiden Codewörter unterschidlich sind. Ich muss allerdings die enthaltenen 1 aus dem XOR Produkt der beiden Codwörter zählen.
XOR kannst nehmen, wenn die codewörter binär vorliegen (die summe der 1-bits ist dann die hamming-distanz). aber wenn du strings (0 und 1 als ascii-zeichen) verwendest, dann musste eigentlich nur die unterschiede zählen.
Chris12 schrieb:
fricky schrieb:
bei der ausgabe z.b. kannste ja vorn nullen anhängen soviel du willst.
Ich brauche die aber nicht bei der Ausgabe sondern bei der Übergabe an die Hamming Distance.
klar, dafür müssen die strings gleich lang sein. also, den kürzeren vorn mit nullen auffüllen, bis er so lang ist, wie der längere.
Chris12 schrieb:
Ok hab gerade deine Funktion getestet, die funktioniert einwandfrei, ich verstehe allerdings nicht wieso.
na, die zählt einfach nur ungleiche zeichen. so ist doch die hamming-distanz definiert, oder verwechsle ich das jetzt mit irgendwas?
-
[/quote]
na, die zählt einfach nur ungleiche zeichen. so ist doch die hamming-distanz definiert, oder verwechsle ich das jetzt mit irgendwas?
:)[/quote]Ne ne das stimmt schon so, habs beim Debuggen auch gecheckt, ich verstehe nur nicht wie die for schleife funktioniert.
Ich habe bisher die for schleife nur so kennengelernt for(i=0; i<=x ;i++)
Ich verstehe die Schleifenbedingung nicht so ganz weil du sagst ja, wenn ich das richtig verstehe, das die schleife solange laufen soll wie der Zeiger auf Code ist und zählst dann Code und Code2 hoch.
-
na, die zählt einfach nur ungleiche zeichen. so ist doch die hamming-distanz definiert, oder verwechsle ich das jetzt mit irgendwas?
Könnte man meinen, weil's Wikipedia in dem Python-Beispiel genauso macht. Aber ich glaub auch, dass das so stimmt.
Ich verstehe die Schleifenbedingung nicht so ganz weil du sagst ja, wenn ich das richtig verstehe, das die schleife solange laufen soll wie der Zeiger auf Code ist und zählst dann Code und Code2 hoch.
while (*Code != '\0') // Solange der Zeiger auf ein Byte zeigt, das kein "Nullzeichen" ist // "Nullzeichen" sind einfach nur Null, deshalb ist das gleiche das wie while (*Code != 0) // und weil ein != entweder Null oder Eins ergibt, ist das das gleiche wie while (*Code)
Man gewöhnt sich gerne dran.
-
Chris12 schrieb:
Ich habe bisher die for schleife nur so kennengelernt for(i=0; i<=x ;i++)
Ich verstehe die Schleifenbedingung nicht so ganz weil du sagst ja, wenn ich das richtig verstehe, das die schleife solange laufen soll wie der Zeiger auf Code ist und zählst dann Code und Code2 hoch.in for-schleifenköpfe kannste alles mögliche einbauen, for (a;b;c) heisst
a - initialisierung, geschieht nur vor dem ersten schleifendurchlauf (kann auch vor die for-anweisung gesetzt werden).
b - abbruchbedingung, wenn b==0 dann ist schluss.
c - was nach jedem schleifendurchlauf gemacht werden soll (kann auch ganz unten in der schleife stehen).