Wozu immer Zeiger?
-
Hey,
ich kenne mich eigentlich relativ gut aus mit C++.. Quellcode und dessen Sinn verstehe ich eig auch meist, was mir aber noch vor den Kopf stößt, sind Zeiger.. Also nicht Zeiger an sich.. Wenn ich sie richtig verstanden habe, sollten sie einfach nur eine Adresse zu einer beliebigen Variable gespeichert haben. Werden deklariert mit dem "*"-Infix zwischen Typ, auf den gezeigt werden soll und dem Namen des Zeigers..
Ich frage mich nur, was denn der genaue Vorteil von Zeigern ist..
Klar, man kann so in einer Funktion eine überlieferte Variable sozusagen extern verändern..void verdoppeln(int * var) // oder (int &var)? Was ist da genau der Unterschied? { // var = Adresse der überlieferten Variable? // &var = Adresse des Zeigers? // *var = Die eigentliche überlieferte Variable, eben das, worauf der Zeiger zeigt? *var = *var * 2; }Wenn man diese Funktion nun z.b. folgend aufrufen würde, wird die Variable verdoppelt.. Oder?
int test = 2; verdoppeln(&test); // test = 4??Ist das so richtig?
Sonst kann ich keine Vorteile von Zeigern entdecken.. Trotzdem sehe ich sehr oft Code, wo fast gänzlich nur mit Zeigern gearbeitet wird.. Wieso? Ich sehe da nur eine Zeitverschwendung, weil man andauernd "*" und "&" vor die Variablen schreiben muss, damit auch wirklich ein Zeiger zurückgeliefert wird/auf die eigentliche Variable, und nicht den Zeiger zugegriffen wird??
---
Ich hab auch die "new"-Funktion irgendwie nicht ganz verstanden..
Der Vorteil von Zeigern soll das dynamische (also zur Laufzeit?) stattfindene Erstellen von Arrays sein..?int * array = new int[10]Ich kann doch genausogut während der Laufzeit sonst auch ein Array erstellen?
Sogar mit variabler Größe, wenn ich das auch möchte?int size; cin >> size; int[size] array;Wo ist da jetzt der Unterschied zu:
int size; cin >> size; int * array = new int[size];
-
Noobfire schrieb:
[...]
int size; cin >> size; int[size] array;Das geht eben nicht (zumindest nicht mit VS2008). Die Arrays werden ja normalerweise auf dem Stack erzeugt und der Compi muss vorher wissen wie groß das Array ist. Mit new erstellst du die Objekte auf dem Heap. So kann der Compiler die 4 Byte (x86-Kompatibel) für den Zeiger auf dem Stack reservieren. Und der Rest spielt sich zur Laufzeit ab.
-
Ui, das sind aber viele Fragen.

Der Unterschied zwischen Zeigern (int *i) und Referenzen (int& i) ist eher sprachlicher als technischer Natur. Im kompilierten Programm wird das recht gleich behandelt."Was ist der Vorteil von Zeigern?"
Einen hast du ja schon selbst genannt, man kann den Wert einer in einer anderen Funktion deklarierten Variable ändern.Parameter müssen (ohne Optimierungen) auf den Stack gepusht werden. Das kostest Zeit und Speicher. Und da wären wir auch gleich bei new. Lokale Variablen/Arrays werden auf dem Stack erstellt. Der Stack ist Speicher, der dem Programm direkt vom System zur Verfügung gestellt wird, seine Größe hängt also auch vom System ab. Windows-Programme haben z.B. eine übliche Stackgröße von 1MB. Das wird jetzt schwierig, wenn du da ein 5MB Bild Speichern willst. (Die Standardcontainer wie std::vector/std::string arbeiten übgrigens auch meist mit Speicher vom Heap, also new/delete.)
PS:
int[size] array; // <- Sieht irgendwie mehr nach D aus, als nach C++.^^ // Technisch ist das aber möglich, weshalb ich da jetzt nicht so drauf eingegangen bin.
-
Noobfire schrieb:
ich kenne mich eigentlich relativ gut aus mit C++
Nö.
Du weisst bloss noch nicht, dass du dich noch nicht gut damit auskennst
Ich kann doch genausogut während der Laufzeit sonst auch ein Array erstellen?
Sogar mit variabler Größe, wenn ich das auch möchte?Nö.
int size; cin >> size; int[size] array;1. gibt's in C++ keine "variable length arrays" (nur in C) und
2. falsche Syntax selbst für C (müssteint array[size];heissen)Wo ist da jetzt der Unterschied zu:
int size; cin >> size; int * array = new int[size];Naja das zweite funktioniert, das erste nicht

