amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Mein erstes C Programm will nicht [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- 2 3 [ - Beitrag schreiben - ]

17.10.2005, 12:46 Uhr

MaikG
Posts: 5172
Nutzer
Ich hab mir gestern den C-Kurs für Anfänger durchgelesen.
Wenn man das Prinzip versteht scheint es nicht so schwer
zu sein. Nur mein erstes Programm geht nicht.
Es soll den größten freien Fastspeicherblock-512kb allocieren,
diesen mit 255 bzw. F füllen, alles wieder auslesen und kontrollieren.


#include <pragmas/exec_sysbase_pragmas.h>
#include <exec/exec.h>
#include <exec/execbase.h>
#include <pragmas/exec_pragmas.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <stdio.h>
#include <string.h>

int main() {
unsigned long size,i,*x,Fehler


size=Availmem(MEMF_Lagerst+MEMF_FAST)
size -= 512000;
*x=AllocMem(size,MEMF_Fast)
for (i=1;i<=size;i++)
{
*x+i=255
}

for (i=1;i<size,i++)
{
if (*x+i<>255) Fehler++
}

Printf("Fehler: %lu",Fehler);

return 0;
}


Fehlerausgabe vom Compiler:
5.Work3:vbcc> vc memtest.c
>size=
warning 54 in line 14 of "memtest.c": ; expected
>size
error 82 in line 15 of "memtest.c": unknown identifier <MEMF_Lagerst>
>size
warning 54 in line 15 of "memtest.c": ; expected
> for
error 82 in line 17 of "memtest.c": unknown identifier <MEMF_Fast>
> for
warning 54 in line 17 of "memtest.c": ; expected
> }
error 86 in line 20 of "memtest.c": lvalue required for assignment
> }
warning 54 in line 20 of "memtest.c": ; expected
> for (i=1;i<size,i++)
warning 54 in line 22 of "memtest.c": ; expected
> if (*x+i<>2
error 76 in line 24 of "memtest.c": identifier expected
aborting...
unexpected end of file
4 errors found!
vbccppc fehlgeschlagen Rückgabewert 20
vbccppc -quiet "memtest.c" -o= "T:t_5_0.asm" -poweropen -sc -no-multiple-ccs -madd -O=1 -Ivincludewos: failed

Also die Exec sachen hab ich doch mit Include eingebunden,
kann C keine berechnungen ala size=size+512000 ?
Kann man Zeiger mit Intergers nicht Kombinieren? *x+i ?
Gibts kein <> ?

[ - Antworten - Zitieren - Direktlink - ]

17.10.2005, 12:53 Uhr

Solar
Posts: 3680
Nutzer
> unknown identifier <MEMF_Lagerst>

MEMF_Lagerst -> MEMF_LARGEST

> unknown identifier <MEMF_Fast>

MEMF_Fast -> MEMF_FAST

> Kann man Zeiger mit Intergers nicht Kombinieren? *x+i ?

Besser x[ i ]. (Du addierst hier i auf den Inhalt in Speicheradresse x...)

> Gibts kein <> ?

In C schreibt man das != (nicht gleich).

Jedes Statement mit Semikolon abschließen. Groß-/Kleinschrift beachten.

Ich hab' nie die Amiga-API programmiert, daher bin ich mir bei den Includes und Funktionsnamen nicht sicher, aber:

code:
#include <pragmas/exec_sysbase_pragmas.h>
#include <exec/exec.h>
#include <exec/execbase.h>
#include <pragmas/exec_pragmas.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <stdio.h>
#include <string.h>

int main()
{
   unsigned long size, i, Fehler;
   unsigned char * x;

   size = AvailMem( MEMF_LARGEST | MEMF_FAST );
   size -= 512000;
   *x = AllocMem( size, MEMF_FAST );

   for ( i = 1; i <= size; i++ )
   {
      x[ i ] = 255;
   }

   for ( i = 1; i < size, i++ )
   {
      if ( x[ i ] != 255 ) Fehler++;
   }

   printf( "Fehler: %lu", Fehler );

   return 0;
}


AvailMem, nicht Availmem.

Parameter werden m.E. mit | verknüpft, nicht mit + (Bitmaske).

Was passiert, wenn AvailMem() weniger als 512000 zurückgibt?

x ist ein Zeiger auf unsigned int; diesen Zeiger um 1 zu erhöhen, bedeutet ihn vier Bytes weiterzuschieben... also überschreibst Du viermal mehr Speicher, als Du zur Verfügung hast. (Speicher, den Du byteweise ansprechen willst, als char * addressieren - in diesem Fall (wegen der 255) besser unsigned char.

printf() kleingeschrieben.


[ Dieser Beitrag wurde von Solar am 18.10.2005 um 09:49 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

17.10.2005, 13:28 Uhr

tokai
Posts: 1071
Nutzer
ich habe es mal berichtig, hoffe das hilft. ;)

code:
/*  exec/exec.h includes exec/#?
 */
#include <exec/exec.h>

/* immer proto niemals pragma oder inline etc. nutzen
 */
#include <proto/dos.h>
#include <proto/exec.h>


int main(void)
{
    ULONG size;
    ULONG i;
    ULONG *x;          /* 4 byte pointer */
    ULONG fehler = 0;


    size  = AvailMem(MEMF_LARGEST | MEMF_FAST);
    size -= 512000UL;


    /*  align to 4
     */
    size  = (size/4UL) * 4UL;


    /*  AllocVec ist bequemer als AllocMem ;)
     */
    x = AllocVec(size, MEMF_FAST);


    /*   testen ob der Alloc erfolgreich war
     */
    if (x)
    {

        /*  wir testen 4 bytes aufeinmal, also muessen wir i nur 
         *  1/4 hochzählen lassen
         */
        size /= 4UL;

        for (i=0; i < size; i++)
        {
            x[ i ] = 0xF0F0F0F0; /* 4 Bytes gehen schneller als 1 Byte */
        }

        for (i=0; i < size; i++)
        {
            if (x[ i ] != 0xF0F0F0F0)
            {
                fehler++;
            }
        }
        
        Printf("Anzahl Fehler: %lu\n", fehler);
        
        /*   Speicher wieder an's System zurückgeben. Wichtig ;)
         */
        FreeVec(x);
    }


    /*  vielleicht nützlich für scripts, aber nur RETURN_OK tuts auch ;)
     */
    return fehler ? RETURN_WARN : RETURN_OK;
}

--
http://www.christianrosentreter.com ~ MorphOS Software

[ Dieser Beitrag wurde von tokai am 17.10.2005 um 13:30 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

17.10.2005, 13:33 Uhr

tokai
Posts: 1071
Nutzer
@Solar:

Zitat:
Was passiert, wenn AvailMem() weniger als 512000 zurückgibt?

jau, sollte man normalerweise abfangen.


Zitat:
printf() kleingeschrieben.

Nah.. Printf() macht kleinere binaries, weil das die dos.library function ist. ;)


--
http://www.christianrosentreter.com ~ MorphOS Software

[ - Antworten - Zitieren - Direktlink - ]

17.10.2005, 19:08 Uhr

MaikG
Posts: 5172
Nutzer
Die codes Compiliert er beide nicht.
Beim 1.gibts mehrere Fehler beim 2.unexpected end of file

[ - Antworten - Zitieren - Direktlink - ]

17.10.2005, 19:17 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von tokai:
Nah.. Printf() macht kleinere binaries, weil das die dos.library function ist. ;)


Dann sollte wohl auch ein
#include <proto/dos.h>
am Anfang stehen und nicht
#include <stdio.h>

Nicht wahr ;)

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

