const bei mehrdimensionalen Arrays
-
Gegeben sei der Integer i(int i; ),
sowie der Zeiger ptr auf i(int* ptr = &i; )
und der Zeiger ptr0 auf ptr(int** ptr0 = &ptr).Ich will mit ptr0 arbeiten, aber er darf i nicht veraendern koennen.
Also hab ich ptr0 als const deklariert.
Wie kann ich i vor ptr0 schuetzen? Bzw. etwas allgemeiner formuliert: Wie kann ich bei mehrdimensionalen Arrays solche Referenten vor Schreibzugriff aus Ebenen, die hoeher als unmittelbar ueber dem Referenten liegen schuetzen?thx in advance
-
Das ist im Allgemeinen der Unterschied zwischen "const int *i" und "int *const i"
Siehe auch: http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.5
-
*nochmalDrueberNachdenk*
-
Raptor schrieb:
Lies nochmal genau
Dito
Raptor schrieb:
Wenn ich ptr0 als int ** const deklariere loest das mein Problem nicht.
Jo, weiß ich, weil "int **const" ein konstanter Pointer auf einen Pointer auf einen int ist. Was du willst ist aber ein Pointer auf einen Pointer auf einen konstanten int, und das ist "const int **".
Folgender Bleistift:#include <iostream> int main(int argc, char **argv) { int i = 42; int *pi = &i; const int *const *ppi = π **ppi = 23; std::cout << **ppi; return 0; }
Kompostiert:
thomas@Majestix:~/Source/temp$ g++ main.c++ -Wall main.c++: In function »int main(int, char**)«: main.c++:10: Fehler: assignment of read-only location thomas@Majestix:~/Source/temp$
Es ist nicht nur eine Warnung, es ist ein Fehler, dem **ppi etwas zuzuweisen.
Das funktioniert auch (oder besser: funktioniert auch nicht *g*), wenn ppi ein "const int **" wäre. Allerdings gäbe es dann in Zeile 8 einen Fehler, weil ein "type **" nicht auf einen "const type **" gecastet werden kann. Stattdessen kann man aber einen "type *" auf "const type *" casten (merke: erst der Doppelpointer geht nicht), weshalb ppi vom Typ "const int *const *" ist. Das Resultat liest sich für den Programmierer wie: "Ein Pointer auf einen konstanten Pointer auf ienen konstanten int". Damit sorgt die Type Safety dafür, daß i tatsächlich nicht verändert werden kann, auch nicht durch Dereferenzieren von ppi.Edit: Merke: Pointer-Syntax in C++ ist ziemlich genau und ziemlich einfach, man muss es nur einmal verstanden haben
Edit Reloaded:
Die ganze "const const"-Problematik kannst du umgehen, indem (bezogen auf mein Beispiel) pi ein "const int *" ist, dann darf auch ppi "nur" ein "const int **" sein. Das illegale hier ist nämlich nur die Zuweisung, nicht die Art der Pointer an sich. Aber ich weiß nicht, ob du auch einen "const int *" gebrauchen kannst, das kommt auf deinen konkreten Code an.
-
Ich habs verstanden
Ich wollte grade damit kontern, wie man denn dann den "Mittelteil" schuetzen kann, weil ja z.B. das const in int const**** und int**** const nur die beiden Enden des Baumes, den die ganzen Pointer bilden schuetzt.
Allerdings kann man das folgendermassen machen:#include <iostream> using namespace std; int main() { int i(42); int * pi = &i; int** ppi = π //So wirds gemacht :) : const int* const * const* const pppi = &ppi; ***pppi = 24; //ERROR **pppi = NULL; //ERROR *pppi = NULL; //ERROR pppi = NULL; //ERROR cout << i << endl; }
Und die Fehlermeldung ist diese hier:
UniX:~/test$ g++ consttest.cpp consttest.cpp: In function 'int main()': consttest.cpp:13: error: assignment of read-only location consttest.cpp:14: error: assignment of read-only location consttest.cpp:15: error: assignment of read-only location consttest.cpp:16: error: assignment of read-only variable 'pppi' UniX:~/test$
Der Schluessel ist es wirklich von rechts nach links zu lesen.
Vielen Dank!
-
Raptor schrieb:
Der Schluessel ist es wirklich von rechts nach links zu lesen.
Jupp, weil die type modifiers in C selbst eine right-to-left associativity haben. Genauso wie der assignment operator (=). Deswegen geht auch
int i, j, k, l, m; i = j = k = l = m = 42;
Wenn du das von links nach rechts liest, kommst du auf keinen grünen Zweig, deswegen geht das Konstrukt in vielen anderen Sprachen auch nicht.
In C kannst du Typen nahezu beliebig genau deklarieren und kriegst (fast) immer genau das Ergebnis, das du geschrieben hast, egal was du erwartest