Hi,
bin gerade dabei ein Menü zu erstellen. Jetzt bin ich auf ein Problem
gestossen, das ich mir bisher nicht beantworten kann und hoffe das ihr
mich auf den Pfad der Erleuchtung führen könnt :)
ich habe diese header Datei erstellt
1
#ifndef MEN_MENUE_H
2
#define MEN_MENUE_H
3
4
5
externstructpage_thauptmenue;
6
7
8
/* Struktur der Anzeige-Page. Jede Menüseite sowie Funktionsseite
9
* wird durch diesen Struct definiert
10
*/
11
structpage_t{
12
charbezeichnung[15];// Menütext der Seite
13
structpage_t*untermenuseiten_p[5];// Array von Zeigern auf die Unterpages der aktuellen Page
Wenn ich das aber mache, bekomme ich diese Fehlermeldung
(../Menue/MEN_main.c:8: error: incompatible types in assignment)
und er markiert mir die Zeile ( hauptmenue.bezeichnung = "Test"; )
Ändere ich jetzt in meiner Struktur den member "bezeichnung", das
anstatt
1
charbezeichnung[15];
2
char*bezeichnung;
geschrieben wird, bekomme ich beim kompilieren keinerlei Fehlermeldungen
mehr.
Wo liegt hier der Fehler ? die Zeichenkette "Test" war doch weniger wie
15 Zeichen lang.......
danke schonmal fürs lesen
gruss Maggus ;)
Lasse S. schrieb:> Guck dir mal an, was Strings in C eigentlich sind.
Ich weiss das Strings aus einem char Array mit '/0' am Ende bestehen.
Und das "bezeichnung[0]" eigentlich ein Zeiger auf die Adresse der
ersten Stelle dieses Arrays ist.
Wenn ich eine Zeichenkette zuweise, die länger ist wie char's reserviert
wurden, überschreibe ich mir den Arbeitsspeicher. Die Gefahr laufe ich
bei der zweiten Zuweisung von
1
2
char*bezeichnung="test";
3
bezeichnung="Das ist zu lang"
wenn mich nicht alles täuscht.
Das erklärt mir aber nicht, wieso ich beim initialiseren von
die Zwueisung machen darf, und später in der Funktion
1
hauptmenue.bezeichnung="Test";
auf einmal nichtmehr.
Das würde ja bedeuten, das der Compiler bei einer einfachen Zuweisung
und einer initialisierung unterschiede mit den Datentypen machen würde.
Will das jetzt nicht bis ins kleinste erklärt bekommen wenn es zu
Umfangreich ist, aber ich würde mich über einen Schups in die Richtige
Richtung freuen, damit ich weiss wo ich nachlesen muss (das wird
wahrscheinlich nicht wenig sein :D )
gruss Maggus
Alles klar,
danke dir Dirk.
Strings im Nachinein zu verändern geht ja in C garnicht so einfach wie
ich mir das gerade vorgestellt hatte.
Ich glaube ich lasse die Initialisierung bei der Variablendeklaration
einfach weg.
Eben hab ichs verstanden......... ;)
oder auch nicht :D
Wieso muss ich den String mit
strcpy(hauptmenue.bezeichnung,"Test");
in die Struktur kopieren?
Selbst wenn ich die initialiserung am Anfang weglasse und nur zuweise,
schreibt er den selben Fehler heraus.
Ich hab irgendwo noch einen ziemlich dicken Denkfehler drin......
Das habe ich mir gedacht :-)
Der Knackpunkt ist, wann und wie der Compiler die tatsächliche Länge des
Strings überhaupt feststellen kann.
Deswegen der Unterschied zwischen Initialiserung und Zuweisung.Die
Initialisierung sieht nur oberflächlich so aus wie eine Zuweisung. Der
Punkt ist nicht der Typ sondern, das der Compiler, da er bei der
Initialisierung die Länge des Strings kennt auch den Speicher dafür
reservieren kann. Eine Zuweisung aber findet nicht zur Compilierzeit
sondern zur Laufzeit statt. Dann aber kann der Compiler nichts mehr
machen. Er ist garnicht mehr aktiv. Und die Programme bekommen keinen
Code mit um zur Laufzeit die Länge von String zu berechnen wenn eine
Zuweisung auftritt.
Das Ergebnis von dem oben gesagten ist, das Du zur Laufzeit selbst
Speicher reservieren musst (alloc, malloc) und den String selbst
kopieren musst (strcpy).
Das der Compiler bei strcpy denselben Fehler bringt wie bei dem Versuch
der Zuweisung halte ich, sagen wir mal, für einen Irrtum.
>Selbst wenn ich die initialiserung am Anfang weglasse und nur zuweise,>schreibt er den selben Fehler heraus.
Uups. Halt. Da habe ich falsch gelesen.
Der Knackpunkt ist wiegesagt, die Zuweisung. Zur Laufzeit kann das
Programm nicht selbst die Länge berechnen und Speicher reservieren. Das
musst Du dann selbst machen.
ok, ....
Lars hatte recht. Ich muss nochmal lesen wie ich Strings in C behandeln
muss :D
das deklarieren von Strings über ein Array mit
1
chartext[15];
birgt doch mehr verständniss das man haben muss.
ich merke mir mal:
Wenn das char Array bereits angelegt wurde, sprich der Speicher
bereitgestellt, muss dieser per Hand befüllt werden
text[0] = 'a'
text[1] = 'b'
etc.
Das ist deshalb nötig , da zur Laufzeit der Reservierte Speicher durch
zuweisungen wie
text = "Test";
nichtmehr automatisch angepasst werden kann, wie es der Compiler machen
würde.
Glaube das klingt ganz gut.....
Markus schrieb:> ich merke mir mal:> Wenn das char Array bereits angelegt wurde, sprich der Speicher> bereitgestellt, muss dieser per Hand befüllt werden> text[0] = 'a'> text[1] = 'b'> etc.
Quatsch,
Das kann man so machen, wenn man Masochist ist.
Man kann aber auch ganz einfach die Sammlung der str.. Funktionen
benutzen, die in deiner Laufzeitumgebung schon fertig vorhanden sind.
> Das ist deshalb nötig , da zur Laufzeit der Reservierte Speicher durch> zuweisungen wie> text = "Test";> nichtmehr automatisch angepasst werden kann, wie es der Compiler machen> würde.
Jain.
Der Knackpunkt ist, dass man in C keine Arrays zuweisen kann.
Arrays sind in C Bastarde, die sich nicht ganz so verhalten, wie andere
Datentypen.
Spar dir das rumraten, kauf dir ein C Buch und arbeite das erste Drittel
durch. Dann kennst du das alles und brauchst nicht mehr raten.
In der Zwischenzeit, bis du dein Buch hast, kannst du dich hier mal über
Strings einlesen.
http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F
sagst du dem Compiler, er solle dir die Strucktur 'hauptmenu', wie in
den geschweiften Klammern beschrieben vor initialisieren. - Der Compiler
erledigt das.
Weiter unten in
1
hauptmenue.bezeichnung="Test";
weist du einen Zeiger einem Array zu. Der String "Test" ist als
Konstante
im Code abgelegt und du hältst einen Zeiger darauf. Der C Compiler hat
keine
Ahnung wie er den Zeiger dem Array zuweisen soll. Du musst also den Text
mit
strcpy() hinein kopieren.
Hoffe es hilft weiter
Gruss
Auf jedenfall habt ihr mir schonmal ein gutes Stück weitergeholfen was
mein Verständnissproblem betrifft.Danke nochmal...
Habe mir
"Programieren in C" von Kernighan und Ritchie gekauft
( Sehr detailliert, aber was das Thema hier betrifft schwer zu erlesen)
und
"Softwareentwicklung in C für Microprozessoren und Microcontroller" von
J. Wiegelmann
( Cooles Buch, macht Spass zu lesen)
gekauft
Meiner Meinung nach sind solche Kniffe die den Compiler betreffen, aus
diesen Büchern (falls überhaupt vorhanden) nur schwer auszulesen.
Gibt es denn gute Bücher über den GCC Compiler zu kaufen, die auf
Anfänger wie mich hin zielen und mir bei solchen Problemen weiterhelfen
können ?
Wenn ich das hier so lese, ist das ja ziemlich verständlich, aber der
Vorteil von diesem Forum ist das ihr auf meine Fragen eingehen könnt.
Das kann ein Buch nicht.
Bin ja echt froh das es das Forum hier gibt ;)
>Meiner Meinung nach sind solche Kniffe die den Compiler betreffen, aus>diesen Büchern (falls überhaupt vorhanden) nur schwer auszulesen.
Das ist kein Kniff. Das ist die Sprachdefinition und die lernst Du aus
Deinem Buch. Man Vektoren initialisieren aber nicht zuweisen. Punkt.
>Gibt es denn gute Bücher über den GCC Compiler zu kaufen, die auf>Anfänger wie mich hin zielen und mir bei solchen Problemen weiterhelfen>können ?
Das hat nichts mit GCC zu tun, sondern folgt aus der Sprachdefinition.
Jeder Compiler macht das (hoffentlich) so.
Tatsächlich ist meine Erklärung sozusagen eine nachträgliche.
Aber man kann das schliessen, wenn man mal selbst einen Compiler
schreibt. Wenn Zuweisungen möglich wären müsste man Speicher
alloziieren, evtl. den Zeiger verändern und sich Gedanken darüber
machen, ob andere Zeigervariablen nicht evtl. auch diesen Zeiger
enthalten. Wegen der Probleme die das mit sich bringt, ist man dankbar,
das Zuweisungen nicht möglich sind.
Ich glaube das Problem ist das ich gelernter Autoelektriker bin mit
garkeine Ahnung von Informatik.
Ich versuche mir das ganze Autodidaktisch beizubringen, und da muss man
eben einfach auf die Hilfe von Büchern zurückgreifen (od. Foren).
Deshalb entschuldigt die Fragen, ..... ;)