17.10.2005, 20:08 Uhr

geit
Posts: 332
[Ex-Mitglied]
Zitat:
Original von Holger:
Zitat:
Original von tokai:
Nah.. Printf() macht kleinere binaries, weil das die dos.library function ist. ;)


Dann sollte wohl auch ein
#include <proto/dos.h>
am Anfang stehen und nicht
#include <stdio.h>

Nicht wahr ;)

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.


Dann aber VPrintf() :)

Geit

[ - Antworten - Zitieren - Direktlink - ]

17.10.2005, 20:14 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
Die codes Compiliert er beide nicht.
Beim 1.gibts mehrere Fehler beim 2.unexpected end of file

Überprüf noch mal, ob Du wirklich alles kopiert hast. Bei mir lief tokai's Programm auf Anhieb.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

17.10.2005, 23:38 Uhr

MaikG
Posts: 5172
Nutzer
>Überprüf noch mal, ob Du wirklich alles kopiert hast.
>Bei mir lief tokai's Programm auf Anhieb.

Da fehlt wohl eine }, ist mir so beim abzählen
aufgefallen.

Der Compiler meldet dann:

10.Work3:vbcc> vc memtest2.c
t_10_0.o: In "_main":
Error 21: t_10_0.o (.text+0x28): Reference to undefined symbol _AvailMem.
Error 21: t_10_0.o (.text+0x50): Reference to undefined symbol _AllocVec.
t_10_0.o: In "l10":
Error 21: t_10_0.o (.text+0xcc): Reference to undefined symbol _FreeVec.
vlink fehlgeschlagen Rückgabewert 20
vlink -bamigaehf -x -R -Bstatic -Cvbcc -Lvlibwos: vlibwos:warpup.o "T:t_10_0.o" -s -lvc vlibwos:x.o -o a.out failed


