Zum Inhalt springen

Fragen zu C++


d.r.eam

Empfohlene Beiträge

Hallo mitteinnander, wir haben grade unser C++ Abschlussklausur bekommen und ich habe

da mit den Lösungen bzw. Formulierungen

der Aufgaben so meine Probleme, also schreibt doch einfach mal was ihr genommen hättet!

----------------------------------------

Variablen können zur Laufzeit(dynamisch)

wie folgend deklariert werden!

1 mit delete

2 mit create

3 geht nicht, Variablen müssen immer im Quellcode deklariert werden und müssen zur Übersetzung

4 mit new

5 durch Aufruf des Konstruktors

--------------------------------------------

Der Datentyp char*

1 definiert einen Speicherplatz von einem Byte

2 deklariert einen Speicherplatz von einem Byte

3 definiert einen Speicherplatz für ein Characterzeichen

4 definiert einen Speicherplatz für eine Adresse einen Characterzeichen

5 definiert den Speicherplatz für einen String

--------------------------------------

Speziell bei der 2. Aufgabe

habe ich erst auf 4(wäre richtig gewesen) gesetzt habe meine Meinung dann auf 2 geändert, mittlerweile bin ich der Meinung das keine der Auswahlen wirklich korrekt ist!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Original erstellt von d.r.eam:

<STRONG>

--------------------------------------------

Der Datentyp char*

1 definiert einen Speicherplatz von einem Byte

2 deklariert einen Speicherplatz von einem Byte

3 definiert einen Speicherplatz für ein Characterzeichen

4 definiert einen Speicherplatz für eine Adresse einen Characterzeichen

5 definiert den Speicherplatz für einen String

--------------------------------------

</STRONG>

5 - weil ein speicherplatz = adresse = zeiger ist und weil dem variablennamen dahinter dann ein string zugewiesen werden kann

[ 01. Juni 2001: Beitrag editiert von: toosten ]

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

zu 1) Bei dieser Frage würde ich Antwort 3 nehmen. Da höchstens der Speicherplatz einer Variablen zur Laufzeit also dynamisch reserviert werden kann und nicht die Variable selbst. Sie muss in jedem Fall im Quellcode vorhanden sein auch wenn Speicherplatz mit new usw. dynamisch reserviert wird. Die deklaration von Variablen zur Laufzeit wäre zwar machbar, es beschreibt aber keine andere antwort diese möglichkeit.

zu 2) Bei primitiven Datentypen (wie char) ist es ja so das sie eigentlich nur die Größe des Speicherplatzes für eine Variable dessen Typs angeben. Und da char* ein Zeiger auf eine Char-Variable ist, und Zeiger immer die Adresse eines Speicherplatzes enthalten würde ich in jedem Fall Antwort 4 wählen.

Du hast aber recht die Fragen sind wirklich blöd formuliert und man muss schon zweimal hinschauen damit man auf die Fallen nicht reinfällt. :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

@EisenUli,

genau dasselbe habe ich auch gedacht, aber ich musste mich halt für eine Lösung entscheiden also habe ich die Deklaration genommen -> weil mit "char* zeichen;" nunmal

Bezeichner und Datentyp festgelegt wird, also eher Deklaration als Definition.

zu 1. hatte ich den gleichen Gedankengang

wie Gmeiner P!

Soviel zum thema Lehrkräfte!! :confused:

Ich kann mich zwar nicht beklagen, war ja immerhin Klassenbester, aber sowas ärgert schon ungemein und das war nicht das erstemal!

mfg

[ 03. Juni 2001: Beitrag editiert von: d.r.eam ]

Link zu diesem Kommentar
Auf anderen Seiten teilen

Original erstellt von EisenUli:

<STRONG>Grrr, ich auch ne Lehrkraft. *'#?ß)(&%$§!"

</STRONG>

nobody is perfect :D

--------------------------------------------

