Hallo Leute,
hab gerade nen kleines Problemchen mit der Übergabe von Char-Feldern,
sprich Strings. Hier mal ein kleines Beispiel Programm welches das
Verhalten hat:
1
#include<avr/io.h>
2
3
voidVersuch(unsignedchar*Daten);
4
5
6
intmain(void){
7
8
unsignedcharTest[5];
9
10
*Test="Hallo";
11
12
Versuch(Test);
13
14
return0;
15
}
16
17
18
voidVersuch(unsignedchar*Daten){
19
intirgendwas=0;
20
irgendwas+=irgendwas;
21
}
Dieses Programm erzeugt eine Warning:
../Uebergabe_Test.c:10: warning: assignment makes integer from pointer
without a cast
Kann mir jemand sagen was ich falsch mache?
Vielen Dank im vorraus
Ralf
Dein Code legt ein Array für 5 Bytes an,dein String ist allerdings
länger,nämlich 10 Bytes für den Text und eines für die Ende-Kennung
0x00. Also 11 Byte.
1
char Test[5];
2
*Test="Hallo welt";
Deine zweites Problem besteht im Ausdruck (*Test). Der derefernziert
nämlich die Variable Test,d.h. du versuchst der Speicherstelle wo "Test"
liegt einen Wert zu zuweisen. Und das Stringliteral "Hallo Welt" gibt in
dem Fall einen Zeiger(!) auf den besagten String zurück. Und der wird
dann in Test geschrieben.
Da Test allerdings dem Compiler nur als 8-Bit Wert bekannt ist,wundert
es mich etwas dass da kein Fehler gemeldet wird oder zumindest ein "Loss
in precision".
Vorschlag:
*Test ist dasselbe wir Test[0]
Die Fehlermeldung ist etwas irreführend, aber C-typisch:
Test ist für den Compiler ein konstanter Zeiger auf 5 unsigned char.
*Test wird auf int erweitert.
*Test = "Hallo";
bedeutet: Weise dem ersten Element die Adresse von "Hallo" zu. Das geht
nur, wenn die Adresse - die ein Pointertyp ist - in int umgewandelt
wird.
Da solche Sachen in aller Regel auf einen Fehler deuten, gibt der
Compiler eine Warnung aus.
Du mußt also entweder
unsigned char Test[5] = "Hallo";
schreiben - dann fehlt aber die abschließende \0 im String, darüber
würdest du dann bei nächster Gelegenheit fliegen, oder, wenn du den
String ändern willst:
strcpy(Test, "Hallo");
was dir den Speicher zerklopft, weil das Ende von Test überschrieben
wird.
Um diese Probleme zu umgehen, mußt du folgendermaßen vorgehen:
unsigned char Test[] = "Hallo"; // Der Compiler reserviert 6
chars
oder
unsigned char Test[6];
strcpy(Test, "Hallo");
R. Quentin wrote:
> naja, das eine schreibt "Hallo" an die Speicheradresse wo test1 liegt,
Das ist falsch.
char* test1
erzeugt einen char pointer und
char* test1 = "Hallo";
reserviert eine Stringkonstante im Speicher und initialisiert test1 mit
deren Adresse.
Es gilt
sizeof test1 == sizeof (char *)
Du solltest dich nochmal ausführlich mit den Grundlagen von C
beschäftigen!
Also nur mal so zum Verständnis, ein Pointer ist nichts weiter als ein
Zeiger auf eine Speicheradresse, zumindest hab ich das mal so gelernt.
Also würde doch
char* test1
alleine geschrieben auf einen nicht näher spezifizierten (nicht
initialisierten) Speicherbereich zeigen.
char* test1 = "Hallo";
>reserviert eine Stringkonstante im Speicher und initialisiert test1 mit>deren Adresse.
ÄÄÄh, und was hab ich geschrieben: schreibt "Hallo" an die
Speicheradresse wo test1 liegt, zwar nicht so umständlich ausgedrückt
wie Du, aber doch exakt das selbe.
>Du solltest dich nochmal ausführlich mit den Grundlagen von C>beschäftigen!
Bin ich genau in diesem Augenblick dabei ;-) und da gibt es dieses
Warning was ich nicht verstehe...
> >reserviert eine Stringkonstante im Speicher und initialisiert test1 mit> >deren Adresse.> ÄÄÄh, und was hab ich geschrieben: schreibt "Hallo" an die> Speicheradresse wo test1 liegt, zwar nicht so umständlich ausgedrückt> wie Du, aber doch exakt das selbe.
test1 liegt nicht dort, wo der String "Hallo" steht. Was du schreibst
ist definitiv falsch.
Im Speicher sieht das Ganze ungefähr so aus:
1
Variable test1
2
Adresse 100 Adresse 500
3
--------- -----------
4
| 500 | -----> | "Hallo" |
5
--------- -----------
test1 liegt also z.B. auf Adresse 100, der String "Hallo" auf Adresse
500.
Auf Adresse 100 steht 500 - nicht "Hallo"!
Mist, ich merke gerade das das alles hier eh vergebliche Liebesmühen
sind. Es ging mir ja explezit um die Zuweisung eines Strings in ein
Array of Char. Ich wollte damit erreichen das ich halt nur einmal ein
Array of Char erzeuge und dann halt, je nach Anforderung, verschiedene
Strings hineinschreibe. Was mir halt gerad auffiel ist, wo speichert er
wohl die "Zuweisungsstrings"?
Also kann ich mir auch gleich die gewünschte Anzahl Array of Char´s
erzeugen und die dann explizit mit Namen übergeben. Damit fällt dieses
ganze Pointer, reservierungs übergabe StringCopy Gemache weg.
Mit strcpy hat das ganze im übrigen geklappt, muß man halt noch die
<string.h> includieren, und kann dann strings einem Char Array zuweisen
(halt keine unsigned chars, naja). Aber das Programm wird durch den
include der <string.h> auch nicht gerade kleiner ;-)
Gruß und danke für die Mühe
Ralf
Huch, tatsächlich, hab ich Mist geschrieben...ups, gemeint hatte ich
aber,...
äääh, ja, nein, oky, du hast recht,.... aaargh, ärgerlich
("schreibt "Hallo" an die Speicheradresse die in test1 liegt")
Danke für die Mühe Uhu Uhuhu
P.S.: Nettes Bild :-)
> Also nur mal so zum Verständnis, ein Pointer ist nichts weiter als ein> Zeiger auf eine Speicheradresse, zumindest hab ich das mal so gelernt.
"Pointer" ist das englische Wort für "Zeiger".
> Also würde doch> char* test1> alleine geschrieben auf einen nicht näher spezifizierten (nicht> initialisierten) Speicherbereich zeigen.
Ob der Speicherbereich initialisiert ist oder überhaupt existiert, weißt
du nicht. Der Zeiger selbst ist nicht initialisiert, zeigt also einfach
irgendwo hin.