Hi,
also ich versuche seit stunden einfach nur einen array in eine C
funktion zu übergeben (AVR GCC und Studio 4).
Egal was ich mache, es ist einfach nicht möglich. Ich habe unzählige
verschiedene varianten im Netzt gefunden. Aber egal wie ich meinen code
ändere, es gibt immer die selbe fehlermeldung und das Programm funzt
nicht richtig
../mt.c:49: warning: passing argument 1 of 'myfunc' from incompatible
pointer type
).
Ich habe ernsthaft überlegt, GCC zu deinstallieren und ausschliesslich
BASCOM zu benutzen.
Hier ist wie ich es gemacht habe:
erstmal in main() das array deklariert und die funktion aufgerufen:
char txt[100];
txt[0]='a'
txt[1]='b'
txt[2]='c'
txt[3]='d'
txt[4]='e'
myfunc(txt); -> funzt nicht
myfunc("hallo"); -> funzt
und dann in der funktion:
void myfunc(char *text){
while(*text){
...
text++;}
}
und der prototyp:
void myfunc(char *text);
Was ist hier falsch
????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????
Danke
Grüße
char txt[100];
myfunc(txt); -> funzt nicht
void myfunc(char *text);
char* ist halt nicht gleich char[100] - ist ja auch bloss eine Warnung,
es geht aber. Um die warnung nch wegzubekommen must du casten.
myfunc((char*)txt);
char txt[100];
txt[0]='a'
txt[1]='b'
txt[2]='c'
txt[3]='d'
txt[4]='e'
myfunc(txt); -> funzt nicht
myfunc("hallo"); -> funzt
und dann in der funktion:
void myfunc(char *text){
while(*text){
...
text++;}
}
der Fehler liegt auch noch woanders:
txt[5]='\0'
Zum cast:
myfunc(&txt[0]); sollte immer funzen.
VG,
/th.
Der Array-Pointer-Dualismus ist hier kein Problem.
Jedoch ist das von Hand initialisierte Array nicht nullterminiert - es
fehlt schlichtweg ein
txt[5] = 0;
Und außerdem nach jeder einzelnen Zeile mit der Initialisierung ein
Semikolon.
Im übrigen ist "funzt nicht" die dümmste aller nur denkbaren
Fehlerbeschreibungen.
Hier bei wird erst das Zeichen ausgegeben und dann auf '\0' geprueft.
void myfunc(char *text)
{
do
{
uart_putchar(*text);
} while(*text++);
}
Besser ist es zuerst auf '\0' zu pruefen
void myfunc(char *text)
{
while(*text)
{
uart_putchar(*text++);
}
}
sonst gibt man '\0' mit aus.
gruss Helmi
>return auf uC? okok, es gibt die _sys_exit(), aber das ist doch nciht dein >ernst??
Laut ANSI-C (C99) muss main() einen Wert zurückliefern (int).
Dass main() auf manchen Systemen nie verlassen wird - die typische
Endlosschleife bei Embedded-Systemen eben - daran haben die Ersteller
des Standards vielleicht nicht gedacht ;-)
Also erstmal vielen dank für die Antworten.
Offenbar hab ich mein Problem nicht genau genug beschrieben.
Das in meinem Beispiel die ; fehlen war mir schon klar, und in meinem
eigentlichen code war auch ein =0; vorhanden. Es ging auch nur darum,
die methodik der array übergabe darzustellen. Immerhin war das ja meine
Frage, wie ich den Array fehlerfrei in die funktion übergeben kann, und
nicht wie die Syntax von c ist.
myfunc(&txt[0]); hat den Fehler auch hervorgerufen.
@Rufus: falls du meinen gesammten post durchgelesen hast dann hättest du
genau gesehen, was für eine Fehlermeldung ich erhalten habe. Und auf
genau diesen Fehler bezieht sich das "funzt nicht". Insofern war nicht
meine Beschrwibung das Dumme ;-)
Grüße
Ich schrieb:
> Offenbar hab ich mein Problem nicht genau genug beschrieben.> Das in meinem Beispiel die ; fehlen war mir schon klar, und in meinem> eigentlichen code war auch ein =0; vorhanden.
Hmm. Dann darfst du dich nicht wundern, wenn die Helfer zum falschen
Problem antworten, wenn du Code mit eigentlich schon klaren Fehlern
postest.
> Es ging auch nur darum,> die methodik der array übergabe darzustellen. Immerhin war das ja meine> Frage, wie ich den Array fehlerfrei in die funktion übergeben kann, und> nicht wie die Syntax von c ist.> myfunc(&txt[0]); hat den Fehler auch hervorgerufen.
Dein Problem ist dein while(*txt)...
Du führst das while so lange aus, wie der Inhalt deiner Arrayzelle
ungleich 0 ist.
Wenn du bei der Definition des Arrays in main() keine 0 in das Array
reinschreibst, ist das Beenden des while nicht vorhersagbar. Irgendwann
kann zufällig eine 0 kommen, derweil läuft der Zeiger text in myfunc()
Amok...
Wenn du in deinem Array txt neben Buchstaben, Ziffern auch eine 0
ausgeben willst, kannst du das nicht mit while(*text) machen. Dann musst
du z.B. die Länge deines Arrays mitgeben z.B.
1
voidmyfunc(char*text,unsignedcharlaenge)
2
3
intmain(void)
4
{
5
chartxt[100];
6
7
txt[0]='a';
8
txt[1]='b';
9
txt[2]=0;
10
txt[3]='d';
11
txt[4]='e';
12
13
myfunc(txt,5);
14
return0;
15
}
16
17
voidmyfunc(char*text,unsignedcharlaenge)
18
{
19
while(laenge)
20
{
21
ausgabe(*text++);
22
laenge-=1;
23
}
24
}
Eine 2. Falle lauert auf µC:
Du legst das Array txt zur Laufzeit an (innerhalb main() und verlangst
100 Bytes dafür, nutzt aber nur 5. Je nach µC ist da schnell der Platz
im RAM weg und es kommt keine Fehlermeldung, wenn das passiert! Wenn du
den Speicher mit char txt[] = "hello" anlegst, gehen nur 5+1 Zeichen
drauf!
> wird ein standardkonformer Compiler wohl eher nicht akzeptieren. Obwohl,> ich seh grad, ist nur ne Warning und kein Error. Zumindest mit gcc> 3.4.5.
doch wird er, war vor kurzen hier im Forum erwähnt, es ist zulässig aber
nur bei main.
**g**
Ich liebe es kurz :-)
Ich bin allerdings von diesen längenangaben in meinem Programmen weg,
zumindest dort, wo ich mit strings arbeite. Macht auf dauer nur
probleme, z.B. beim Bearbeiten eines strings. old_len, new_len, tmp_len,
... **argh**
VG,
/th.
Ich schrieb:
> @Rufus: falls du meinen gesammten post durchgelesen hast dann hättest du> genau gesehen, was für eine Fehlermeldung ich erhalten habe.
Und ich behaupte mal:
Wenn dein (vollständiges) Programm so aussieht, wie es in deinem
Ursprungsposting angedeutet ist, dann kommt diese Warnung nicht.
Das was du gepostet hast, ist der normale und von C vorgesehene Weg, wie
man ein Array an eine Funktion übergibt (indem der Name des Arrays zu
einem Pointer auf das erste Array Element degradiert wird und dieser
Pointer an die Funktion zugewiesen wird).
Weder der Cast, noch &txt[0] dürfen da irgendetwas daran ändern.
Dass du deinen 'String' falsch aufgebaut hast und daher deine Schleife
innerhalb der Funktion nicht korrekt abbrechen wird, ist ein anderes
Problem.
In diesem Sinne hat die Warnung, so sie sich überhaupt auf den Aufruf
bezieht, nichts damit zu tun, dass dein Programm nicht funzt (was auch
immer 'nicht funzt' bedeutet). Du scheinst immer noch der Auffassung zu
sein: Wenn der Compiler nichts meldet, dann ist alles in Ordnung. Das
ist ein Trugschluss.
Mark Brandis schrieb:
> Aber nicht ohne Warnung.> Guter Code erzeugt keine Warnungen :-)
Im C-Standard gibt es keine Warnungen. Dort ist nur definiert, was als
Fehler zu gelten hat.
Wenn dein Compiler da eine Warnung rauswirft, dann kann er das tun.
Verpflichtet dazu ist er nicht.
1
intmain()
2
{
3
}
ist laut C-Standarddokument ein 100% legales, dem C-Standard
entsprechendes Programm. Da ist nichts falsch oder undefiniert. Jeder
standardkonforme Compiler weiß, wie er das zu übersetzen hat. Und wenn
er dieses Programm nicht richtig übersetzen kann, dann ist er
genaugenommen nicht standardkonform.
Das ist dasselbe, wie ...
1
intmain()
2
{
3
intc;
4
5
if(c=5)
6
c=8;
7
8
return0;
9
}
... ebenfalls ein dem C-Standard 100% entsprechendes Programm ist, auch
wenn in der if-Bedingung eine Zuweisung vorkommt. Das dich dein Compiler
freundlicherweise darauf aufmerksam macht, dass die Zuweisung
möglicherweise nicht das ist was du wolltest, ist zwar nett von ihm aber
wird vom Standard nirgends eingefordert. Einige Compiler warnen, andere
nicht. Aber das Verhalten, was dieser Code bewirken soll und wie er das
tut, ist 100% vom Standard definiert.
Mark Brandis schrieb:
> Warnings sind kein C-Standard? Echt jetzt? Hm, wieder was gelernt.
Dein Compiler kann dich auch warnen, dass das Badewasser übergeht.
Interessiert im C-Standard keinen Hund.
Hm, dann wiederum gibt es Sachen die der Standard verlangt, die aber bei
Nichtbeachtung durchaus eher eine Warnung als einen Fehler erzeugen.
(Bsp. "no newline at end of file"). Vielleicht daher meine Konfusion.
Mark Brandis schrieb:
> Hm, dann wiederum gibt es Sachen die der Standard verlangt, die aber bei> Nichtbeachtung durchaus eher eine Warnung als einen Fehler erzeugen.> (Bsp. "no newline at end of file"). Vielleicht daher meine Konfusion.
Der Standard kennt nur 2 Zustände.
Entweder das Programm entspricht den Regeln oder es entspricht nicht.
Alles was nicht entspricht ist automatisch ein Fehler und muss als
solcher gemeldet werden.
Was dein Compiler dir als Zusatzleistung noch an Warnungen ausgibt, ist
dem Standard egal.
Bisher reden wir nur von Syntaxfehlern, also Dingen die der Compiler zur
Compilezeit erkennen muss.
Nun gibt es natürlich noch Fehler, die der Compiler nicht erkennen kann
und die sich erst zur Laufzeit als Fehler bemerkbar machen. Davon gibt
es im Standard 2 Stück:
undefined behaviour
unspecified behaviour
Der Unterschied ist etwas akademisch, denn ein Fehler ist es auf jeden
Fall.
"unspecified behaviour" bedeutet, dass der Standard keine Vorgabe macht,
was in so einem Fall zur Laufzeit passieren soll. Derjenige der den
Compiler implementiert, kann sich etwas aussuchen. Wichtig aber: Was
genau passiert muss dokumentiert werden und es muss immer gleich sein.
Aber natürlich ist unspecified behaviour von Compiler zu Compiler
verschieden.
Bei "undefined behaviour" hingegen ist alles erlaubt. Der Standard macht
keine Vorgaben was passieren soll und es ist auch zulässig, wenn sich
das Programm anders verhält, weil die Mondphase anders ist.
> int main()> {> }>> ist laut C-Standarddokument ein 100% legales, dem C-Standard> entsprechendes Programm.Ganz sicher? Das ist K&R-Syntax (oder C++), ich würde da ein 'void' in
die runden Klammern schreiben.
Rufus t. Firefly schrieb:
>> int main()>> {>> }>>>> ist laut C-Standarddokument ein 100% legales, dem C-Standard>> entsprechendes Programm.>> Ganz sicher? Das ist K&R-Syntax (oder C++), ich würde da ein 'void' in> die runden Klammern schreiben.
OK. zu schnell getippt und nicht drauf geachtet :-)