Aber mal im Ernst, wenn ich die Beiträge hier im Forum lese, dann scheint die Situation in

den meisten Bildungsträgern und Berufsschulen

gleich zu sein.

mfg

P.S. Ausnahmen bestätigen die Regel ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Original erstellt von maddin:

<STRONG>naja präsentiert einem lehrer mal einen prototypen folgender art.

int funktion (int a, ... );

der würde euch doch den kopf abreisen oder nicht. ?!?!?!?</STRONG>

Wieso das denn???

(Am besten sag ich kein Wort mehr ohne meinen Anwalt.) :D

Uli

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Uli,

zum kommentar von dir zu Frage 2)

Es ist schon klar das der Ausdruck char* allein überhaupt nichts bewirkt wenn er nur so alleine dasteht. Doch könnte man die fragestellung auch nicht wie folgt interpretieren:

Der Datentyp char* legt fest wie der Speicherplatz einer Variable dieses Typs auszusehen hat. Man könnte doch auch annehmen das sich das definiert nicht auf irgendeine Speicherplatzdefinition bezieht (was sicher naheliegend erscheint) sondern auf die DEFINITON des Datentypen char*. Was ich meine ist das ja irgenwann einmal festgelegt wurde was den ein char* eigentlich ist und wie das ganze aussieht. In unserem Fall wäre daher Antwort 4 in meinen Augen schon recht zutreffend. Man könnte ja auch anstatt char* sagen Speicherplatz_für_Adresse_eines_Characters, oder?

Nur mal so als Anmerkung und anregung für diskussionen.

mfg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nun nochmal um Euch alle ganz wirr zu machen:

Ich lese meist von rechts nach links um dahinterzusteigen was gemeint ist:

char * ist ein Zeiger auf einen char, da aber nichts dabei steht handelt es sich nur um eine Typ-Vereinbarung für einen Zeiger und alle Antworten sind falsch weil einfach mehr nicht da steht (es sei denn man will was reininterpretieren).

Ob das das erste Zeichen eines Strings ist ist ungewiß. Aber eines ist sicher:

Es ist kein Unterschied zwischen einem Array und einem Zeiger außer die Schreibweise und daß der Zeiger austauschbar ist; beide werden vom Compiler gleich behandelt weil beide auf ein Zeichen des definierten Typs zeigen!

Das war nur so als Denkanstoß weil´s zum Thema paßt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was heisst hier es gibt keine Unterschied zwischen Array und Zeiger?

Ein Array hat natürlich einen Zeiger aber wenn ich

char cMyArray[5];

schreibe werden ja mehr Byte angelegt als bei

char* pPointer;

Um nochmal auf die Fragen zurückzukommen.

Was findet Ihr denn bei 2. so schwer?

Finde 4. ist doch relativ logisch, schliesslich zeigt ein char* grundsätzlich auf ein char also ein Zeichen.

Das viele Funktionen mit Übergabe eines char* die Anfänge von Strings hinundherschieben spielt dabei doch keine Rolle.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Cool-Matthias: Korrigier mich , wenn ich falsch liege, aber soweit ich weiß legt der Compiler weder mit char* pPointer noch mit char Feld[5] Speicher an...

Dieser wird erst im Prozess physisch angelegt, wenn Werte dazukommen, also:

char* pPointer=new char[5];

Feld[3]='A';

gruß gugel

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nach deiner Methode hiesse das also ein

char a[5] wäre gleichzusetzen mit einem

new char[5] ?

Das meinst du doch nicht ernst oder?

Schliesslich handelt es sich bei einem Array nicht um dynamischen speicher.

Wenn du ein Array anlegst bleibt der Speicher solange reserviert bis die Variable zerstört wird und nicht erst wenn ich ein 'a' reinschreibe sondern schon beim Erstellen des Arrays.

Aber um zum Punkt zu kommen.

Bei einem Pointer werden 4 Byte reserviert, bei einem Array kommt das auf den Typ und die groesse an.