wobei ich das Printf in printf geändert habe, vorher
wurde das auch noch als fehler ausgegeben.

[ - Antworten - Zitieren - Direktlink - ]

17.10.2005, 23:50 Uhr

Kaesebroetchen
Posts: 643
Nutzer
@MaikG:
Ich habs bei mir mal schnell getestet (mit AmiDevCpp) und es lief ohne Fehler durch.
Unter WinUAE macht es die Ausgabe:
Anzahl Fehler: 0

Wie es scheint, hast du einen Fehler in deiner Compiler Konfiguration. Lassen sich denn andere Sachen wie Hallo Welt usw. korrekt kompilieren ?
--
http://amidevcpp.kilu.de/

[ - Antworten - Zitieren - Direktlink - ]

17.10.2005, 23:58 Uhr

MaikG
Posts: 5172
Nutzer
#include <stdio.h>

char *string = "Hello world !\n";

int main () {
printf("%s", string);
return 0;
}

Das macht er schon. Wo genau müssten die Definitionen
von z.B. AllocMem denn stehen?
In Basic ist das in exec.bh, die MEMF_Fast ist in exec.bc

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 00:56 Uhr

whose
Posts: 2156
Nutzer
@MaikG:

evtl. noch gegen amiga.lib (oder wie die nu grad beim VBCC heißt) linken?

Grüße

--
---

:boing: µA1 PPC 750GX-800
:boing: A4000 PPC 604e-233

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 02:04 Uhr

geit
Posts: 332
[Ex-Mitglied]
Das Beispiel von Tokai läßt sich mit VBCC compilieren, wenn man

vc test.c -lamiga

benutzt, oder die printf Zeile in

VPrintf("Anzahl Fehler: %lu\n", &fehler);

ändert und dann mit vc test.c compiliert. Ohne Linker Lib wird es natürlich kürzer.

a.out starten und tada:

Anzahl Fehler: 0

Geit


[ Dieser Beitrag wurde von geit am 18.10.2005 um 02:08 Uhr editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 09:27 Uhr

gni
Posts: 1106
Nutzer
Zitat:
geit:
Dann aber VPrintf() :)

Warum sollte man VPrintf verwenden? Printf() tut schon was es soll.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 09:50 Uhr

Solar
Posts: 3680
Nutzer
Hm. Hab' selber nicht alle meine Ratschläge im Code umgesetzt. Jetzt müßte mein Code eigentlich auch funktionieren - es sei denn, Tokais Alignment-Trick ist nicht-optional. Falls noch Fehler auftreten, würden die mich interessieren.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 09:55 Uhr

MaikG
Posts: 5172
Nutzer
>@MaikG:
>evtl. noch gegen amiga.lib (oder wie die nu grad beim
>VBCC heißt) linken?

Genau das war es jetzt Compiliert er, werde das Programm
nachher Probieren wenn ich aus dem Internet bin.
Danke erstmal @all

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 10:50 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von gni:
Zitat:
geit:
Dann aber VPrintf() :)

