mikrocontroller.net

Forum: Compiler & IDEs Warum diese Warnung?


Autor: R. Quentin (timebeast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
#include <avr/io.h>

void Versuch (unsigned char *Daten);


int main(void){
  
  unsigned char Test[5];

  *Test="Hallo";

  Versuch(Test);

return 0;
}


void Versuch (unsigned char *Daten){
  int irgendwas=0;
  irgendwas+=irgendwas;
}

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

Autor: Ronny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
char  Test[5];
*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:

void func1(char *str)
{
 //...
}

void main(void)
{
char test1[] = "Hallo Welt";  // Als Array
char *test2  = "Hallo Welt";  // Als Pointer

func1(&test1[0]);  // Zeiger auf 1.Byte übergeben
func1(test1);      // Startadresse übergeben

func1(test2);      // Zeigervariable übergeben
}

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
*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");

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch mal, dir den theoretischen und praktischen Unterschied zwischen
 char* test1 = "Hallo";
und
 char test2[] = "Hallo";

klar zu machen.

Oliver

Autor: R. Quentin (timebeast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Oliver,
naja, das eine schreibt "Hallo" an die Speicheradresse wo test1 liegt, 
das andere erzeugt mir ein Array of Char mit der Größ0e 5 Char.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: R. Quentin (timebeast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: R. Quentin (timebeast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Uhu Uhuhu:
entschuldigung, "umständlich" war falsch, exakt wollte ich schreiben! 
Sorry.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> >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:
       Variable test1
       Adresse 100       Adresse 500
        ---------        -----------
        | 500   | -----> | "Hallo" |
        ---------        -----------

test1 liegt also z.B. auf Adresse 100, der String "Hallo" auf Adresse 
500.
Auf Adresse 100 steht 500 - nicht "Hallo"!

Autor: R. Quentin (timebeast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ging auch nur darum, dir den Unterschied zwischen den verschiedenen 
Möglichkeiten klar zu machen.

Autor: R. Quentin (timebeast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :-)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.