Mfg

Matthias

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Cool-Matthias Nix für ungut, wir verstehen uns nur falsch :

Ich meinte nur, daß der Compiler Maschinencode anlegt, der bei einer Zeile wie char* pPointer, keinen Code generiert!

Er merkt sich nur Symbole, deshalb auch immer die Compiler-Warnungen, daß eine Variable angelegt wurde, die nie verwendet wird (kennt sicher jeder von uns *ggg*)

Sobald dieses Symbol einen Wert bekommt (hat mit dem Stack-Frame zu tun) erzeugt der Compiler Code (irgendeinen MOV nehm ich an)

und das Programm wird bei der Ausführung diesen Speicher mit diesem Wert belegen.

Dasselbe trifft meines Wissens nach auch für die Zeile char Feld[5] zu. Auch hier wird kein Code generiert (wie sollte der in Assembler auch aussehen ???)

Aber Anweisungen (die sich natürlich unterscheiden von der Semantik) wie:

char* pPointer=new char[5];

und

char Feld[5]={'a','b','c','d','e'};

erzeugen physischen Code, der bei Prog-Ausführung auch Speicher reserviert.

gruß gugel :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gut, dann hab ich dich nur falsch verstanden :)

Das mit dem Array müsste man direkt mal probieren und sich angucken was im Speicher passiert. Fakt ist aber spätestens wenn ich auch nur einen char in dem Array benutze wird wahrscheinlich die komplette groesse reserviert (zumindest so meine Vermutung).

Oder was denkst du dazu?

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Cool-Matthias:

Genau das ist es!

char Feld[5]; -> kein Code

cout << Feld[4]; -> 5 Byte Speichern anlegen (aber nur hier !!!) und den "krummen" Wert ausgeben

;)

Aber vielleicht macht das jeder Compiler anders ?! Habs auch nur mitbekommen von einem Freund an der FH *gggg*

gruß gugel

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Cool-Matthias :D

Hast recht !! (*mirpeinlichis*)

Habs grad auch mit dem VC-Compiler getestet. Der legt bei einem Feld den Speicher gleich an. Aber zu meiner Rettung muss ich sagen, daß es stimmt mit char* pPointer.

Da legt er nix an, egal wieviel Deklarationen man macht, ausse meine RAM-Anzeige stimmt nicht *ggg*

gruß gugel

Link zu diesem Kommentar
Auf anderen Seiten teilen

Da ist sehr wohl ein Unterschied:

char a[5] legt die Variable auf dem Stack an der vom System aus relativ klein ist. Beim verlassen der Routine wird einfach der Stack wieder aufgelöst und der Stackpointer auf die letzte Position des aufrufenden Programms zurückgesetzt. Geht ruckzuck!

new char[5] legt die Variable auf dem Heap an, der so groß ist wie der physikalische und virtuelle Speicher. Deshalb muß diese Variable explizit "aufgeräumt" werden.

Ausnahme:

Deklarationen in der H:

Diese werden sofort beim laden des Programms reserviert-> beim Hunk-Loader (jo wos is´n des?) als BSS-Hunk (nur eine Zahl die klarstellt wieviel Speicher für Variablen beim Laden des Programms reserviert werden müssen).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Noch als Anmerkung:

Initialisierte Variablen werden im Data-Hunk abgelegt!

Aber außer mir hat sich bestimmt kein Schwein jemals mit Hunk-Loading befaßt. Ich habe mal einen selber programmiert für einen Cruncher - damit das Programm danach im Speicher ausführbar gemacht werden konnte (korrigieren der Adressen, initialisieren der Data-Hunks, reservieren der BSS-Hunks).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Original erstellt von Crush1:

<STRONG>Es ist kein Unterschied zwischen einem Array und einem Zeiger außer...</STRONG>