Warum sollte man VPrintf verwenden? Printf() tut schon was es soll.

Weil tokai's Argumentation auf code-Größe basierte. Printf ist m.W. eine Link-Lib Funktion, VPrintf die dahinterstehende DOS-Funktion. Wer also sich um solche Nebensächlichkeiten kümmern will, muß auch VPrintf benutzen.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 11:00 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von MaikG:
>@MaikG:
>evtl. noch gegen amiga.lib (oder wie die nu grad beim
>VBCC heißt) linken?

Genau das war es jetzt Compiliert er, werde das Programm
nachher Probieren wenn ich aus dem Internet bin.
Danke erstmal @all

VBCC sollte doch auch inlines beherrschen...
oder benutzt Du AOS4?

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 11:03 Uhr

tokai
Posts: 1071
Nutzer
@Holger:

Zitat:
Dann sollte wohl auch ein
#include <proto/dos.h>
am Anfang stehen und nicht
#include <stdio.h>


ist doch da. ;)

regards,
tokai
--
http://www.christianrosentreter.com ~ MorphOS Software

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 11:06 Uhr

Solar
Posts: 3680
Nutzer
Da ging es um Maik's Original-Code. Der included <stdio.h>, nix DOS. Deshalb entweder printf() oder den Include anpassen.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 11:07 Uhr

tokai
Posts: 1071
Nutzer
@Holger:

Zitat:
Weil tokai's Argumentation auf code-Größe basierte. Printf ist m.W. eine Link-Lib Funktion, VPrintf die dahinterstehende DOS-Funktion. Wer also sich um solche Nebensächlichkeiten kümmern will, muß auch VPrintf benutzen.

Printf() ist nur die vararg stub function für VPrintf(), wir wollen es doch nicht gleich überverkomplizieren. ;)

Trotzdem spart man etliche Bytes mit der Verwendung von Printf() anstatt von printf() (wird nur die kleine stubfunction anstatt des kompletten printf() codes gelinkt).


Kenne mich nicht mit VBCC aus (noch nie verwendet), kann d.h. durchaus sein, dass man dann die linkerlib mit den stubs manuell hinzulinken muss (meine MorphOS gcc config macht das automatisch).

regards,
tokai
--
http://www.christianrosentreter.com ~ MorphOS Software

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 11:21 Uhr

tokai
Posts: 1071
Nutzer
Zitat:
Original von Solar:
Da ging es um Maik's Original-Code. Der included <stdio.h>, nix DOS. Deshalb entweder printf() oder den Include anpassen.


richtig. und deshalb hatte ich das in meiner Version berichtigt. ;)
--
http://www.christianrosentreter.com ~ MorphOS Software

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 11:36 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von tokai:
Printf() ist nur die vararg stub function für VPrintf(), wir wollen es doch nicht gleich überverkomplizieren. ;)

"Nur" ist gut. Unter 68k bedeutet das schonmal alle Argumente auf den Stack kopieren, auf dem ppc bedeutet das zusätzlich noch alle Argumente von stack in einen definitiv linearen Speicherbereich kopieren. Wer auf den Unterschied zwischen printf und Printf Wert legt, sollte auch den Unterschied zwischen Printf("bla", wert) und VPrintf("bla", &wert) beachten.
Zitat:
Trotzdem spart man etliche Bytes mit der Verwendung von Printf() anstatt von printf() (wird nur die kleine stubfunction anstatt des kompletten printf() codes gelinkt).
Das ist compiler-spezifisch. Es gibt auch Umgebungen, in denen printf auch nur ein Stub für Printf ist.
Zitat:
Kenne mich nicht mit VBCC aus (noch nie verwendet), kann d.h. durchaus sein, dass man dann die linkerlib mit den stubs manuell hinzulinken muss (meine MorphOS gcc config macht das automatisch).
Das liegt eher daran, daß in MaikG's Umgebung auch keine inlines benutzt wurden. (Deshalb brauchte er eh die amiga.lib). Warum das so ist, wissen wir nicht, dazu müßten wir mehr über MaikG's Umgebung wissen.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 11:38 Uhr

