![]() |
ENGLISH VERSION |
|
![]() |
Links | | | Forum | | | Kommentare | | | News melden |
![]() |
Chat | | | Umfragen | | | Newsticker | | | Archiv |
![]() |
amiga-news.de Forum > Programmierung > imsg zeug in C | [ - Suche - Neue Beiträge - Registrieren - Login - ] |
-1- 2 3 | [ - Beitrag schreiben - ] |
16.08.2007, 23:55 Uhr MaikG Posts: 5172 Nutzer |
Nun hab ich mal ein einfaches Gadtools-C beispiel gefunden, leider fehlt da ausser Refresh+Windowclose alle abfragen. Ich brauche das ergebniss von mess->IAddress und den searchstring aus dem Stringgadget. Aber C ist so unnötig kompliziert, ich bekomme ständig compilerfehler: code:#include <proto/exec.h> #include <proto/dos.h> #include <proto/intuition.h> #include <proto/graphics.h> #include <proto/gadtools.h> #include <string.h> int main (void) { struct Screen *scr; struct Window *win; struct IntuiMessage *mess; struct Gadget *glist = NULL; struct Gadget *gad; struct NewGadget ng = {0}; BOOL terminated; UWORD thetopborder; UWORD gid; ULONG myimsgCode; WORD ret; UBYTE searchstring[64]; ULONG selgad; if (scr = LockPubScreen (NULL)) { gad = CreateContext (&glist); ng.ng_VisualInfo = GetVisualInfo (scr,TAG_END); ng.ng_TextAttr = scr->Font; thetopborder=scr->WBorTop+scr->Font->ta_YSize+1; ng.ng_LeftEdge = 80; ng.ng_TopEdge = 10+thetopborder; ng.ng_Width = 160; ng.ng_Height = 18; ng.ng_GadgetText = "Searchstring"; ng.ng_GadgetID = 0; gad = CreateGadget (STRING_KIND,gad,&ng,TAG_END); ng.ng_LeftEdge = 30; ng.ng_TopEdge = 40+thetopborder; ng.ng_Width = 80; ng.ng_Height = 16; ng.ng_GadgetText = "Okay"; ng.ng_GadgetID = 1; gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); ng.ng_LeftEdge = 150; ng.ng_TopEdge = 40+thetopborder; ng.ng_Width = 80; ng.ng_Height = 16; ng.ng_GadgetText = "Abbruch"; ng.ng_GadgetID = 2; gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); if (gad) { if (win = OpenWindowTags (NULL, WA_Left,100, WA_Top,100, WA_InnerWidth,250, WA_InnerHeight,60, WA_Title,"Search string", WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_ACTIVATE, WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | STRINGIDCMP | BUTTONIDCMP, WA_Gadgets,glist, TAG_END)) { GT_RefreshWindow (win,NULL); SetFont (win->RPort,scr->RastPort.Font); terminated = TRUE; do { if (Wait ((1L << win->UserPort->mp_SigBit) | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) terminated = FALSE; while (mess = GT_GetIMsg (win->UserPort)) selgad = (struct Gadget *) mess->IAddress; myimsgCode = mess->Code; { switch (mess->Class) { case IDCMP_GADGETDOWN | IDCMP_MOUSEMOVE | IDCMP_GADGETUP: switch(selgad) { case 0: searchstring=selgad->GadgetSpecialnfo->StringInfoBuffer; case 1: ret=1; case 2: ret=0; } case IDCMP_CLOSEWINDOW: terminated = FALSE; break; case IDCMP_REFRESHWINDOW: GT_BeginRefresh (win); GT_EndRefresh (win,TRUE); break; } GT_ReplyIMsg (mess); } } while (terminated); CloseWindow (win); } else Printf ("cannot open windown"); } else Printf ("cannot create gadgetsn"); FreeGadgets (glist); if (ng.ng_VisualInfo) FreeVisualInfo (ng.ng_VisualInfo); UnlockPubScreen (NULL,scr); } else Printf ("cannot lock public screenn"); return (0); } [ Dieser Beitrag wurde von MaikG am 17.08.2007 um 10:35 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 09:51 Uhr Holger Posts: 8116 Nutzer |
Zitat:C mag kompliziert und grottig sein, aber wenn Du nicht mal über das, was Du machst, nachdenkst, wirst Du in keiner Sprache Erfolg haben. Zitat:Was genau soll diese Variable beinhalten? Zitat:Wie passt das dazu? Ist selgrad ein Gadget oder ein ULONG? Zitat:Wo kommen denn jetzt diese Zahlen wiederum her? 0 ... 1 .. 2 Wenn sie eine Bedeutung haben, definiere dafür auch die entsprechenden Konstanten. Aber das erklärt nicht, wie der passende Wert in selgrad kommen soll. Wenn Du sie aus dem Gadget (z.B. als ID) lesen willst, musst Du sie vorher beim Anlegen auch angeben... mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 10:34 Uhr MaikG Posts: 5172 Nutzer |
>C mag kompliziert und grottig sein, aber wenn Du nicht mal über das, was Du machst, nachdenkst, wirst Du in keiner Sprache Erfolg haben. Ich denke schon Stunden darüber nach. In Basic mach ich so ein Programm in weniger als 3 Minuten. > ULONG selgad; >Was genau soll diese Variable beinhalten? In basic ist es dieses: gad& = PEEKL(imsg&+IAddress) also im prinzip nichts anderes als die Nummer des Gadget welches gedrückt/geentert etc. wurde. > selgad = (struct Gadget *) mess->IAddress; >Wie passt das dazu? weiss nicht hab das irgendwo gefunden. >Ist selgrad ein Gadget oder ein ULONG? Selgad soll die Nummer des gewählten Gadgets enthalten. 0 ist das String gadget 1 Button okay 2 Button abbrechen > Wenn Du sie aus dem Gadget (z.B. als ID) lesen willst, musst Du > sie vorher beim Anlegen auch angeben... Ja, hab ich doch auch. Ich mach gleich nochmal den gesamten source rein. [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 12:28 Uhr Der_Wanderer Posts: 1229 Nutzer |
gad& = PEEKL(imsg&+IAddress) In C wäe das: struct Gadget *selgad = imsg->IAddress; D.h. selgad darf nicht vom typ ULONG sein, da es ein Pointer auf das Gadget ist. In Basic würdest du mit "Select gad&" aber auch scheitern. Richtig wäre: switch(selgad->GadgetID) case 0 ... Du verwechselst den Pointer auf das Gadget mit seiner ID, welches ein Eintrag in der Gadgetstruktur ist. In Basic müsstest du wohl Select PEEKW(selgad&+GadgetID) case 0 ... machen. Erst denken, dann programmieren ;-) -- Thilo Köhler, Author von: HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr... Homepage: http://www.hd-rec.de [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 12:52 Uhr thomas Posts: 7719 Nutzer |
@MaikG: Ich habe dein Programm mal korrigiert. Die Kritik überlasse ich den anderen, das wäre sonst zu vernichtend. Nur einem möchte ich mich anschließen: erst nachdenken, dann tippen. C code:#include <proto/exec.h> #include <proto/dos.h> #include <proto/intuition.h> #include <proto/graphics.h> #include <proto/gadtools.h> #include <string.h> int main (void) { struct Screen *scr; struct Window *win; struct IntuiMessage *mess; struct Gadget *glist = NULL; struct Gadget *gad; struct NewGadget ng = {0}; BOOL running; UWORD thetopborder; ULONG myimsgCode; WORD ret; UBYTE searchstring[64] = ""; UBYTE *stringptr; ULONG selgad; if (scr = LockPubScreen (NULL)) { gad = CreateContext (&glist); ng.ng_VisualInfo = GetVisualInfo (scr,TAG_END); ng.ng_TextAttr = scr->Font; thetopborder=scr->WBorTop+scr->Font->ta_YSize+1; ng.ng_LeftEdge = 80; ng.ng_TopEdge = 10+thetopborder; ng.ng_Width = 160; ng.ng_Height = 18; ng.ng_GadgetText = "Searchstring"; ng.ng_GadgetID = 0; gad = CreateGadget (STRING_KIND,gad,&ng,TAG_END); ng.ng_LeftEdge = 30; ng.ng_TopEdge = 40+thetopborder; ng.ng_Width = 80; ng.ng_Height = 16; ng.ng_GadgetText = "Okay"; ng.ng_GadgetID = 1; gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); ng.ng_LeftEdge = 150; ng.ng_TopEdge = 40+thetopborder; ng.ng_Width = 80; ng.ng_Height = 16; ng.ng_GadgetText = "Abbruch"; ng.ng_GadgetID = 2; gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); if (gad) { if (win = OpenWindowTags (NULL, WA_Left,100, WA_Top,100, WA_InnerWidth,250, WA_InnerHeight,60, WA_Title,"Search string", WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_ACTIVATE, WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | STRINGIDCMP | BUTTONIDCMP, WA_Gadgets,glist, TAG_END)) { GT_RefreshWindow (win,NULL); SetFont (win->RPort,scr->RastPort.Font); running = TRUE; do { if (Wait ((1L << win->UserPort->mp_SigBit) | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) running = FALSE; while (mess = GT_GetIMsg (win->UserPort)) { myimsgCode = mess->Code; switch (mess->Class) { case IDCMP_GADGETDOWN: /* case IDCMP_MOUSEMOVE: */ case IDCMP_GADGETUP: gad = (struct Gadget *) mess->IAddress; selgad = gad->GadgetID; switch(selgad) { case 0: GT_GetGadgetAttrs (gad,win,NULL,GTST_String,&stringptr,TAG_END); strncpy (searchstring,stringptr,63); running = FALSE; break; case 1: ret=1; running = FALSE; break; case 2: ret=0; running = FALSE; break; } break; case IDCMP_CLOSEWINDOW: running = FALSE; break; case IDCMP_REFRESHWINDOW: GT_BeginRefresh (win); GT_EndRefresh (win,TRUE); break; } GT_ReplyIMsg (mess); } } while (running); CloseWindow (win); } else Printf ("cannot open windown"); } else Printf ("cannot create gadgetsn"); FreeGadgets (glist); if (ng.ng_VisualInfo) FreeVisualInfo (ng.ng_VisualInfo); UnlockPubScreen (NULL,scr); } else Printf ("cannot lock public screenn"); Printf ("eingabe = %sn",searchstring); Printf ("ret = %ldn",ret); return (0); } Gruß Thomas -- Email: thomas-rapp@web.de Home: thomasrapp.homepage.t-online.de/ [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 15:40 Uhr MaikG Posts: 5172 Nutzer |
>struct Gadget *selgad = imsg->IAddress; >D.h. selgad darf nicht vom typ ULONG sein, da es ein Pointer auf >das Gadget ist. Warum kann eine ULONG denn nicht einfach einen wert enthalten, welcher auf einen beliebigen Speicherbereich zeigt? Wenn ich jetzt z.B. 20 Stringgadgets hätte und will jedes aktivieren können brauch ich doch zu jedem ein Pointer, also 20 struckturen. Gab es nicht auch Peek's equivalente in C? >Erst denken, dann programmieren ;-) Ich denke hauptsächlich in Basic... @Thomas danke, das geht. Noch eine frage dazu sollte man ReplyImsg nicht so schnell wie möglich beantworten? [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 15:52 Uhr thomas Posts: 7719 Nutzer |
Zitat: Weil ein ULONG eine Zahl ist. Eine Zahl kann nicht auf irgendwas zeigen. Dafür gibt es Zeiger. Zitat: Ja, genau. Zeiger, keine Zahlen. Zitat: Jedes Lesen aus einem Speicherbereich ist ein Peek. Dafür braucht C keine extra Funktion. Du mußt halt nur einen Zeiger benutzen. Zitat: Du mußt erst beweisen, daß du überhaupt denkst. Das Beispiel mit dem selgad hat eher das Gegenteil bewiesen. Wenn du ein Basic-Programm Zeile für Zeile nach C übersetzt, dann funktioniert das auch. Wenn du aber die Hälfte vergißt, dann funktioniert's natürlich nicht. Der Unterschied bei C ist, daß der Compiler dir genau auf die Finger schaut und meckert, sobald du etwas ungezogenes tust, während du in Basic alle möglichen Schweinereien programmieren kannst. Gruß Thomas -- Email: thomas-rapp@web.de Home: thomasrapp.homepage.t-online.de/ [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 16:05 Uhr DrNOP Posts: 4118 Nutzer |
Zitat:Stimmt soweit. Kurzer Ausflug in die C-Grundlagen?
So weit zur Kosmetik. Es gibt aber noch einen ganz anderen Grund: Überleg mal du hättest nicht 20 einzelne Strukturen, sondern vielleicht ein Array von Elementen, deren Größe eben nicht mit der eines ULONG übereinstimmt. Dann könntest du mit Hilfe des Zeigers auf jedes Element zugreifen, a la xy = selgad[2] oder so. Ist jetzt dieser Zeiger nicht vom passenden Typ, landest du irgendwo, aber sicher nicht an der Anfangsadresse des Elementes das du suchst. Ein Zeiger selbst ist immer gleich lang, was du mit dem Typ angibst ist das Element, auf das er zeigt. Und wenn du ihn wirklich flexibel halten willst oder die Größe des Elementes (noch) nicht weißt, dann mach ihn zu einem Void-Pointer: void *selgad = 0. Zitat:Ich erinnere mich nicht genau was Peek macht, aber meinst du vielleicht memcopy? Das ist aber kein Befehl, sondern eine Funktion. Die muß also nicht exakt so heißen, und du mußt die entsprechende Bibliothek einbinden. Zitat:Und warum programmierst du dann in C? ![]() -- Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 16:07 Uhr MaikG Posts: 5172 Nutzer |
>Jedes Lesen aus einem Speicherbereich ist ein Peek. >Dafür braucht C keine extra Funktion. Du mußt halt nur einen Zeiger >benutzen. Und wie Zeige ich z.B. auf den 5. Buchstabe in einem BYTE[] ? >Der Unterschied bei C ist, daß der Compiler dir genau auf die Finger schaut und meckert, sobald du etwas ungezogenes tust, >während du in Basic alle möglichen Schweinereien programmieren kannst. Bei Basic bekomme ich aber eine einfach verständliche Information darüber was ich falsch gemacht habe. Wo ich übrigens auch diverse Code Beispiele habe an denen ich alles lernen kann. Das einzige was C scheinbar weniger durchgehen lässt ist wenn ich z.B. einer WORD Function ein LONG zuweise. Was in Basic kein fehler ist und auch Funktioniert. [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 16:08 Uhr DrNOP Posts: 4118 Nutzer |
Zitat:Ach herrje! Er hatte ja überhaupt keinen Zeiger angelegt! ![]() Das hab' ich völlig übersehen ... Zitat:*grins* eigentlich hätte ich diese Aussage über C erwartet, nicht über Basic ... ![]() Frag' dazu mal z.B. Oberon-Programmierer... ![]() -- Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 16:12 Uhr DrNOP Posts: 4118 Nutzer |
Zitat:1.) BUCHSTABEN liegen nicht in einem BYTE[], sondern in einem char[] 2.) ergebnis = char[4] Zitat:Als gäb's für C keine Beispiele ... schon mal im Internet geschaut? Außer, du meinst speziell die Amiga-GUI-Programmierung. Da wird's im Internet an sich dünne sein, aber bis du das Aminet abgegrast hast wird sicher auch Weihnachten ... ![]() ![]() -- Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 17:57 Uhr MaikG Posts: 5172 Nutzer |
>Als gäb's für C keine Beispiele ... schon mal im Internet geschaut? Ja, thomas seine seite hab ich gefunden - das wars dann auch schon. >Außer, du meinst speziell die Amiga-GUI-Programmierung. Ja, na klar. Ich brauch von alles möglichem beispiele, wie die bei MaxonBasic dabei sind. Wenn ich dann was bestimmtes in C machen will könnte ich dann da nachgucken, das als Basismodell nehmen und weniger fragen stellen :-) [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 19:12 Uhr ZeroG Posts: 1487 Nutzer |
Wenn du nicht gerade Reaction oder MUI benutzt solltest du in den RKMs bzw. auf den AmigaOS DeveloperCDs reichlich Beispiele finden. [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 19:33 Uhr Holger Posts: 8116 Nutzer |
Zitat:Wenn Du das, was Du da in C gemacht hast, genauso in Basic gemacht hättest, wäre Dein Programm einfach nur abgestürzt. Von verständlicher Information überhaupt keine Spur. Bei Deinem C-"Programm" dagegen hast Du nicht einmal versucht, Dir die Fehlermeldung des Compilers durchzulesen und zu verstehen. Ich bin mir sicher, dass diese ganz genau gesagt hat, was an dem Programm falsch ist. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 21:57 Uhr Ralf27 Posts: 2779 Nutzer |
Ich kann MaikG schon verstehn. Es ist wirklich nicht so einfach wenn man in Basic "denkt" und dann auf C wechseln möchte. Ich denke auch das der Compiler genau sagt wo es "bedenken" hat. Allerdings ist es für einen Anfänger ganz bestimmt nicht einfach dies auch zu verstehn. Es gibt einen ganz einfachen Grund von Basic (bzw. MaxonBasic) weg zu kommen und das ist vor allem die unglaublich geringe Geschwindigkeit von MBasic bzw. von Basic. Es ist schon unglaublich wie schnell C im vergleich zu Basic ist. Das sind wirklich leider Welten. Ich hänge da auch irgendwie zwischendrin. Zum einen würde ich gerne zu C "konvertieren", allerdings verdreh ich mir da leider auch komplett die Finger. Das Programmieren soll schon Spaß machen und da ich das wirklich nur ab und zu mach (z.b. jetzt seit Wochen eigentlich nichts mehr, da ich keine Zeit habe) und es eigentlich "nur" Funprojekte sind, reicht da auch Basic. Aber, naja, ich würde mich schon über mehr Speed freuen, bzw. einer "richtigen" Programmiersprache, das ist schon klar. Und, ich will jetzt kein Glaubenskrieg a la Programmiersprachen lostreten: Ich steh bei C genauso vor dem Berg(bzw. schon etwas höher... ![]() PS: C-Bücher unter das Kopfkissen legen bringt leider auch nichts, es drückt sich einfach nicht durch... ![]() -- http://www.alternativercomputerclub.de.vu [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 22:11 Uhr NoImag Posts: 1050 Nutzer |
@ MaikG: Unterschiedliche Typen sind dazu da, damit das, was Dir passiert ist, gerade nicht so leicht passieren kann. In Basic gibt es so gut wie keine Typen, darum ist Dir der Umgang mit Typen nicht vertraut. Um das Konzept zu verstehen, empfehle ich Dir ein Lehrbuch über Modula 2 bzw. 3 oder Oberon durchzuarbeiten. C geht nämlich auch ziemlich lax mit Typen um. Trotzdem hat der C-Compiler Dir gesagt, dass Du Mist geschrieben hast. Wenn Dir das Konzept von Typen vertraut ist, dann verstehst Du auch die Fehlermeldungen des Compilers. Du solltest Dich auch mit dem Konzept von Zeigern und Strukturen (Records) beschäftigen. Wenn Du das Konzept verstanden hast, dann wirst Du PEEKs und POKEs nicht mehr mögen. Beides sind nämlich nur Krücken, die Basic benötigt, weil es keine Zeiger und Strukturen kennt. Tschüß [ - Antworten - Zitieren - Direktlink - ] |
17.08.2007, 22:20 Uhr NoImag Posts: 1050 Nutzer |
@Ralf27: Über die Aussage, C sei im Gegensatz zu Basic eine "richtige" Programmiersprache, lässt sich trefflich streiten. C hat gegenüber anderen "richtigen" Programmiersprachen nur 2 Vorteile: C gibt es für jedes Betriebssystem und für C gibt es Beispiele im Überfluss. Tschüß [ - Antworten - Zitieren - Direktlink - ] |
18.08.2007, 10:03 Uhr MaikG Posts: 5172 Nutzer |
>Und warum programmierst du dann in C? ![]() Tja, wenn du ein bestehendes C-Programm "reparieren" willst bleibt einem wohl nicht übrig. Allerdings könnte es auch bald heissen "AOS4 gibts jetzt auch für den Classic und entspricht meinen anforderungen an Kompatiblität, trotzdem will ich ein Programm von mir auf PPC-Speed bringen" >1.) BUCHSTABEN liegen nicht in einem BYTE[], sondern in einem char[] Also ist in Byte der ASCII-Code gespeichert? Gut und beim char könnte ich aber auch den ASCII-Code wollten... >Wenn du nicht gerade Reaction oder MUI benutzt solltest du in den >RKMs bzw. auf den AmigaOS DeveloperCDs reichlich Beispiele finden. Hab nur den NDK3.9 >Es gibt einen ganz einfachen Grund von Basic (bzw. MaxonBasic) weg >zu kommen und das ist vor allem die unglaublich geringe >Geschwindigkeit von MBasic bzw. von Basic. Das sagst du, ich bin an keine MB grenzen gestossen. Ich erinnere nur mal an die DTMF erkennung C genauso lahm wie MBasic. >Du solltest Dich auch mit dem Konzept von Zeigern und Strukturen (Records) beschäftigen. Wenn Du das Konzept verstanden hast, dann wirst Du PEEKs und POKEs nicht mehr mögen. Beides sind nämlich nur Krücken, die Basic benötigt, weil es keine Zeiger und Strukturen kennt. Ich hab mir das gestern auch nochmal durchgelesen(C-Kurs) aber das dauert sehr lange bis ich sowas praktisch anwenden kann ohne ständig irgendwo nachzuschlagen. BTW: Hat hier schonmal einer mit BGUI gearbeitet? [ - Antworten - Zitieren - Direktlink - ] |
18.08.2007, 10:22 Uhr DrNOP Posts: 4118 Nutzer |
@MaikG: Okay, wir halten fest: Die Meldungen deines C-Compilers findest du vor allem deshalb unverständlich, weil sie dir - im Gegensatz zu den Basic-Meldungen - unbekannt sind. Vorschlag zur Lösung: Wenn du das nächste mal ein Problem hast, dann poste nicht nur den fehlerhaften Quellcode, sondern auch die Meldungen deines Compilers. Dann kann dir die jemand erklären, dann lernst du damit umzugehen. Andererseits, wenn es nicht gerade ein komplett schräger Compiler ist, dann findet man zu den meisten Meldungen im Internet haufenweise Abhandlungen a la "AAAAAAH!!! Mein Compiler spuckt irgendwelche Meldungen aus mit denen ich nichts anfange! Hilfe!" ![]() -- Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker [ - Antworten - Zitieren - Direktlink - ] |
18.08.2007, 10:30 Uhr ZeroG Posts: 1487 Nutzer |
@MaikG:Zitat: Da in exec/types.h BYTE / UBYTE sowieso als signed / unsigned char definiert sind ist es eigendlich egal welches du verwendest. Bei char sieht man aber halt schon am Datentyp das die Variable für Zeichen gedacht ist. Ein char enthält immer den ASCII-Code des Zeichens. In C sind Buchstaben ganz normale Zahlen, man kann sogar damit berechnungen machen. Zitat:Die CDs sind wirklich besser, schon allein weil da die RKMs drauf sind. Und soo teuer ist es auch nicht. [ - Antworten - Zitieren - Direktlink - ] |
18.08.2007, 11:46 Uhr akl Posts: 265 Nutzer |
@MaikG: >Warum kann eine ULONG denn nicht einfach einen wert enthalten, >welcher auf einen beliebigen Speicherbereich zeigt? Ein ULONG kann tatsächlich eine Adresse beinhalten, weil Zeiger und ULONGs unter AOS beide 32 Bit breit sind - das wird z.B. bei TagItems auch gerne und häufig angewendet. Ein ULONG entspricht dabei in etwa einem typlosen Zeiger (APTR). Bevor aber C bzw. der Compiler auf diese Adresse zugreifen kann, muss sie einen Typ bekommen - das geschieht in der Regel durch Typecasts, also z.B. ULONG adresse = (ULONG) adresseL; APTR pointer = (APTR) adresseL; struct Gadget *gad = (struct Gadget *) pointer; Wäre das nicht so, wäre das Risiko recht groß, dass man wild versucht, von Adressen Daten zu lesen, die dort überhaupt nicht vorhanden sind. Bei Sprachen wie BCPL war das beispielsweise noch stärker der Fall. Hin- und Her-Konvertieren zwischen ULONG, APTR und bestimmten Zeigern ist also kein Problem - wenn Du das "casten" jedoch vergisst, beschwert sich der Compiler. Zu Recht. Die entsprechenden Fehler und Warnings sollte man als Hilfestellung begreifen, um eigene Fehler im Programmcode zu finden. Schließlich kann es sein, dass die ULONG-/APTR-Adresse die Du zu verwenden versuchst, überhaupt nicht zu einem Gadget gehört. Je weniger Warnings, desto "sauberer" und potentiell fehlerfreier der Quellcode. P.S.: Natürlich geht auch jeder Unsinn in C, wie z.B. struct Gadget *gad = (struct Gadget *) 0x12345678; // Peek($12345678) [ Dieser Beitrag wurde von akl am 18.08.2007 um 11:47 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
18.08.2007, 13:16 Uhr DrNOP Posts: 4118 Nutzer |
Zitat:Abgesehen davon, daß er sich auch dann nicht beschwert, wenn du Blödsinn castest. Und du dich bei jedem einzelnen Cast daran erinnern mußt was denn nun für Daten hinter dem zu castenden Objekt liegen. -- Signaturen mit mehr als zwei Zeilen gehen mir auf den Wecker [ - Antworten - Zitieren - Direktlink - ] |
18.08.2007, 19:44 Uhr hansfaust Posts: 56 Nutzer |
@MaikGZitat:So, ich will auch mal was dazu sagen. Zuerst: Alle die, die hier große Töne spucken, haben wahrscheinlich das Programmieren in C von ihren Müttern gelernt, während sie an der Brust lagen ... oder ???? ![]() Also Leute, geht bitte ein wenig freundlicher mit denen um, die sich die Mühe machen und C lernen wollen. Sowas wie "... erst nachdenken und dann hinschreiben ... " (nach dem Motto "Ich weiß wie man's macht, aber Du Trottel scheinbar nicht.") ist nicht gerade hilfreich. Ich selbst habe C gelernt, als viele Dinge, die heute normal sind, noch garnicht normal waren. Ich denke da z.B. an K&R C, dem Vorläufer des heutigen ANSI-C. Und ich habe mich sehr geplagt in einer Zeit, als es noch kein Internet gab, wo man schnell mal im Forum um Rat fragen konnte ... z.B. unsigned long, ULONG, uint32 sind Bezeichner für exact den gleichen Datentyp, nämlich eine 32 Bit lange Zahl. Wenn ich z.B. schreibe: ULONG einezahl; dann kann(!) einezahl wirklich eine Zahl sein. Es könnte (auf dem AMIGA) aber auch eine Speicher-Adresse sein (auch Pointer genannt). Denn Speicheradressen sind 32 Bit Zahlen. Es könnte aber auch (um die Verwirrung noch ein wenig größer zu machen) ein Bitfeld mit 32 bits sein. Solche Bitfelder enthalten z.B. die sogenannten Flags, etwa in der struct Gadget das Feld Flags (... ja ich weiß dort ist das ausgerechnet ein UWORD, das Prinzip ist aber das gleiche ...). Jedes Bit dieser Zahl bedeutet eine bestimmte Eigenschaft. Ist ein Bit gesetzt, dann ist damit eine bestimmte Eigenschaft festgelegt. z.B. beim Gadget: Ist das erste Bit in Flags gesetzt, so wird beim Draufklicken eine Box um das Gadget gezeichnet. Woher weiß ich das ? Das steht in den sogenannten includes am Kopf des Quelltextes, hier in intuition/intuition.h. Ich suche darin "struct Gadget" und etwas darunter steht: /* --- Gadget.Flags values --- */ /* combinations in these bits describe the highlight technique to be used */ ... #define GFLG_GADGHBOX 0x0001 /* Draw a box around the image */ ... Auch da muß ein Anfänger erst mal durchsteigen. Und es ist wirklich nicht leicht in den includes Informationen zu finden, wenn man garnicht weiß, daß sie dort stehen, bzw. wenn man nicht weiß, wo man danach suchen soll. Mir war und ist da immer das MAXON HotHelp eine echte Hilfe. Als ich mit meiner Arbeit an dem Quellcode von Bars&Pipes Professional begonnen habe, sind mir oft Teile im Quellcode begegnet, die (ca. 1988) in einem ganz alten Programmierstil geschrieben wurden. z.B. long IntuitionBase; long GfxBase; ... Ist das falsch ? Ja und Nein. Nach neueren Programmierrichtlinien ist es falsch ... aber es funktioniert bestens, warum sollte es dann falsch sein ? Wichtig ist nur, daß ich weiß, daß hier in dem long IntuitionBase die Basis-Adresse der geöffneten intuition.library steht, und diese entsprechend behandle. Überschaubarer und leichter zu warten (besonders, wenn andere meinen Quellcode lesen wollen) ist der Code natürlich, wenn ich: struct IntuitionBase * IntuitionBase; schreibe. NB: für die Freunde, die von Basic kommen: das Semikolon am Ende eines Ausdrucks ist für den C-Compiler sehr wichtig, damit er weiß, wo ich als Programmierer das Ende eines Ausdrucks haben will. Ich könnte so sogar mehrere Ausdrücke in eine Zeile schreiben, wo ich in Basic zwingend mehrere Zeilen dazu brauche. z.B. ULONG a, b, c; b = 345; c = (28 / 7); a = b + c; So, nochmal zu den Gadgets: Ein Gadget wird als die Adresse einer(Zeiger - Pointer - auf eine) Gadget-Struktur definiert. In dieser Struktur ist alles definiert, was für das Gadget wichtig ist. In einigen Fällen ist es nicht nötig, diesen Zeiger extra zu speichern. Manchmal braucht man ihn aber, dann legt man einfach eine Variable dafür an (Deklaration). In Basic geschieht das "im Vollzug" - erst wenn ich diese Variable im Quellcode brauche. In C stehen die Deklarationen immer am Beginn einer Funktion. Das ist zwar etwas mehr Arbeit als in Basic, am Ende ist es aber übersichtlicher. Für den Anfänger ist es am einfachsten, jedes Gadget einzel zu deklarieren. C läßt zu, daß Variablen vom gleiche (Daten-)Typ hintereinander mit Komma getrennt deklariert werden können. z.B: ULONG a,b,c,d; oder struct Gadget *yesgad, *nogad, *prefsgad; Nun könnte man die Zeiger für die Gadgets entsprechend dem Quelltext speichern: ... ng.ng_GadgetID = 0; yesgad = gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); ... ng.ng_GadgetID = 1; nogad = gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); ... ng.ng_GadgetID = 2; prefsgad = gad = CreateGadget (BUTTON_KIND,gad,&ng,TAG_END); ... Später kann man nun über den Gadget-Zeiger die einzelnen Felder erreichen. UWORD id; (am Anfang der Funktion) ... id = yesgad->GadgetID; Die GadgetID eines Gadget kann ich aber auch erfahren, wenn der Anwender auf das Gadget klickt. Intuition liest für mich diese nämlich aus der betreffenden Gadget-Struktur aus, und speichert sie für mich in einem bestimmten Feld der IntuiMessage-Struktur ab (((struct Gadget *)(message->IAddress))->GadgetID), die ich dann auswerten kann mit einer switch() { case ... } Anweisung. Nochmal zum obigen Cast (Damit wird die Umwandlung in einen bestimmten Datentyp bezeichnet.). message->IAdress enthält die Adresse des Gadgets wird also in einen Zeiger vom Typ struct Gadget umgewandelt. NB.: Das kleine Sternchen nach struct Gadget bezeichnet die Umwandlung als Zeiger (Speicheradresse an der hier die struct Gadget beginnt). Dann der weitere Zeiger auf die GadgetID (Speicheradresse an der die GadgetID abgelegt ist). Man könnte das Ganze auch zerlegen: struct Gadget *gad; UWORD id; ... gad = (struct Gadget *)(message->IAdress); id = gad->GadgetID; Ich weiß, das war jetzt schon fast ein Mikro-C-Kurs. Aber nur mit ausführlichen sachlichen Erklärungen kann man weiterhelfen. Und ich würde es sehr begrüßen, wenn dies so gehalten würde. Ansonsten werde ich mich hier nicht wieder zu Wort melden. Und: Es gibt keine blöden Fragen, sondern nur blöde Antworten. hansfaust alias Alfred Faust http://www.alfred-j-faust.de [ - Antworten - Zitieren - Direktlink - ] |
18.08.2007, 22:16 Uhr NoImag Posts: 1050 Nutzer |
Zitat: Nur zur Info: In Basic gibt es den Doppelpunkt: b& = 345 : c& = (28 / 7) : a& = b& + c& Zitat: Das stimmt so nicht. Du kannst in C eine Variable jederzeit deklarieren. Der einzige Unterschied zu Basic ist, dass die Variable vor oder bei der ersten Benutzung tatsächlich deklariert werden muss: int a, b; irgendwelcher Programmcode int c = a + b; Tschüß [ - Antworten - Zitieren - Direktlink - ] |
19.08.2007, 00:22 Uhr thomas Posts: 7719 Nutzer |
@NoImag:Zitat: Nein, kann man nicht. Bei C++ gibt es einige Ausnahmen, bei denen man Variablen mittem im Code deklarieren kann. Bei C jedoch muß eine Deklaration immer am Beginn eines Blocks stehen. Der Unterschied zu anderen Programmiersprachen ist hier, daß jeder {}-Block geeignet ist, also auch nach einem if oder while oder einfach so. Bei anderen Sprachen muß es der Beginn einer Prozedur sein. Jedanfalls kann man aber nicht Deklarationen und Code miteinander mischen, man muß immer einen Block öffnen, um eine Deklaration vorzunehmen. Gruß Thomas -- Email: thomas-rapp@web.de Home: thomasrapp.homepage.t-online.de/ [ - Antworten - Zitieren - Direktlink - ] |
19.08.2007, 11:46 Uhr Ralf27 Posts: 2779 Nutzer |
Zitat: Dann frag ich mich, wieso sonst keiner mehr in MBasic programmiert wenn es keine Grenzen hat? ![]() Ich hab mal für ein Projekt eine Routine von MBasic nach ASM konvertiert und dann auch gleich das ganze möglichst an die Möglichkeiten von ASM angepasst. Mit ASM sind halt einfache Bitmanipulationen einfacherer als in Basic(Ja, geht wohl auch mit C, aber damals hab ich es halt in ASM gemacht). Und, was soll ich tippen, ASM war wesentlich schneller. Und das, obwohl ich kaum ASM kann bzw. eigentlich nichts an die "neueren" 68k-Prozessoren angepasst war. Geschwindigkeitstechnisch stoße ich immer wieder an die Grenzen von MB. Aber es kommt halt auch darauf an was man programmieren möchte. Selbst ACE ist im Integerbereich schneller(!) als MBasic. Außerdem: MBasic scheint wohl nur reinen 68000er-Code zu generieren. Und: Es gehen auch keine Befehle die FPU-Register belegt haben möchten. Ich tippe hier z.b. von 3D-Libs. Das ist eine der vielen Grenzen von MB. ![]() -- http://www.alternativercomputerclub.de.vu [ Dieser Beitrag wurde von Ralf27 am 19.08.2007 um 11:48 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
19.08.2007, 11:53 Uhr Ralf27 Posts: 2779 Nutzer |
Zitat: Das stimmt schon, allerdings wenn man es genau sieht: code:DEFLNG a,b,c b=345 : c=(28/7) : a=b+c So würde das aussehn wenn man es wirklich fast(ULONG gibt es eigentlich nicht bei Basic, leider ist alles Vorzeichenbehaftet) 1 zu 1 nach Basic übersetzen würde. ![]() -- http://www.alternativercomputerclub.de.vu [ - Antworten - Zitieren - Direktlink - ] |
19.08.2007, 13:05 Uhr Der_Wanderer Posts: 1229 Nutzer |
Der Grund warum hier so "hart" mit MaikG umgegangen wird ist, dass er seine Programmierfehler auf die "Komplexität" von C schiebt. Der Fehler, den er aber gemacht hat, würde genauso in Basic passieren. Ob nun C oder Basic, sollte man erstmal genau hinsehen und das RKM (oder NDK3.9) konsultieren, und nicht gleich auf C bashen. Das geht einigen Leuten hier eben auf den Keks. Zitat: @maikG: Sei froh dass der C Compiler meckert. Du kannst davon ausgehen, dass er in den meisten Fällen dir nicht das Leben schwer machen will, sondern auf einen Fehler hinweist, den du in Basic zur Laufzeit debuggen müsstest. Und zur Laufzeit debuggen ist wesentlich "teuerer" als zur Compilezeit. Es ist eben so: Für einfache Sachen ist Basic Style ok, weil die Disziplin, die C erzwingt, nicht notwendig ist. Aber wenn man was komplexeres machen will, was ja MaikG offenbar vor hat, dann verwandelt sich die Nachsichtigkeit von Basic in einen grossen Nachteil, und die Pingeligkeit von C in einen grossen Vorteil. Das muss man eben mal verstanden haben. Bei größeren Sachen muss man einfach diziplinierter programmieren, sonst wird das programm irgendwann unwartbar und voller Fehler, die erst zur Laufzeit auftreten. -- Thilo Köhler, Author von: HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr... Homepage: http://www.hd-rec.de [ - Antworten - Zitieren - Direktlink - ] |
19.08.2007, 13:11 Uhr Der_Wanderer Posts: 1229 Nutzer |
Aber ich will ja nicht nur meckern, sondern Maik soll was lernen dabei: Maiks Beispiel ist ein Paradebeispiel für die Vorteile von C: Maik hat vergessen, GadgetID auszulesen und testest die ID versehentlich mit dem Pointer auf das Gadget. Basic würde das zulassen, da es automatisch Typen umwandelt. Dann hätte das Programm kompiliert, aber Maik hätte sich gewundert warum die Buttons nicht reagieren, und hätte keinen Hinweis warum. In C dagegen kann man das Program erst gar nicht kompilieren, sondern bekommt sofort gesagt, dass ein Pointer auf ein Gadget mit einem Integer (0, 1, 2 etc.) verglichen wird, was nicht zulässig ist. Das zu beheben in C hätte vielleicht 30sec gebraucht, ohne Testlauf des Programms. In Basic hätte Maik lange über dem Source brüten müssen, viele Testläufe machen müsssen etc. Kaum abzuschätzen wie lange es dauert, diesen Fehler zu finden, da man einen Geistesblitz benötigt während man zig mal über den Code liesst. Bei einem grossen Projekt wäre das der Killer. Und nicht jeder Bug ist so offensichtlich. Vermutlich lauern da dann noch zig andere Bugs, die nur in seltenen Situationen auftreten. -- Thilo Köhler, Author von: HD-Rec, Sweeper, Samplemanager, ArTKanoid, Monkeyscript, Toadies, AsteroidsTR, TuiTED, PosTED, TKPlayer, AudioConverter, ScreenCam, PerlinFX, MapEdit, TK AB3 Includes und viele mehr... Homepage: http://www.hd-rec.de [ Dieser Beitrag wurde von Der_Wanderer am 19.08.2007 um 13:13 Uhr geändert. ] [ Dieser Beitrag wurde von Der_Wanderer am 19.08.2007 um 13:14 Uhr geändert. ] [ - Antworten - Zitieren - Direktlink - ] |
19.08.2007, 18:00 Uhr MaikG Posts: 5172 Nutzer |
>Dann frag ich mich, wieso sonst keiner mehr in MBasic programmiert wenn es keine Grenzen hat? ![]() Weil C Portabler ist, oder man da schnellere und bessere hilfe findet. MUI+Reaction Includes fehlen z.B. auch. >Ich hab mal für ein Projekt eine Routine von MBasic nach ASM konvertiert und dann auch gleich das ganze möglichst an die Möglichkeiten von ASM angepasst. Mit ASM sind halt einfache Bitmanipulationen einfacherer als in Basic(Ja, geht wohl auch mit C, aber damals hab ich es halt in ASM gemacht). Und, was soll ich tippen, ASM war wesentlich schneller. Und das, obwohl ich kaum ASM kann bzw. eigentlich nichts an die "neueren" 68k-Prozessoren angepasst war. ASM ist auch schneller als C, das war nicht die frage. Fast jeder Maxonbasic befehl hat eine unmenge an sicherheitabfragen, weil der User könnte ja was falsches übergeben oder es könnte was unerwartet auftreten. Unter ASM kannst du ganz genau das machen was du willst, normalerweise weiss man ja welche eingaben kommen können und daher legt man die überprüfungen selbst fest. >Außerdem: MBasic scheint wohl nur reinen 68000er-Code zu generieren. Jain, einige befehle z.b. ungrade adressionen erfordern den 020... Das DTMF teil hab ich auf C sogar auf 68060 optimiert, war trotzdem nicht schneller als MB. >Und: Es gehen auch keine Befehle die FPU-Register belegt haben >möchten. Ich tippe hier z.b. von 3D-Libs. Das ist eine der vielen >Grenzen von MB. ![]() Von 3D hab ich keinen schimmer, ich meinte auch die grenzen der Geschwindigkeit. [ - Antworten - Zitieren - Direktlink - ] |
-1- 2 3 | [ - Beitrag schreiben - ] |
amiga-news.de Forum > Programmierung > imsg zeug in C | [ - Suche - Neue Beiträge - Registrieren - Login - ] |
![]() |
Impressum |
Datenschutzerklärung |
Netiquette |
Werbung |
Kontakt
Copyright © 1998-2025 by amiga-news.de - alle Rechte vorbehalten. |
![]() |