Nanana, jetzt sind wir aber erstmal alle bitte ganz andaechtig, lenken nicht mit new und und anderen Feinheiten vom Wesentlichen ab und lauschen den weisen Worten der FAQ, welche da lauten:

2.2: Aber ich habe gehört daß char a[] das gleiche wie char *a ist.

A: Überhaupt nicht. (Diese Aussage hat etwas mit den formalen

Parametern einer Funktion zu tun. Vgl. Frage 2.4.) Arrays sind

keine Zeiger. Die Feldvereinbarung "char a[6]" fordert, daß Platz

für sechs Zeichen bereitgestellt wird, der unter dem Namen "a"

bekannt ist. Das bedeutet, daß es einen Ort mit dem Namen "a"

gibt, an dem sechs Zeichen gespeichert sein können. Die

Zeigervereinbarung "char *p" dagegen fordert Platz für einen

Zeiger an. Der Zeiger trägt den Namen "p" und er kann auf jedes

Zeichen (oder jedes zusammenhängende Array von Zeichen) irgendwo

im Speicher zeigen.

Wie so häufig ist ein Bild tausend Worte wert. Die Anweisungen

char a[] = "hello";

char *p = "world";

würden zu Datenstrukturen führen, die auf folgende Weise

dargestellt werden können:

+---+---+---+---+---+---+

a: | h | e | l | l | o |\0 |

+---+---+---+---+---+---+

+-----+ +---+---+---+---+---+---+

p: | *======> | w | o | r | l | d |\0 |

+-----+ +---+---+---+---+---+---+

Es ist wichtig zu begreifen, daß ein Bezug wie x[3] zu

unterschiedlichem Maschinencode führt, je nach dem, ob x

ein Array oder ein Zeiger ist. Wenn man den obigen

Quelltext heranzieht, wird ein Comiler für den Ausdruck

a[3] Maschinencode ausgeben, der an der Speicherpostition "a"

beginnt, von dort drei Schritte weitergeht und das Zeichen an

der so gefundene Speicherposition ließt. Wenn der Compiler

auf den Ausdruck p[3] trifft, erzeugt er Maschinencode der an

der Speicherposition "p" beginnt, den Zeiger holt der dort

liegt, zu diesem Zeiger 3 dazuzählt und zum Schluß das

Zeichen holt, auf das dieser Zeiger zeigt. In dem obigen

Beispiel sind zufällig sowohl a[3] als auch p[3] das Zeichen

'l', aber der Compiler kommt auf verschieden Wegen zu diesem

Zeichen. (Siehe auch 17.19 und 17.20)

2.3: Was ist dann mit der "Äquivalenz von Zeigern und Arrays" in C

gemeint?

A: Ein großer Teil der Verwirrung, die Zeiger in C umgibt, kann

auf ein falsches Verständnis dieser Aussage zurückgeführt

werden. Wenn gesagt wird, daß Arrays und Zeiger "äquivalent"

sind, bedeutet das nicht, daß sie identisch oder austauschbar

seien.

"Äquivalenz" bezieht sich auf die folgende wichtige Definition:

Ein Lvalue [vgl. Frage 2.5] vom Typ Array aus T, der in

einem Ausdruck verwendet wird, verfällt (mit drei

Ausnahmen) zu einem Zeiger auf sein erstes Element.

Der Typ des Zeigers, der sich so ergibt, ist Zeiger auf T.

(Die Ausnahmen hiervon sind ein Array, das als Operand des sizeof

oder des & Operators auftritt, oder das eine buchstäbliche

Zeichenkette [Anm: d.h. eine Zeichenkette in Anführungszeichen]

ist, die verwendet wird, um ein Array von Zeichen zu

initialisieren.)

Als Folge dieser Definiton gibt es keinen offensichtlichen

Unterschied im Verhalten des "Array Element Zugriffs"-Operators,

wenn er auf Arrays und Zeiger angewendet wird. In einem

Ausdruck der Form a verfällt der Verweis auf das Array a