Gibt aber noch viele andere Anwendungsfälle von Zeigern.
Aber da kommst du noch drauf, wenn du programmieren lernst
-
Noobfire schrieb:
[...]Werden deklariert mit dem "*"-Infix zwischen Typ, auf den gezeigt werden soll und dem Namen des Zeigers..
* als Deklarator sowie der Dereferenzierungsoperator würde ich als "Präfix-Deklarator/Operator" bezeichnen. *x als Deklaration heisst: "x ist ein Zeuger auf". Als Ausdruck ist das dann die Dereferenzierung.
Noobfire schrieb:
Ich frage mich nur, was denn der genaue Vorteil von Zeigern ist..
Schonmal einen binären Suchbaum implementiert oder eine verkettete Liste? Viele Datenstrukturen schreien gerade zu nach Zeigern.
Noobfire schrieb:
[...] Oder?
int test = 2; verdoppeln(&test); // test = 4??Ist das so richtig?
Ja.
...
int * array = new int[10]Ich kann doch genausogut während der Laufzeit sonst auch ein Array erstellen?
Sogar mit variabler Größe, wenn ich das auch möchte?int size; cin >> size; int array[size];Wo ist da jetzt der Unterschied zu:
int size; cin >> size; int * array = new int[size];Der C++ Standard verlangt, dass bei einer Deklaration wie
int array[size];`size` eine Compile-Zeit-Konstante sein muss. Das ist bei Dir nicht gegeben. Es ist also kein legaler C++ Quellcode. Falls Du GCC verwendest, solltest Du auch die Optionen "-Wall -std=c++03 -pedantic" benutzen. Damit wird er Deine Stelle anmeckern, da nicht Standardkonform.Ist `size` also nicht zur Compile-Zeit bekannt, musst Du das Array "dynamisch" allozieren. Im Falle einer Compiler-Zeit-Konstante kannst Du beides machen. Dann wird das erste Feld im automatischen Speicher leben und das zweite im Freispeicher. Im automatischen Speicher ist die Lebenszeit durch die umschließenden geschweiften Klammern beschränkt. Das, was Du manuell im Freispeicher anlegst, bleibt da solange, bis Du es wieder entfernst bzw entfernen lässt. Man kann es sich nicht immer aussuchen, wo man seine Objekte speichert. Manchmal braucht man eben den Freispeicher, weil die Objekte lang genug am Leben bleiben müssen. Den Freispeicher zu verwenden, wenn der automatische gereicht hätte, wäre aber auch "ungeschickt".
-
Das mit den Zeigern und new sind eigentlich alles Sachen, die du nicht andauernd brauchen solltest. Wenn es dir sehr oft begegnet, dann liest du vermutlich gerade C-Quellcode oder C++ von jemandem der C++ für C mit Klassen hält.
Noobfire schrieb:
Klar, man kann so in einer Funktion eine überlieferte Variable sozusagen extern verändern..
Und das kommt dir nicht irgendwie sinnvoll vor? Das ist praktisch das was eine C++-Referenz ist, auf C-Art geschrieben. Und Referenzen hältst du doch sicher für sinnvoll, oder?
void verdoppeln(int * var) // oder (int &var)? Was ist da genau der Unterschied?Der Unterschied ist, dass das erste ein Pointer ist, das zweite eine Referenz. Referenzen haben eine bequemere Syntax als Zeiger (und ein paar Kleinigkeiten sind auch noch anders).
{ // var = Adresse der überlieferten Variable? // &var = Adresse des Zeigers? // *var = Die eigentliche überlieferte Variable, eben das, worauf der Zeiger zeigt? *var = *var * 2; }Wenn man diese Funktion nun z.b. folgend aufrufen würde, wird die Variable verdoppelt.. Oder?
int test = 2; verdoppeln(&test); // test = 4??Ist das so richtig?
Ja, alles richtig.
Ich hab auch die "new"-Funktion irgendwie nicht ganz verstanden..
Der Vorteil von Zeigern soll das dynamische (also zur Laufzeit?) stattfindene Erstellen von Arrays sein..?Ja. Und auch für das dynamische Anlegen einzelner polymorpher Objekte ist das ganz nützlich. Da du in C++ aber die Containerklassen hast, solltest du das eigentlich nur selten zu Gesicht bekommen. Dynamische Arrays werden von den Containern komplett abgedeckt und somit bleiben nur noch Polymorphie und ein paar Ausnahmefälle wo ein Objekt eine exotische Lebenszeit hat.
Ich kann doch genausogut während der Laufzeit sonst auch ein Array erstellen?
Sogar mit variabler Größe, wenn ich das auch möchte?int size; cin >> size; int[size] array;Nein, das kannst du eben nicht. Das ist in C++ nicht erlaubt. Das ist eine Erweiterung von C99, die in manchen Compilern auch für C++ umgesetzt wurde. Aber es gibt auch prominente Compiler die das nicht unterstützen (selbst C99 ist noch nicht überall angekommen, falls du mal C machst), dein Code würde mit diesen nicht funktionieren, wäre nicht portabel. Im neuen Standard wird es dies geben, aber bevor der überall unterstützt wird, wäre ich damit vorsichtig.
Zudem gibt es noch einen wichtigen Unterschied: Die variable length arrays (VLA) liegen auf dem Stack, Sachen die du mit new holst liegen auf dem Heap. Das beeinflusst in erster Linie die Lebenszeit, Stackobjekte werden automatisch abgeräumt wenn sie den Scope verlassen, Heapobjekte leben weiter. Deswegen gibt es auch die Containerklassen, die das ebenfalls automatisch machen und das new wird benutzt um Objekte mit exotischen Lebenszeiten anzulegen (wie oben schon gesagt). Zudem ist der Stack wesentlich schneller beim "Anfordern" (wenn man das so nennen kann beim Stack) von Speicher. Nachteil ist, dass der Platz oftmals sehr begrenzt ist, große Objekte müssen auf den Heap, aber dafür hat's ja die Container und du brauchst kein new.
edit: Oh, da haben aber viele vor mir geantwortet. Kein Wunder bei so vielen Fragen und so einer langen Antwort.
-
Jonas OSDever schrieb:
Das geht eben nicht (zumindest nicht mit VS2008). Die Arrays werden ja normalerweise auf dem Stack erzeugt und der Compi muss vorher wissen wie groß das Array ist. Mit new erstellst du die Objekte auf dem Heap. So kann der Compiler die 4 Byte (x86-Kompatibel) für den Zeiger auf dem Stack reservieren. Und der Rest spielt sich zur Laufzeit ab.
Der Grund warum es nicht geht, ist nicht technischer Natur, sondern weil es VS2008 einfach nicht unterstützt. Muss er auch nicht, da der C++ Standard keine VLAs kennt.
Der C Standard dagegen schon. Was auch ein gutes Indiz dafür ist, dass man es auch umsetzen kann
-
SeppJ schrieb:
[...] Im neuen Standard wird es [VLAs] geben, aber bevor der überall unterstützt wird, wäre ich damit vorsichtig.
VLAs sind nicht Bestandteil von C++2011. Das ist auch gut so.
-
krümelkacker schrieb:
SeppJ schrieb:
[...] Im neuen Standard wird es [VLAs] geben, aber bevor der überall unterstützt wird, wäre ich damit vorsichtig.
VLAs sind nicht Bestandteil von C++2011. Das ist auch gut so.
Nicht? Ich meine mich fest erinnern zu können, das mal in irgendeinem Vorschlag gelesen zu haben. Aber bei der Entwicklungszeit ist das gut möglich, dass es wieder rausgeflogen ist. Und ich stimme dir zu: Das ist besser so.
-
Der Grund warum es nicht geht, ist nicht technischer Natur, sondern weil es VS2008 einfach nicht unterstützt. Muss er auch nicht, da der C++ Standard keine VLAs kennt.
Ja, ich weiß das VLAs nicht im Standard sind. Wollt nur sichergehn falls es andere Compiler unterstützen

-
krümelkacker schrieb:
Noobfire schrieb:
[...] Oder?
int test = 2; verdoppeln(&test); // test = 4??Ist das so richtig?
Ja.
Eben nicht, weil es
// test == 4??heißen müsste. :p
-
Erstmal danke für die vielen Antworten

Jonas OSDever schrieb:
Das geht eben nicht (zumindest nicht mit VS2008). Die Arrays werden ja normalerweise auf dem Stack erzeugt und der Compi muss vorher wissen wie groß das Array ist. Mit new erstellst du die Objekte auf dem Heap. So kann der Compiler die 4 Byte (x86-Kompatibel) für den Zeiger auf dem Stack reservieren. Und der Rest spielt sich zur Laufzeit ab.
Okay, sry, bin ich jetzt irgendwie felsenfest von ausgegangen
Funktioniert das denn in Java oder Delphi? (Bin in der 11. Klasse, Gynmasium, und da haben wir mit den beiden Sprachen zu tun.. In der Freizeit beschäftige ich mich aber lieber mit C++.. Erscheint mir iwie intuitiver und weniger redundant (von der benötigten Zeichenanzahl her) zu sein.. Ständig iwelche Klassen erstellen ist iwie etwas lästig)Die Begriffe Heap und Stack sagen mir jetzt leider auch noch nicht so viel :S Also Stack = Stapelspeicher? Das hab ich mir mal bei Wikipedia angeguckt, scheint sehr simpel zu sein. (Neue Elemente werden einfach auf den Stapel "draufgepackt", man kann das oberste Element auslesen oder entfernen, das wars) Mit Heaps hatte ich schonmal in der Schule für Heapsort zu tun.. Beides sagt mir aber jetzt so in diesem Kontext recht wenig.. Wird eben iwie im RAM abgespeichert (z.b. array gibt die Adresse des ersten Elementes wieder, die darrauffolgenden Elemente haben eine linear ansteigende Adresse.. Der Abstand der Adressen hängt dabei ja von dem Typ des Arrays, also der Speichergröße eines einzelnen Elementes ab.. Char -> 1 Byte, Int32 -> 4 Byte, etc.)..? Aber das zu erklären (was jetzt genau der Heap und Stack darstellt) ist wohl etwas komplizierter, denke ich..

cooky451 schrieb:
Der Unterschied zwischen Zeigern (int *i) und Referenzen (int& i) ist eher sprachlicher als technischer Natur. Im kompilierten Programm wird das recht gleich behandelt.
Ist es denn so, dass Referenzen im Gegensatz zu Zeigern keinen Speicher belegen? (was dazu führen würde, dass &Referenz keinen Sinn hat, da diese Referenz keinen Speicher belegt -> also auch keine Adresse im Speicher hat)
cooky451 schrieb:
int[size] array; // <- Sieht irgendwie mehr nach D aus, als nach C++.^^ // Technisch ist das aber möglich, weshalb ich da jetzt nicht so drauf eingegangen bin.Sry, Arrays deklariere ich irgendwie IMMER falsch.. Also damit mein ich die Position der eckigen Klammern.. Ich denk auch immer ich müsste iwie
int array = new int[10]oder sowas machen.. Von Java her. Ist etwas doof, wenn man 3 Programmiersprachen auf einmal lernen möchte

krümelkacker schrieb:
Dann wird das erste Feld im automatischen Speicher leben und das zweite im Freispeicher. Im automatischen Speicher ist die Lebenszeit durch die umschließenden geschweiften Klammern beschränkt. Das, was Du manuell im Freispeicher anlegst, bleibt da solange, bis Du es wieder entfernst bzw entfernen lässt. Man kann es sich nicht immer aussuchen, wo man seine Objekte speichert. Manchmal braucht man eben den Freispeicher, weil die Objekte lang genug am Leben bleiben müssen. Den Freispeicher zu verwenden, wenn der automatische gereicht hätte, wäre aber auch "ungeschickt".
SeppJ schrieb:
Zudem gibt es noch einen wichtigen Unterschied: Die variable length arrays (VLA) liegen auf dem Stack, Sachen die du mit new holst liegen auf dem Heap. Das beeinflusst in erster Linie die Lebenszeit, Stackobjekte werden automatisch abgeräumt wenn sie den Scope verlassen, Heapobjekte leben weiter. Deswegen gibt es auch die Containerklassen, die das ebenfalls automatisch machen und das new wird benutzt um Objekte mit exotischen Lebenszeiten anzulegen (wie oben schon gesagt). Zudem ist der Stack wesentlich schneller beim "Anfordern" (wenn man das so nennen kann beim Stack) von Speicher. Nachteil ist, dass der Platz oftmals sehr begrenzt ist, große Objekte müssen auf den Heap, aber dafür hat's ja die Container und du brauchst kein new.
Okay, danke, das hat auch einiges erklärt

hustbaer schrieb:
Nö.
Du weisst bloss noch nicht, dass du dich noch nicht gut damit auskennst
Danke. Das nehm ich als Kompliment
Die Kentnisse, die ich habe, reichen für ein Überleben (nutze eig nur SFML) bei den Sachen, die ich so mache, aus 
SeppJ schrieb:
Noobfire schrieb:
Klar, man kann so in einer Funktion eine überlieferte Variable sozusagen extern verändern..
Und das kommt dir nicht irgendwie sinnvoll vor? Das ist praktisch das was eine C++-Referenz ist, auf C-Art geschrieben. Und Referenzen hältst du doch sicher für sinnvoll, oder?
Klar finde ich das sinnvoll, sonst hätte ichs ja wohl kaum geschrieben
Ich finde es nur (wie gesagt) etwas komisch, dass bei besagtem Quellcode ständig und fast ohne Ausnahme auf Zeiger gesetzt wird.
-
Warum ist das gut so?
Mir fällt spontan kein Grund ein, der dringend dagegen spricht.
-
@Noobfire: Wenn du über den Unterschied zwischen Referenz und Zeiger rätselst: Bis auf den Unterschied, dass Referenzen nicht 0 sein können sind sie praktisch das gleiche wie (konstante) Pointer mit ordentlich Syntaxzucker. Und dieser Syntaxzucker ist auch gut so, denn wie du selbst schreibst, nerven die dauernden * und & doch nur, wenn man mit Zeigern arbeitet.
Wie eine Referenz intern funktioniert ist nicht festgelegt, aber du darfst davon ausgehen, dass das in der Praxis die gleiche Technik wie für Pointer ist. Früher hätte ich auch mal gemutmaßt, das Referenzen besser optimiert werden können, da ein paar stärkere Annahmen über die Objekte auf die sie sich beziehen getroffen werden können, aber Compiler sind mittlerweile dermaßen gut im Optimieren von Pointeroperationen, dass ich da keine Unterschiede erwarten würde (Nachmessen macht Freude
).
-
Caligulaminus schrieb:
Warum ist das gut so?
Mir fällt spontan kein Grund ein, der dringend dagegen spricht.1. Sie lösen ein Problem, das niemand hat. In C++ gibt es vector.
2. Dafür würden sie komische Probleme bringen: Was soll zum Beispiel der Typ eines solchen Arrays sein und wann steht er fest? Auf diese Frage gibt es keine befriedigende Antwort und das in einer Sprache in der Typen dermaßen wichtig sind!
3. Und es führt Fehlerquellen in den Code ein, die man mit vector nicht hätte. Z.B.: Anforderung des Programms ändert sich, Array muss nun wirklich groß werden können? vector -> na und? VLA->Programm muss umgeschrieben werden.
4. Es macht eine Stackanalyse des Programms schwierig. Wie groß kann der Stack meines Programms maximal werden? Welche Rekursionstiefe kann ich mir erlauben? Alles nicht mehr beantwortbar.Und selbst wenn man zu den Punkten 2,3 und 4 auch Gegenargumente bringen kann, gilt immer noch 1. Und dann hätte man selbst bei den tollsten Gegenargumenten zu 2,3, und 4 immer noch ein Sprachmittel ohne Bedarf und mit potentiellen Problemen.
-
Dank für deine Zeit SeppJ,
1. Ich hatte VLA wahrscheinlich falsch interpretiert. Ich bezog mich darauf, ein Array mit einer Variablen als Größenangabe zu definieren.
int a[x]; // Wert von x ist zur Compilezeit nicht bekannt.Für Arrays mit veränderbarer Größe gibt's von mir keine Diskussion -> std::vector.
2. Steht ja fest. In meinem Beispiel: int.
3. Ich(als Compiler) würde sowas dann ja auch auf dem Heap anlegen. Alles andere wäre ja kreuzgefährlich.
4. Siehe 3.Im Prinzip läuft mein Kopfkino wohl auf sowas wie std::array hinaus (heißt das so?). Und damit wäre/ist die möglichkeit Arrays mit Variable als Größe auch überflüssig. Nur was spricht dagegen, soetwas als Sprachmittel einzuführen/zuzulassen. Wär' doch einfach einfacher.
-
@Caligulaminus: Du hast VLAs richtig interpretiert. Schon beim Gedanken an sizeof(a) aus deinem Beispiel packt mich das kalte Grauen. Und bei std::array<> muss die Größe des Arrays auch schon zur Compilezeit feststehen. Du könntest jetzt noch einen Zwischentyp entwerfen, der zwar eine feste Größe hat, aber diese erst zur Laufzeit übergeben bekommen hat, weil er im Gegensatz zu std::vector<> Speicher und evtl. etwas Laufzeit sparen könnte, da std::vector<> Speicher exponentiell allozieren muss, um logarithmische Komplexität gewährleisten zu können (was für ein Satz...). Ich halte das allerdings für nicht lohnenswert.
EDIT: Da VLAs auf dem Stack liegen, wäre das ja noch ein Zwischending. Wers unbedingt braucht, kann sich ja mit _alloca zumindest unter Linux was zusammenbasteln (oder so etwas ähnliches aka Compilermagik).@Noobfire: Wenn dich an Java und Delphi (die Sprache heißt übrigens Objekt Pascal) stört, dass man dauernd "mit Klassen rumhantieren" muss, dann hast du sie vermutlich noch nicht ganz verstanden. Und was die Intuitivität (gibt's das Wort?) angeht, würde ich lieber noch ein Weilchen abwarten. In C++ gibt es Dinge, die sind so unintuitiv, das kann man sich nur schwer vorstellen. Ich empfehle dir, ein gutes Buch zu lesen (auch über Java/Delphi/...), damit du die Zusammenhänge verstehst. In der Schule lernt man das Programmieren meistens sowieso nicht vernünftig (Erst klickibunti, und dann, wenn die Grundlagen fehlen, ist die Oberstufe zu Ende).
-
Caligulaminus schrieb:
1. Ich hatte VLA wahrscheinlich falsch interpretiert. Ich bezog mich darauf, ein Array mit einer Variablen als Größenangabe zu definieren.
Genau das sind VLAs. vector kann eben noch mehr.
2. Steht ja fest. In meinem Beispiel: int.
Das ist die schlechtestmögliche Antwort auf die Frage nach dem Typen. Welchen Typ hat denn deiner Meinung nach int[3]? Tipp: Es ist nicht int.

3. Ich(als Compiler) würde sowas dann ja auch auf dem Heap anlegen. Alles andere wäre ja kreuzgefährlich.
Wo ist dann der Sinn dieses Sprachmittels? Auf dem Heap habe ich vector und new.
4. Siehe 3.
Siehe 3.
Im Prinzip läuft mein Kopfkino wohl auf sowas wie std::array hinaus (heißt das so?).
std::array ist ein statisches Array dessen Größe zur Compilezeit feststehen muss. Es hat im Gegensatz zum normalen Array aber die von allen anderen Datentypen gewohnte Semantik.
Nur was spricht dagegen, soetwas als Sprachmittel einzuführen/zuzulassen. Wär' doch einfach einfacher.
Was wäre damit einfacher als mit vector? Siehe meine Einwände zu deinen Erwiederungen. Du sparst dir bloß 7 Zeichen (oder 12 mit std::) bei der Deklaration.
-
Hallo Sepp,
dann gab es wohl zwei Mißverständnisse.
Welchen Typ hat denn deiner Meinung nach int[3]? Tipp: Es ist nicht int.
Welchen sollte es schon haben?
int*, klassisches Array halt.Und daß std::arrays Größe zur Compilezeit feststehen muß war mir auch nicht bewußt.
Nun, wenn das die Einwände sind, sehe ich immer noch keinen dringenden Grund, solch ein Konstrukt auszuschließen(auch wenn der Vorteil eher minimal ist). In anderen Sprachen geht's doch auch.
Das Einzige 'Problem' wäre dann für mich noch die sizeof-Frage. Aber da finde ich den aktuellen Zustand in dem
sizeof alokal die Arraygröße(x sizeof typ) hergibt, in einer anderen Funktion dann aber nur die Zeigergröße verwirrender, als wenn man C-Arrays konsequent als Zeiger behandeln würde. Mit einer kleinen Änderund des Verhaltens von sizeof wäre dann ja alles klar.
Vielleicht sollte ich mich mal an die ISO wenden
.P.S. Ich habe überhaupt kein Problem mit dem Status quo, aber Neugier ist eine menschliche Eigenschaft, die es meiner Ansicht nach zu pflegen gilt.
Wie immer, Dank für Deine Zeit.
-
@Caligulaminus: Nein, ein int[3] hat den Typ int[3] - es ist aber in einen Zeiger konvertierbar. Diese Diskussion gab es schon öfters - warum ein Array kein Zeiger ist. Und wenn du sizeof() verändern willst, kannst du in C++ auch gleich ein neues Modulsystem einbauen. VLAs sind Dinge, die nur in 0.001% der Fälle nützlich wären - aus Effizienzgründen. Und die Gegenargumente - Inkonsistenz, Verwirrung, zusätzliche Arbeit für Kommitee/Compilerhersteller, noch mehr Anfängerverwirrung - sind viel gewichtiger.
Wer wirklich genau diese Mischung aus Effizienz und Dynamik braucht, soll sich an Inline-Assembler den Magen verderben.