Gast
#1921872
Hallo, ich würd euch gern mal fragen wie ihr folgende Code-Zeile ohne PGM_P und pgm_read_byte umschreiben würdet.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
|
Anzeige
|
code umwandeln
Gast
#1921872
Hallo, ich würd euch gern mal fragen wie ihr folgende Code-Zeile ohne PGM_P und pgm_read_byte umschreiben würdet.
Gast
#1921896
so ...
Gast
#1921899
nee so geht ja schon gar nicht, weil PGM_P meines erachtens ein Zeiger ist oder liege ich da falsch. Hintergrund des ganzen ist, dass der Code für einen ATMEGA geschrieben ist ich ihm aber für einen LPC1768 benötige es also keine pgmspace.h mehr gibt folglich alle damit verbundenen Variablen ersetzt werden müssen. Tom schrieb: > weil PGM_P meines erachtens ein Zeiger ist oder liege ich da falsch. Wo ist das #define oder die Typdefinition dazu? > ich würd euch gern mal fragen wie ihr folgende Code-Zeile ohne PGM_P und > pgm_read_byte umschreiben würdet. WELCHE der folgenden Zeilen?
Gast
#1921909
man sollte code nicht 1:1 umschreiben, man soll verstehen was der code macht und dann umschreiben. Man müsste dazu wissen wo die Daten denn herkommen sollen die bis jetzt über pgm_read_word gelesen wurden - woher sollen wir das wissen? Peter schrieb: > man sollte code nicht 1:1 umschreiben, man soll verstehen was der code > macht und dann umschreiben. @TO Da hat Peter recht. Wenn dann noch ein bischen Wissen über typische C-Abläufe dazukommt, dann schreibt sich dieser Code fast von alleine. Einziges Problem: er hängt von genauen Aufbau der Font Strkutur ab. Seine Aufgabe: er liefert aus diesr Fontstruktur den widthtable Pointer, also charset->widthtable. Mehr tut er nicht.
Gast
#1922016
alles klar ich bin schon dabei, jedoch habe ich eine Zeile die ich nicht verstehe, da ich so was noch nie gesehen habe: if(table) also eine if-Anweisung ohne für mich ersichtliche Bedingung, ich wette das steckt was ganz einfaches hinter ich komme aber nicht darauf. table ist ein Zeiger der die Adresse auf ein Array enthält danke =)
Gast
#1922019
in C gilt alles was !=0 == TRUE. Also wenn der zeiger table auf etwas zeigt dann ist die bedingung war. Tom schrieb: > if(table) > > also eine if-Anweisung ohne für mich ersichtliche Bedingung, ich wette > das steckt was ganz einfaches hinter Das 'ganz einfache' besteht aus 2 Teilen * dem if ist es schnurzegal was da in der Klammer steht. Es will einfach nur einen Ausdruck sehen, der ausgewertet entweder 0 ist oder nicht 0 ist * auch ein Vergleich oder eine Zuweisung sind in C nichts anderes als Ausdrücke die einen Wert liefern a < b ist ein arithmetischer Ausdruck, so wie es auch a + b ist. a + b liefert die Summe aus a und b, a < b liefert 0 wenn die Bedingung falsch ist und 1 wenn sie wahr ist. In C ist das hier d = 2 * ( a < b ); absolut zulässig und völlig korrektes C. C unterscheidet nicht zwischen Bedinungen und sonstigen arithmetischen Ausdrücken, so das Bedingungen irgendetwas besonderes wären. Ein < ist genauso wie ein + oder ein * (Multiplikation) einfach nur eine Operation, die ihren linken Operanden mit ihrem rechten Operanden verwurschtet und daraus ein Ergebnis generiert, mit welchem weiter gerechnet werden kann. Wenn dieses Ergebnis (0 oder 1) dem if als Entscheidungskriterium vorgeworfen wird wie es weitergehen soll, dann ist das dem if recht. Aber das if besteht nicht darauf, dass da eine Bedingung steht. Das interessiert sich nur dafür ob der Ausdruck in der Klammer 0 oder nicht 0 ergibt, wenn man ihn auswertet. Mit der Einführung von 'bool' in C99 haben sich die Regeln zwar ein bischen geändert, aber die Quintessenz bleibt immer noch die gleiche. Offensichtlich wollte der Programmierer den Code flexibel halten für Systeme mit 2-Byte großen Zeigern und größeren Zeigern (??große und kleine AVRs)... PGM_P scheint ein Zeiger zu sein. Der Autor hofft wohl, daß der Compiler den unbenutzten if-Zweig rausoptimiert...
Gast
#1922083
vielen dank bis hierher =) ich bin nun auch schon ein bisschen weiter und versuche gerade den folgenden ausdruck auszuwerten: *font_prop_24px_data + 0xFF -0x20 +1 so hinter dem font... versteckt sich ein Array welches einen Zeichensatz enthält nun zeigt da ein Zeiger drauf, ich habe mir schon einiges über Zeiger durchgelesen jedoch die oeben aufgeschriebene Notation nie gefunden, kennt ihr so etwas? Ich kenn das nur wenn alles in klammern stehen würde und somit der Pointer verändert wird sprich das Feld auf das er zeigt ein anderes ist.
Gast
#1922084
ich glaube du solltes erstmal dich genauer mit C beschäften. Wenn es auf beiden seiten ein C compiler ist, dann kannst du die anweisung doch einfach stehen lassen, warum willst du sie umschreiben? a[2] == *(a+2) == 2[a] Tom schrieb: > *font_prop_24px_data + 0xFF -0x20 +1 > > so hinter dem font... versteckt sich ein Array welches einen Zeichensatz > enthält nun zeigt da ein Zeiger drauf, ich habe mir schon einiges über > Zeiger durchgelesen jedoch die oeben aufgeschriebene Notation nie > gefunden, kennt ihr so etwas? Jeder C Programmierer kennt sowas. Er kennt sowas, weil er weiß, dass in C a[d] vom Compiler sofort umgeformt wird zu *(a + d) und damit ist dann a[0] identisch zu *( a + 0 ) und das ist wiederrum identisch zu *a Eventuell solltest du erst mal deine C Kentnisse soweit vervollständigen, dass du zumindest das erste Drittel eines ordinären C Buches soweit intus hast, dass du die Dinge erkennst wenn du sie siehst. Von dem was dann in den restlichen 2/3 des C-Buchs alles zu finden ist, reeden wir erst mal gar nicht.
Gast
#1922093
ich will den teil nicht umschreiben ich will ihn verstehen ob *font_prop_24px_data + 0xFF - 0x20 + 1 das selbe ist wie *(font_prop_24px_data + 0xFF - 0x20 + 1) sprich ob bei dieser Funktion einfach der Zeiger erhöht wird und nun auf ein neues element zeigt
Gast
#1922096
Tom schrieb: > ich will den teil nicht umschreiben ich will ihn verstehen ob > *font_prop_24px_data + 0xFF - 0x20 + 1 das selbe ist wie > *(font_prop_24px_data + 0xFF - 0x20 + 1) > sprich ob bei dieser Funktion einfach der Zeiger erhöht wird und nun auf > ein neues element zeigt es wird nirgends etwas zugewiesen als kann auch kein Zeiger erhöht werden!
Gast
#1922103
der Codeteil steht innerhalb einer Struktur und anschließend wird die adresse dieses Teils einem Zeiger übergeben. Tom schrieb: > ich will den teil nicht umschreiben ich will ihn verstehen ob > *font_prop_24px_data + 0xFF - 0x20 + 1 das selbe ist wie > *(font_prop_24px_data + 0xFF - 0x20 + 1) Ach komm. Das sind doch einfache Grundlagen der Operatoren Reihenfolge (Operator Precedence). Der Dereferenzier-* bindet stärker als das + http://www.difranco.net/cop2220/op-prec.htm Daher: Nein, das ist nicht dasselbe
Gast
#1922194
soweit war ich auch also das es nicht das selbe sein kann. Aber kann mir jemand auf die Sprünge helfen was dort passiert, also was das +0xFF-0x20+1 mit dem Zeiger anstellen.
Gast
#1922196
Tom schrieb: > also was das +0xFF-0x20+1 mit dem Zeiger anstellen überhaupt nichts, es wird nur der Wert verwendet Tom schrieb: > soweit war ich auch also das es nicht das selbe sein kann. > Aber kann mir jemand auf die Sprünge helfen was dort passiert, also was > das +0xFF-0x20+1 mit dem Zeiger anstellen. Du hast es immer noch nicht. Mit dem Zeiger passiert dort überhaupt nichts mehr. Es wird der Wert geholt, auf den der Zeiger zeigt *font_prop_24px_data -> ergibt einen Wert und mit diesem Wert wird dann weiter gerechnet dieser Wert + 0xFF - 0x20 + 1 wozu auch immer das gut sein soll. Die 0x20 könnten wieder mal der Versuch sein, seinen Code als besonders schlau zu verkaufen, indem da der ASCII Code eines Leerzeichens eingesetzt wird. Das ist aber nur eine Vermutung basierend darauf, dass es hier um Fonts geht und in Fonttabellen die Pixeldaten gerne erst beim ASCII-Zeichen ' ' anfangen um damit etwas Platz zu sparen.
Gast
#1923536
so so so hab mir nun alles mal ganz genau angeschaut und auch verstanden was der Code tun soll, habe mich nun ans Umschreiben gemacht und stoße dabei auf folgendes Problem. Und zwar geht es um den folgenden Abschnitt:
Hierbei soll aus einer Struktur der Teil data herausgelesen werden und die Anfangsadresse der Daten mit tmp zurückgegeben werden in der Strukur steht an der Stelle data folgendes :
Hierbei wird der Zeiger verschoben sodass er auf dem Datenteil der Table von font_proportional_16pc_data steht. So da ich ja mit einem anderen Controller arbeite habe ich den Code folgendermaßen verändert
diese Funktion wird nun in einem Teil für die genaue Position des Zeichens in der Datentabelle benötigt
Hierbei wird der Zeiger der Tabelle soweit verschoben bis er man richtigen Punkt angelangt ist. ret wird vorher erzeiugt und die height_bytes sind für jedes Zeichen gleich und in meinem Fall sind dies 2. Nun ist mein Problem, dass der Compiler in eben dieser Zeile mir ausgibt: warning: return makes integer from pointer without a cast meiner meinung nach hängt dies mit dem data zusammen weil ich ja hier über einen Zeiger auf eine Struktur zugreife, ich weiß aber nicht was falsch ist. Wenn jemand Ahnung hat immer her damit =) Poste vollständigen Quelltext, sonst kann Dir nicht geholfen werden.
Gast
#1923572
naja ich dachte es ist so einfacher wenn ich das schritt für schritt mache dann eben so erstmal der alte Text
und hier in der neuen Variante wo aber wie gesagt etwas nciht stimmt beim font_data undfont_widthtable
Gast
#1923575
hier nocheinmal die Strutkur
Gast
#1923820
okay so ein ganzer Code ist auch doof zu lesen mal in kurz: seh ich das richtig tmp = (PGM_P)pgm_read_word(&(charset->data)); charset->data =pointer ist das gleiche wie tmp = charset.data wobei sich hinter charset.data ein pointer verbirgt und der Rückgabewert der Funktion hier auf ein Pointer ist. Was um alles in der Welt hast du blos aus dem Originalcode gemacht. <Kopfschüttel>
Gast
#1923906
ich habe ihn mir angesehen und ihn auch verstanden was wie wo hin muss mir fehlt leider das fahcwissen darüber wie ich z.B. das Array aus der Struktur auslese und einen Zeiger auf das erste Feld lege. ich erhalte mitlerweile von meinem Compiler auch keine warnungen mehr jedoch funktioniert das einlesen der Tabelle meiner meinung nach nicht. Tom schrieb: > typedef const struct font_info FONT_P; Das ist Unsinn. FONT_P war im Originalcode gedacht als Datentyp für einen Pointer. Dieser Pointer auf eine Font Struktur wurde an Funktionen weitergereicht, damit die dann Einzelinformationen aus der Struktur auf die sie einen Pointer erhalten haben herausholen können. Verkompliziert wurde das im Original dadurch, dass es sich um keinen SRAM Pointer handelte, sondern das der Pointer auf Daten im Flash zeigte. Dadurch war es nicht mehr einfach möglich zu sagen charset->width um an die Breite eines Zeichens zu kommen, wie man das normalerweise machen würde, sondern man musste den Umweg über die pgm_.... Funktionen gehen. Aber: Die Funktionen sollen nach wie vor einen Pointer auf die Fontstuktur bekommen! Du willst doch nicht ständig Strukturen komplett umkopieren!
Da ich das hier nicht testen kann, bin ich nicht sicher ob das jetzt so stimmt, aber soweit dürfte ich nicht daneben liegen Warte noch, da sind noch Fehler Edit: Ich denke, ich hab jetzt die meisten Fehler, die du beim Ausbau der Flash-Zugriffe gemacht hast im vorhergehenden Code korrgiert. Tom schrieb: > ich habe ihn mir angesehen und ihn auch verstanden was wie wo hin muss > mir fehlt leider das fahcwissen darüber wie ich z.B. das Array aus der > Struktur auslese und einen Zeiger auf das erste Feld lege. > ich erhalte mitlerweile von meinem Compiler auch keine warnungen mehr > jedoch funktioniert das einlesen der Tabelle meiner meinung nach nicht. Wenn du Datenstrukturen nicht verstehst, dann mal sie dir auf einen Zettel auf! Die Technik funktioniert perfekt um sich einen Überblick zu verschaffen, wie eine Datenstruktur aufgebaut ist und wie sie benutzt werden will. Aber einfach so nach Gutdünken in einer Datenstruktur herumfuhrwerken führt nur zu Fehlern.
Gast
#1923956
so ich habe das mal eingebunden und in folgenden zeilen
noch die Warnung assignment makes integer from pointer without a cast Die Funktion font_data liefert als Rückgabewert einen Pointer. Die erste derartige Warnung kommt hier
und es muss lauten
Die von dir gezeigten Zeilen bringen die Warnung warning: return discards qualifiers from pointer target type und die Lösung sollte offensichtlich sein, wenn man sich mal den Datentyp ansieht, den der Ausdruck beim return generiert und mit dem Datentyp des Rückgabewertes der Funktion vergleicht.
Gast
#1924036
bist du dir da sicher? ich geh ind er Funktion an die richtige Stelle in dem Datenarray wo meine Breite verzeichnet ist und table zeigt auf die erste Zeile und font_get_char_number(charset,character) sagt mir wieviele ich weiterrutschen muss. hab da noch ne frage zu deiner änderung von tmp = tableposition+i zu tmp = tableposition[i] an dieser stelle wird meiner meinung nach die position der Datentabelle verändert, dann ergibt für mich tableposition[i] keinen sinn Tom schrieb: > bist du dir da sicher? Ja Bin ich Tom schrieb: > an dieser stelle wird meiner meinung nach die position der Datentabelle > verändert, dann ergibt für mich tableposition[i] keinen sinn Du hast return pgm_read_byte(table+font_get_char_number(charset,character)); zu return table+font_get_char_number(charset,character); übersetzt. Das ist aber falsch. Ein i = pgm_read_byte( a ); wird zu einem i = *a; denn genau das macht pgm_read_byte. Das Byte holen, welches an der Adresse a im Speicher sitzt. Wenn also im Original das Byte geholt wird, welches vom Tabellenanfang x Zeichen entfernt ist pgm_rad_byte( table + x ); dann ist das in Nicht-Flash-Schreibweise ganz einfach table[x] Das pgm_read_byte beinhaltet eine implizte Dereferenzierung! Und *(table+x) ist nun mal identisch zu table[x] Du hast bei deiner Übersetzung an manchen Stellen einfach das pgm_read_byte unter den Tisch fallen lassen. Das darfst du aber nicht! Wenn schon, dann hättest du es mit einem Derferenzier-* ersetzen müssen. Und daraus ergeben sich dann natürlich an anderen Stellen Möglichkeiten für Vereinfachungen. Aus return pgm_read_byte( &charset->width ); wird dann return * &charset->width; und da die Dereferenzierung eines Ausdrucks von dem man die Adresse nimmt, der Ausdruck selber ist, vereinfacht das dann zu return charset->width; Hier ist nicht nur das pgm_read_byte weggefallen sondern auch das &. Dies deshalb weil *& eine 0-Operation ist. Nur dort wo du keinen Adressoperator im pgm_read_byte hast, kannst du nicht einfach nur das pgm_read_byte weglassen, sondern du musst tatsächlich den langen Weg gehen und pgm_read_byte durch einen * ersetzten und dann nachehen ob du etwas vereinfachen kannst.
Gast
#1924053
okay danke, kann mir noch jemand sagen wie ich den Rückgabewert (Pointer) anpassen kann bzw so mache,dass er verarbeitet werden kann Tom schrieb: > okay danke, kann mir noch jemand sagen wie ich den Rückgabewert > (Pointer) anpassen kann bzw so mache,dass er verarbeitet werden kann Der Ausdruck beim Return hat welchen Datentyp? Die Funktion hat welchen Datentyp in ihrer Vereinbarung des Returnwertes? Daraus folgt dann das weitere Vorgehen.
Gast
#1924066
also ich muss nen zeiger zurückgeben und habe zur verarbeitung einen zeiger plus einem Wert Tom schrieb: > also ich muss nen zeiger zurückgeben Du hast nicht einfach nur einen Zeiger. Auch Zeiger haben Datentypen! Nämlich den Datentyp des Objektes auf welches sie zeigen! Ein Zeiger der auf einen int zeigt, ist datentypmässig nicht dasselbe wie ein Zeiger der auf einen double zeigt! Auch wenn beides Zeiger sind. > und habe zur verarbeitung einen > zeiger plus einem Wert Also: welche Datentypen hast du? Beim return hast du return (font_data(charset) + ret*font_get_height_bytes(charset)); font_data(charset) ist ein Ausdruck, genauer ein Funktionsaufruf. Welchen Datentyp liefert diese Funktion zurück?
Gast
#1924081
also meine drei hinteren werte sind vom typ int und die Rückgabe der Funktion ist const char Tom schrieb: > also meine drei hinteren werte sind vom typ int ? Welche 3 hinteren Werte > und die Rückgabe der > Funktion ist const char ? Hier ist die Funktion const char* font_data(FONT_P charset) { ... } ihr Rückgabetype ist 'const char*' also ein Pointer auf einen Character und diese Character ist als konstant anzusehen, kann also nicht verändert werden. Damit hast du return (font_data(charset) + ret*font_get_height_bytes(charset)); | | | | Der Teil hier hat den Datentyp const char* Die Addition zu einem Pointer ergibt wieder einen Pointer (genauso ist in C letzten Endes der Arrayzugriff definiert) wobei sich der Datentyp des Pointers nicht ändert. D.h. dieser komplette Ausdruck font_data(charset) + ret*font_get_height_bytes(charset)); hat immer noch den Datentyp 'const char*' und die Funktion in der dieser return steht, sagt von sich selber, das sie was zurückliefert? char* font_get_char_position(FONT_P charset, unsigned char character) { Die Funktion liefert einen 'char*' Ein 'const char*' ist aber nicht dasselbe wie ein 'char*'
Gast
#1924915
hm okay alles klar das leuchtet mir alles ein =) Danke das Programm läuft aber leider immer noch nicht auch jetzt ohne Warnungen und Fehler ... hm
Gast
#1924936
so hab mich mal an die "Fehlersuche" gemacht und zwar mittels LEDs die angehen sollen wenn das Programm an bestimmten Punkten angelangt ist. der erste Punkt des Programmes ist font_get_char_width
hierbei geht die erste LED an, die zweite geht im font_widthtable geht auch an und die dritte hinter der Funktion bleibt jedoch aus ...
Gast
#1924938
hinter der struktur fehlt noch
Tom schrieb: > hierbei geht die erste LED an, die zweite geht im font_widthtable geht > auch an und die dritte hinter der Funktion bleibt jedoch aus ... wie rufst du das ganze auf? Ist der charset Pointer, der da überall reingegeben wird korrekt?
Gast
#1925010
über lcd_draw_char(font_vw_24px, NORMAL_STYLE,'-',30, 70, 255); mittlerweile durchläuft er das ganze programm auch und zeigt mir was an es sieht den zeichen auch ähnlich jedoch sind ein paar pixel falsch angeordnet, sprich irgendwas beim auslesen passt so nicht ganz Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|