nach der obigen Regel zu einem Zeiger und der Elementzugriff

erfolgt dann wie bei einer Zeigervariablen in dem Ausdruck p

(obwohl der tatsächliche Speicherzugriff verschieden ist, wie

in Frage 2.2. erklärt wird). In beiden Fällen ist der

Ausdruck x, wobei x entweder ein Array oder ein Zeiger ist),

definitionsgemäß identisch mit *((x)+(i)).

Literatur: K&R I Sec. 5.3 pp. 93-6; K&R II Sec. 5.3 p. 99; H&S

Sec. 5.4.1 p. 93; ANSI Sec. 3.2.2.1, Sec. 3.3.2.1, Sec. 3.3.6

Uli

Link zu diesem Kommentar
Auf anderen Seiten teilen

So, um jetzt mal, nachdem grosse Umwege gemacht haben, Grundsatzentscheidungen und kryptische FAQs gelesen haben :D (Nichts für Ungut EisenUli ;) ), zum wesentlichen zurückzukommen.

Ich fand die 4. Antwort der zweiten Frage logisch richtig:

1. Laut FAQ :P rerserviert der Zeiger den Platz für eine Adresse.

2. Danach kann der Zeiger auf die Adresse eines Zeichens zeigen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ist ja klar, daß ein Zeiger kein Array ist ich habe ja ein paar Eigentschaften ausgeschlossen. Aber dann erklärt mir mal das hier:

char ax[]="array";

-> character Array ax, im Memory block betrachtet ergibt sich folgendes bild:

a r r a y /0

61 72 72 61 79 00

char*px="pointer";

-> pointer auf einen character String bei px steht im Speicher:

EC 93 42 00 = Adresse 004293ec ab welcher der String "array" steht.

Bis jetzt klar, aber wieso muß ich wenn das Array als Adresse verwendet werden soll nicht referenzieren?

Der Beweis:

char variable='a'; // normale Variable

px=ax; // Zuweisung des Arrays geht so

px=&ax[0]; // verlangt den Offset also ist ax ähnlich wie ein Zeiger!!!

*px=ax[0]; // Genauso beim kopieren der Inhalte

px=&variable; // Die Variable muß referenziert werden damit alles klappt

char*py=&ax[0]; // Aber warum muß bei Definition und Deklaration auch referenziert werden?

Mir ist es jetzt schon klar, was wann warum verwendet wird, aber rein von der Logik her paßt da irgendwas nicht. Der Offset beim Array muß beim Kopieren verwendet werden, aber beim Zuweisen der Adresse an einen Pointer nicht, und wenn man referenzieren möchte benötigt man den offset aber der *-operator beim Pointer wird verwendet.

nochmal:

px=ax;

px=&ax[0];

macht dasselbe (Adresse kopieren in Pointer)

also sollte das hier auch dasselbe machen:

*px=&ax;

*px=ax[0]; // klappt aber nicht, weil wohl [0] referenziert auch wenn kein & davor steht was bedeutet, daß ax ein Pointer sein muß, der nur nicht im Debugger angezeigt wird, weil man ja ein Array nicht verschieben darf!

Also meiner Meinung nach ist ein Array ein Pointer und es wird entweder nur vom Compiler und Debugger verboten auf diesen Array-Pointer zuzugreifen oder es ist das nicht so (was nach dem Assembler-code ja so sein sollte) und man hat wohl einen Design-Fehler in C++ begangen den man bis heute noch nicht ausgebügelt hat!

Oder ich bin einfach nur saudoof!

Bitte um Stellungnahme ohne Zuhilfenahme von sog. "Fachliteratur" die eh nur zitiert worauf im Register als Quelle verwiesen wird.

Ich weiß ja, daß ich nerve, aber ich hab mir C++ nicht ausgedacht und dachte beim Lernen, daß ich wohl nichts kapiert habe weil nicht alles so funktionierte, wie es in der Theorie sein sollte.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...