MaikG
Posts: 5172
Nutzer
>oder benutzt Du AOS4?

Nein, 3.9

>Kenne mich nicht mit VBCC aus (noch nie verwendet), kann
>d.h. durchaus sein, dass man dann die linkerlib mit
>den stubs manuell hinzulinken muss (meine MorphOS gcc
>config macht das automatisch).

Da gibt es eine einstellungsdatei, da kann man das irgenwo
eintragen das vbcc das immer linkt.

Ja zu den Programm, es Funktioniert zwar, laut Stoppuhr
komme ich jedoch nur auf 10-20 MB/s. Sysspeed zeigt
mir etwa 100MB/s PPC-Speicherdurchsatz mit LONGs an.

WarpStat zeigt das Programm an, ist also nicht versehentlich
für 68k Compiliert worden.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 11:39 Uhr

thomas
Posts: 7716
Nutzer

Es gibt noch einen entscheidenden Vorteil von Printf gegenüber printf: es unterstützt die Erweiterungen der locale.library. Man kann also so Späßchen machen wie

Printf ("%3$s %2$s %1$s\n","eins","zwei","drei");

und bekommt in der Ausgabe "drei zwei eins".

Außerdem ist Printf reentrant. Wenn man printf in mehreren Tasks gleichzeitig benutzt, kommt nur Kuddelmuddel heraus.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 12:48 Uhr

Solar
Posts: 3680
Nutzer
Zitat:
Original von MaikG:

Ja zu den Programm, es Funktioniert zwar, laut Stoppuhr
komme ich jedoch nur auf 10-20 MB/s. Sysspeed zeigt
mir etwa 100MB/s PPC-Speicherdurchsatz mit LONGs an.


Da würde ich mich nicht weiter drüber wundern. Probier's mal mit memset( x, 255, size ) statt einer selbst programmierten Schleife...

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 14:32 Uhr

gni
Posts: 1106
Nutzer
Zitat:
thomas:
Es gibt noch einen entscheidenden Vorteil von Printf gegenüber printf: es unterstützt die Erweiterungen der locale.library. Man kann also so Späßchen machen wie

Printf ("%3$s %2$s %1$s\n","eins","zwei","drei");

und bekommt in der Ausgabe "drei zwei eins".

Das kannst Du mit printf() auch machen.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 14:36 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Holger:
Zitat:
gni:
Warum sollte man VPrintf verwenden? Printf() tut schon was es soll.

Weil tokai's Argumentation auf code-Größe basierte.
Ja und? Auch wenn man "nur" Printf() verwendet, reduziert sich die Größe des Programmes erheblich. Und zb. SAS/C kann auch solche Funktionen "in-line" aufrufen.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 14:45 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Holger:
Wer auf den Unterschied zwischen printf und Printf Wert legt, sollte auch den Unterschied zwischen Printf("bla", wert) und VPrintf("bla", &wert) beachten.

Und Du kennst den Unterschied? Auch bei VPrintf muß "wert" im Speicher liegen, oder wie willst Du sonst die Adresse der Variable bestimmen? Für den behandelten Fall kann man VPrint verwenden, da es nur eine Parameter gibt. Sobald Du mehr hast, mußt Du das Argument-Array selber erstellen. Dann kannst Du auch gleich Printf nehmen.
Zitat:
Es gibt auch Umgebungen, in denen printf auch nur ein Stub für Printf ist.
Was soll das für eine Umgebung sein?
Zitat:
Das liegt eher daran, daß in MaikG's Umgebung auch keine inlines benutzt wurden. (Deshalb brauchte er eh die amiga.lib). Warum das so ist, wissen wir nicht, dazu müßten wir mehr über MaikG's Umgebung wissen.
Er hat mit VBCC ein WarpOS Programm erstellt. Da werden OS-Funktionen generell über Stubs aufgerufen.

[ - Antworten - Zitieren - Direktlink - ]

18.10.2005, 14:56 Uhr

thomas
Posts: 7716
Nutzer
Zitat:
Original von gni:
Das kannst Du mit printf() auch machen.


Nein, funktioniert nicht.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]


-1- 2 3 [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Mein erstes C Programm will nicht [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.