Komme bei Strukturen durcheinander...
-
Denk dir das struct fern drumherum mal weg. Dann steht beim ersten:
struct gr { short breite; short hoehe; short tiefe; } groesse;
Das ist zwar etwas ungewöhnlich, weil man das struct gr vielleicht noch woanders brauchen könnte, aber legal. Es definiert das struct gr und erzeugt eine Instanz groesse davon. Beim zweiten steht:
struct gr { short breite; short hoehe; short tiefe; };
Das ist die Definition eines structs (Du definierst hier einen Datentyp namens struct fern::struct gr), allerdings keine Instanziierung. Das nachfolgende
struct gr groesse;
funktioniert nicht, weil struct gr nicht im globalen scope definiert ist, sondern innerhalb des structs fern, und fernseher.groesse.breite ist nicht definiert, weil das struct fernseher keinen member namens groesse hat. Beim dritten widerum definierst du zwar das struct fern korrekt, aber erzeugst keine Instanz davon.
-
Fall 2: das
struct fern fernseher wird auch ausserhalb des ganz structs deklariert und es geht,wieso nicht mit dem struct gr ?
verstehe nicht, beim aüssersten struct darf die deklaration aussen stehen,abe rim inneren nicht ?
Also müsste ich,wenn ich vom struct gr z.b. eine variable mit nem feld haben will,das auch noch inenrhalb dieses structs machen ?WIE ?
Ausserdem noch ne Frage:
wieos gibt der so beide werte aus, versteeh nicht warum, der pointer zeigt doch nur auf die struktur selbst,nicht auf die werte,trotzdem geht es !?
#include <stdio.h> #include <stdlib.h> int main() { struct hh { double d1,d2; }; struct hh *pt; pt->d1 =3.0; pt->d2=4.0; printf("%f%f",*pt); }
-
Fall 2: das
struct fern fernseher wird auch ausserhalb des ganz structs deklariert und es geht,wieso nicht mit dem struct gr ?
verstehe nicht, beim aüssersten struct darf die deklaration aussen stehen,abe rim inneren nicht ?
Also müsste ich,wenn ich vom struct gr z.b. eine variable mit nem feld haben will,das auch noch inenrhalb dieses structs machen ?WIE ?
oder so dann oder:
#include <stdio.h> int main() { struct fern { char firma[20]; char modell[20]; float preis; struct gr { short breite; short hoehe; short tiefe; }; struct gr groesse[10]; }; struct fern fernseher; fernseher.groesse[0].breite = 951; printf("%d\n",fernseher.groesse[0].breite); }
Ausserdem noch ne Frage:
wieos gibt der so beide werte aus, versteeh nicht warum, der pointer zeigt doch nur auf die struktur selbst,nicht auf die werte,trotzdem geht es !?
#include <stdio.h> #include <stdlib.h> int main() { struct hh { double d1,d2; }; struct hh *pt; pt->d1 =3.0; pt->d2=4.0; printf("%f%f",*pt); }
-
Beim Fall2 das wichtige ist nicht das fern außerhalb, sondern das gr innerhalb von fern definiert ist und somit außerhalb von fern nicht sichtbar ist.
Sinnvoller wäre eine Definition der folgenden form
#include <stdio.h> struct gr { short breite; short hoehe; short tiefe; }; struct fern { char firma[20]; char modell[20]; float preis; struct gr groesse; }; int main() { struct fern fernseher: fernseher.groesse.breite = 951; printf("%d\n",fernseher.groesse.breite); return 0; }
Immer daran denken
:p nicht alles machbar ist ist auch sinnvoll,
und nicht alles was sinnvoll ist ist macbbar :p
-
an alle, die hier meinen, struct gr wäre ausserhalb nicht sichtbar, weil es innerhalb von fern definiert ist: DAS IST C, NICHT C++
-
Ach ja, C und Scoping war ja so ne Sache...*peinlich*
Wie auch immer. Der Aufruf
struct hh *p; p->d1 = 2; p->d2 = 3;
ist gefährlich, weil du keinen Speicher für das eigentliche struct angefordert hast (der Zeiger zeigt irgendwo wild in die Gegend. Das kann gut gehen, muss es aber nicht). Wenn du unbedingt nen Zeiger verwenden willst (wovon ich, wenn es anders geht, abraten würde), dann wenigstens so:
struct hh eigentliche_instanz, *zeiger_auf_instanz = &eigentliche_instanz;
Der Aufruf
printf("%f%f", *p);
funktioniert, weil dein Betriebssystem die Werte im struct und auf dem stack zufällig direkt hintereinanderschreibt. Darauf verlassen kannst du dich nicht; zum Beispiel wird dir dieser Code auf Maschinen mit verschiedenem Endian verschiedene Ergebnisse liefern, und du machst Annahmen über den Aufbau des Stacks, die auch nicht gesichert sind.
-
also das:
struct hh eigentliche_instanz, *zeiger_auf_instanz = &eigentliche_instanz;wäre dann richtig ? Will ja keine Zeiger verwenden,hab ja keien aufgabe zu lösen,will nur alles komplett verstehen,auch sonderfälle.
oder was meinst mit speicher für struct anfordern ? mit malloc, nee oder ? Denke du meinst das das struct nur nen namen hat und noch keine eigene Variable oder ?
Bei sowas braucht man ja eh keine zeiger,aber muss ja zeiger können,weil man sie bestimmt irgendwann mal braucht.
Ist zwar noch C aber schriebe Mittwoch c++ Klausur, aber muss ja structs erstmal verstehen um Klassen z.b. zu lernen.
Blöd nur das mein buch jetzt Zu ende ist,war gut beschrieben, c++ wird vllt. unter garnz andere Voraussetzungen beigebrahct in nem anderen Buch...
-
@Bashar Danke für die Korrektur bezüglich des Scopings.
Abgesehen davon das ich nicht auf die Idee kommen würde Strukturen innerhalb von Strukturen zu definieren und diese dann eigenständig zu benutzen.
Ich ging davon aus das es ist wie mit Blockstatements, was innerhalb eines Blocks definiert ist, ist außerhalb nicht sichtbar. (leider falsch)
-
Also, folgendes: Der Aufruf
struct hh meine_instanz;
fordert Speicher für ein struct hh an, und nennt ihn in Zukunft meine_instanz. Der Aufruf
struct hh *mein_zeiger;
fordert Speicher für einen Zeiger an und nennt ihn in Zukunft mein_zeiger. Es wurde kein Speicher für das eigentliche struct angefordert. Man kann zwar auch per malloc Speicher anfordern, aber wenn du den Speicher nur lokal brauchst, bietet es sich an, eine lokale Variable zu benutzen, weil du die nicht von Hand wieder freigeben musst - sie fliegt vom Stack, sobald der Kontext, in dem sie besteht (idR die Funktion) verlassen wird. Wenn du malloc benutzt, musst du höllisch aufpassen, dass du keinen Speicher leckst (Speicher anforderst, ohne ihn nachher wieder freizugeben), deswegen würde ich das vermeiden, wo immer es geht. Das ist nicht immer möglich - zum Beispiel wirst du Probleme haben, eine verkettete Liste oder einen Baum ohne malloc/free zu verwirklichen - aber in den meisten Fällen kommt man ohne recht gut aus.
Was Zeiger angeht - gerade in C++ brauchst du die nur noch sehr selten, weil es da Referenzen gibt. Wo du in C noch
void quadriere(int *p) { *p *= *p; } /*...*/ int i = 2; quadriere(&i);
schreiben musstest, schreibst du in C++:
void quadriere(int &p) { p *= p; } //... int i = 2; quadriere(i);
Damit fällt das hauptsächliche Anwendungsgebiet von Zeigern in C++ weg. Es ist trotzdem noch sinnvoll, damit umgehen zu können, aber ähnlich wie malloc sollte man sie eher vermeiden - zumindest meiner Meinung nach. Man kann damit die wildesten Effekte haben - nur zum Beispiel:
int *zeiger; void do_something() { int zahl = 3; zeiger = &zahl; } void do_something_else() { printf("%d\n", *zeiger); } int main() { do_something(); do_something_else(); }
Wenn do_something verlassen wird, ist "zahl" nicht mehr gültig, das heißt, "zeiger" zeigt ins Nirvana, und da steht eher zufällig noch die 3, die mal in "zahl" stand. Mit solchen Sachen kann man die wildesten Effekte haben.
-
Öhm ich schriebe ja mehr c++, jedenfalls habe wir da sam ende des semsters gehabt, heisst das,dass ich das gelernte über zeigern in c gar nicht brauche und ich das in c++ ga rnicht anwenden kann ?
Für mich ist c++ bisher fast das gleiche,ausser anderer ausgabe befehl und so...
man nimmt ja auch gleiche editor , compiler und so dafür ??
Ausserdem dachte ich das zeiger mit am wichtigsten bei c/c++ sind !?
-
Ich würd nicht sagen, dass du es garnicht anwenden kannst. Ich meine nur, dass du es selten musst, und wenn du es nicht musst, nicht solltest. Der Code wird dadurch schnell unübersichtlich, und es ist eine beliebte Quelle für Heisenbugs.
C++ ist auf jeden Fall nicht das Gleiche wie C - C++ ist aus C entstanden, bringt aber wesentliche neue Bestandteile mit - Klassen, Polymorphismus und was sonst noch so zu OOP gehört, templates (also generische Strukturen) und nicht zuletzt die STL. C++ ist eine Übermenge von C, das heißt, jeder gültige C-Code ist auch in C++ gültig, umgekehrt gilt das nicht. Dementsprechend kann ein C++-Compiler beide Arten von Code übersetzen, ein C-Compiler aber nur C. Wenn C++ dich interessiert, kann ich dir das Buch "C++ für Dummies" empfehlen, das erklärt das alles ziemlich gut. Ein Buch wirst du auf jeden Fall brauchen, C++ ist einfach zu umfangreich, als dass man es eben mal so erklären könnte.
-
0xdeadbeef schrieb:
C++ ist eine Übermenge von C, das heißt, jeder gültige C-Code ist auch in C++ gültig, umgekehrt gilt das nicht. Dementsprechend kann ein C++-Compiler beide Arten von Code übersetzen, ein C-Compiler aber nur C.
falsch
-
Manchmal ist es richtig schön, wenn man die Antwort auf ein Wort reduzieren kann.
P.S. Warum das so ist einfach mal im Forum suchen.
-
Ja, klar. Mein Fehler, und gerade in diesem Thread ein bisschen peinlich, weil wir den Unterschied im Scoping schon besprochen hatten. Um das "zu Kreuze kriechen" zu vervollständigen:
struct a { struct b { }; }; int main() { struct b c; }
ist in C legal, in C++ aber nicht. Auch in C-Golf häufig verwendeter Code wie
main(c,s)int*s;{/*...*/}
ist in C++ illegal. Aber ich glaube, den haben sie auch mit C99 abgeschafft, oder? Dafür gibts in C99 wieder long longs, die C++ nicht kennt... Ich muss gestern wirklich müde gewesen sein...