Arrayfrage
-
net schrieb:
deshalb kannste ja in deinem beispiel die const-referenz indirekt verändern.
...aber das versuch mal mit WERTWorauf willst du hinaus?
Der einzige Unterschied zwischen
#define DEFINE 10
und
int const CONST=10;ist der, dass man von DEFINE nicht die adresse nehmen kann, von CONST schon. Sonst gibt es aber keinen Unterschied.
Mit der nebensächlichen Ausnahme, dass DEFINE jedesmal ein 'anderer' Wert ist, der nur zufällig immer gleich ist und CONST immer das selbe. Ein Compiler macht aus beiden aber den selben Code (es sei denn, du nimmst die Adresse von CONST, dann könnte der Code uU etwas unterschiedlich aussehen).
-
Shade Of Mine schrieb:
Der einzige Unterschied zwischen
...dass man von DEFINE nicht die adresse nehmen kann, von CONST schon. Sonst gibt es aber keinen Unterschied.das ist ja der haken an der sache. alles was 'ne adresse hat kann man mit irgendwelchen bösen tricks zur laufzeit verändern (es sei denn, es befindet sich im ROM).
Shade Of Mine schrieb:
Ein Compiler macht aus beiden aber den selben Code (es sei denn, du nimmst die Adresse von CONST, dann könnte der Code uU etwas unterschiedlich aussehen).
das stimmt schon, aber da frag ich dich warum man von einer konstanten die adresse holen kann. es ist doch sinnlos und provoziert fehler. wieso erlaubt ein c++ compiler sowas?
-
net schrieb:
das ist ja der haken an der sache. alles was 'ne adresse hat kann man mit irgendwelchen bösen tricks zur laufzeit verändern (es sei denn, es befindet sich im ROM).
int const PI=3; int* p=(int*)Π *p=4;
schmiert bei mir ab.
const sollte nunmal in einem const-data Bereich liegen.
das stimmt schon, aber da frag ich dich warum man von einer konstanten die adresse holen kann. es ist doch sinnlos und provoziert fehler. wieso erlaubt ein c++ compiler sowas?
Ganz einfach: weil man eine Übergabe by reference ermöglichen muss. Eine konstante soll ja nicht magisch sein. Und wenn eine Funktion (aus welchen Gründen auch immer (zB wegen templates)) einen T const* erwartet, dann soll man ihr ein
int const pi=3;
foo(&pi);
geben können.Fände ich doof, wenn das nicht ginge.
-
net schrieb:
Shade Of Mine schrieb:
Der einzige Unterschied zwischen
...dass man von DEFINE nicht die adresse nehmen kann, von CONST schon. Sonst gibt es aber keinen Unterschied.das ist ja der haken an der sache. alles was 'ne adresse hat kann man mit irgendwelchen bösen tricks zur laufzeit verändern (es sei denn, es befindet sich im ROM).
Brauchst du dazu wirklich einen Kommentar?
net schrieb:
Shade Of Mine schrieb:
Ein Compiler macht aus beiden aber den selben Code (es sei denn, du nimmst die Adresse von CONST, dann könnte der Code uU etwas unterschiedlich aussehen).
das stimmt schon, aber da frag ich dich warum man von einer konstanten die adresse holen kann. es ist doch sinnlos und provoziert fehler. wieso erlaubt ein c++ compiler sowas?
Naja, wirklich sinnlos ist es wohl eher nicht, oder? Insbesondere wenn du nicht zwischen PODs und Objekten unterscheiden willst.
Und so direkt provoziert würde ich deinen const_cast nicht nennen; auch darüber hinaus fallen mir spontan keine Situationen ein wo const einen Fehler 'provozieren' könnte - eher andersrum.
-
net schrieb:
const int x = 10; int *p = (int*)&x; // huch? *p = 11; // undefined? printf ("%d %d\n", x, *p); // überraschung?
Ne keine Überraschung x bleibt 10 und jetzt?!?
-
net schrieb:
und 'nicht gefunden' ist wie ein 'strlen()'
Nein, nicht wie strlen. strlen gibt nur zufälligerweise den gleichen Wert zurück.
Ynnus schrieb:
Wieso sollte ich 5 erwarten wenn es nur 4 gültige Stellen gibt?
5 ist eine logische Fortsetzung der Positionszählung, -1 nicht.
Ynnus schrieb:
Ein fester Wert für "nichts gefunden" halte ich immer noch für sinnvoller.
Kann letztendlich jeder machen wie er lustig ist. Ich halte solche einzelnen Dummy Werte in vielen Situationen für Blödsinn.
Ynnus schrieb:
Und irgendwo muss man seine Variable so wählen dass sie die negative 1 annehmen kann. Bei welchen Funktionen muss man nicht zusehen, dass die Rückgabewerte passend sind?
Eben, du passt deinen Rückgabetyp dem "Fehlerwert" an, ich nicht. Ich nehm einfach den passenden Typ für die benötigte Funktionalität.
Stell dir einfach mal eine nativere Heransgehenweise vor. Du hast ein Array und suchst nach einem Wert. Welche Parameter brauchst du? Genau, das Array selbst, die Länge und den zu suchenden Wert.
size_t suche(int* feld, size_t len, int wert)
Jetzt lässt du suchen, und erhälst als Rückgabe einen Wert dir irgendwas zwischen 0 und len-1 ist. Wurde nichts gefunden, erhälst du len. Ist für mich jedenfalls logischer als irgendwie einen unpassenden Fehlerwert herbeizuzaubern.
Ynnus schrieb:
Ich könnte jetzt bei deiner Funktion auch kein 2000-Zeichen-Array auf die letzte Ziffer prüfen und den Rückgabewert nur in eine byte Variable speichern wollen.
Dann hast du aber definitiv den falschen Rückgabetyp gewählt, denn der letzte mögliche Index (1999) passt dann auch nicht rein.
Ynnus schrieb:
Geht eben nicht, ebenso wie in meiner Funktion die Variablen signed sein müssen, und natürlich auch groß genug für die Werte.
Schon klar. Nur sollte man sich darüber im Klaren sein, dass man sich mit einem signed Typ gleich die Hälfte des möglichen Wertebereichs nimmt. Ob man den wirklich braucht, ist dabei 'ne andere Frage.
Ynnus schrieb:
Meine Zählung beginnt bei 1. Wieso ein Array bei 0 beginnt weiß ich nicht
Weil man in C++ nunmal nicht "zählt", sondern die Indizes als Offset betrachtet. Und bis zum 1. Element ist nunmal nix. Ich würde dir deshalb empfehlen, auch mit 0 für den 1. Index zu arbeiten. Das ist in C++ gebräuchlich, nicht nur bei Arrays. Ansonsten bist du in VB vielleicht besser aufgehoben.
-
Hi,
Will auch mal wertend meinen Senf dazugeben:
zum Thema "const"-Qualifizierer:
Ich find es absolut unsinnig diesen zu vermeiden und nicht zu benutzen. Um Fehler zu vermeiden und Lesern des Codes das lesen zu vereinfachen.
Desweiteren werden const Variablen teilweise in schreibgeseschützten Datenbereichen gespeichert, so wie man es sich auch wünscht.zum Thema Rückgabewert der "Such-Funktion", falls der Suchterm nicht vorhanden ist:
Es gibt ja an sich die 2 Varianten, die eine bei der der Pointer auf die Fundstelle zurückgegeben wird, so machen es die C-Standardfunktionen und die die Position der Fundstelle im String zurückgibt.
Die Rückgabe von NULL bzw. -1 finde ich persönlich sinnvoll, da die Abfrage, simpler ist. Und die NULL ist sowieso keine gültige Position, das schränkt den Wertebereich also an sich nicht ein und wenn man meint, man müsse bei der zweiten Variante Möglichkeiten haben mit mehr als 2 GB Strings zu arbeiten, dann kann man ja unsigned int zurückgeben und falls nicht gefunden wird, -1 nach unsigned int casten, bzw. gleich 0xFFFFFFFF zurückgeben.MfG
DDR-RAM
-
finix schrieb:
Und so direkt provoziert würde ich deinen const_cast nicht nennen; auch darüber hinaus fallen mir spontan keine Situationen ein wo const einen Fehler 'provozieren' könnte - eher andersrum.
haste ja gesehen, mein code mit dem pointer und der von shady mit der referenz. zugegeben, das sind willkürliche beispiele mit absichtlichem wegcasten von 'const'. aber immerhin, ich find's bedenklich was man mit 'const' für'n quatsch machen kann
dali schrieb:
net schrieb:
const int x = 10; int *p = (int*)&x; // huch? *p = 11; // undefined? printf ("%d %d\n", x, *p); // überraschung?
Ne keine Überraschung x bleibt 10 und jetzt?!?
dein compiler macht das so. und was macht ein anderer? und was ist mit der 11? wo wird die gespeichert?
DDR-RAM schrieb:
Hi,
Desweiteren werden const Variablen teilweise in schreibgeseschützten Datenbereichen gespeichert, so wie man es sich auch wünscht.nicht immer. ich kenne zum beispiel einen c-compiler der speichert const-sachen trotzdem im ram. der meckert dann zwar, wenn man im code schreibend drauf zugreifen will, aber mit nem 'int* p =(int*)adresse' kannste das trotzdem umgehen. wenn man den dazu bewegen will, was in's rom zu tun, geht das nur mit 'nem #pragma.
btw: schreibt der c++ oder c-standard eigentlich vor, dass const-objekte physikalisch read-only gespeichert werden müssen?
-
net schrieb:
DDR-RAM schrieb:
Hi,
Desweiteren werden const Variablen teilweise in schreibgeseschützten Datenbereichen gespeichert, so wie man es sich auch wünscht.nicht immer. ich kenne zum beispiel einen c-compiler der speichert const-sachen trotzdem im ram. der meckert dann zwar, wenn man im code schreibend drauf zugreifen will, aber mit nem 'int* p =(int*)adresse' kannste das trotzdem umgehen. wenn man den dazu bewegen will, was in's rom zu tun, geht das nur mit 'nem #pragma.
Also, ich habs getestet mitm VC++ 2003 und ne globale constante Variable, die ich derefenziert habe, war in einem schreibgeschützten Speicherbereich und eine lokale befand sich auf dem Stack, also nicht schreibgeschützt.
Konstante Arrays wird er wahrscheinlich auch nem schreibgeschützten Speicherbereich aufheben, egal ob global oder lokal, aber ích hab es nicht getestet, da ich normalerweise davon ausgehe, das const = const ist und const bei mir nicht weggecastet wirdbtw: schreibt der c++ oder c-standard eigentlich vor, dass const-objekte physikalisch read-only gespeichert werden müssen?
Weiß ich nicht.
MfG
DDR-RAM
-
Weil man in C++ nunmal nicht "zählt", sondern die Indizes als Offset betrachtet. Und bis zum 1. Element ist nunmal nix. Ich würde dir deshalb empfehlen, auch mit 0 für den 1. Index zu arbeiten. Das ist in C++ gebräuchlich, nicht nur bei Arrays. Ansonsten bist du in VB vielleicht besser aufgehoben.
Nun denn, strlen() zählt wohl, wie sollte es auch anders gehen? Ist vielleicht eine C-Funktion, das nimmt sich aber wohl kaum was. Meine Funktion soll eben nicht den Offset bzw. den Index des Arrays wiedergeben sondern die Stell angeben an der sich das Zeichen befindet, beginnent bei 1. Und ob oder ob nicht ist doch wohl völlig wurscht und alles eine Auslegungssache des Programmierers. Da muss man jetzt nicht einen Elefanten aus einer Mücke machen und obendrein von VB rum erählen denn damit hab ich überhaupt nichts am Hut, tut auch nichts zur Sache hier. Es ist doch so egal ob ich nun zum Rückgabewert noch 255 hinzu addiere und die später eben wieder abziehen muss. Die Strings meiner Funktion fangen eben bei 1 an, deine bei 0, spielt keine Rolle.
Und wenn man weiß, dass die Funktion bei 1 zu zählen beginnt, dann kann man entsprechend damit weiterarbeiten. Bei dir, wenn man die Postion "gezählt" (wie du es nennst) haben wollte müsste man nach Erhalten des Rückgabewertes auch noch +1 rechnen. Ist eine Frage was man damit machen will. Und wenn man den Index sucht, die Funktion aber die Stelle "gezählt" herausgibt, dann zieht man eben 1 ab. Ist wohl nicht das Problem. Andererseits muss dann dafür keine 1 mehr dazu zählen wenn man die Stellen "gezählt" haben will.
-
Ynnus schrieb:
Nun denn, strlen() zählt wohl
Schon, nur liefert strlen eine Grössenangabe, keine Position. Ich glaube, dir ist nicht ganz klar, was der Unterschied zwischen Offset und Grösse ist. Schau mal bei Wiki nach. Oder um's kurz zu machen, ein Offset gibt den Abstand "zu etwas" an. Kann also durchaus auch negativ sein. Eine Größe hingegen definiert die Quantität "von etwas". Ist also mehr oder weniger ein Betrag, kann deshalb auch nicht negativ sein. So ist zumindest das grundlegende Verständnis in der Informatik. Das das in anderen Bereichen durchaus anders sein kann, ist schon klar.
Ynnus schrieb:
Meine Funktion soll eben nicht den Offset bzw. den Index des Arrays wiedergeben sondern die Stell angeben an der sich das Zeichen befindet
Genau das ist aber ein Offset, nämlich jener vom Beginn des Arrays ausgehend. Was anderes ist es, wenn du den Rückgabewert anders definierst. Du könntest zB sagen, die Funktion liefert die Anzahl der Zeichen, die bis zur Fundstelle durchlaufen wurden. Dann hast du eine Grössenangabe. Nur am Ergebnis ändert das nichts. Schau dir mal folgendes Beispiel an:
"haxor"
Nun suchst du nach 'x'. Wieviele Zeichen musst du durchlaufen (und verwerfen) bis du beim 'x' bist? Genau, 2. Und an welcher Position befindet sich 'x' (ausgehend davon, dass das erste Zeichen Position 0 ist)? Genau, auch 2. Was hast du nun beim "zählen" anders gemacht? Nichts! Das funktioniert aber halt nur, wenn du die Positionen jedes einzelnen Zeichens als Offset vom Ursprung 0 betrachtest.
Ynnus schrieb:
und obendrein von VB rum erählen denn damit hab ich überhaupt nichts am Hut, tut auch nichts zur Sache hier
Hast du den Smiley bemerkt? Falls nicht, dann sollte ich vielleicht nochmal explizit erwähnen, dass das nicht ernst gemeint war. Die Sache an VB ist nur, dass dort alle Indizes per default bei 1 beginnen.
Ynnus schrieb:
Es ist doch so egal ob ich nun zum Rückgabewert noch 255 hinzu addiere und die später eben wieder abziehen muss.
Keine Ahnung auf was du damit anspielen willst, aber wenn's dir egal ist, dann soll's mir auch egal sein.
Ynnus schrieb:
Die Strings meiner Funktion fangen eben bei 1 an, deine bei 0, spielt keine Rolle.
Solange ein Benutzer dieser Funktion weiss, dass Rückgabewert 1 das erste Zeichen meint, ist's egal. In C/C++ aber eben unüblich.
Ynnus schrieb:
Bei dir, wenn man die Postion "gezählt" (wie du es nennst) haben wollte müsste man nach Erhalten des Rückgabewertes auch noch +1 rechnen.
Wüsste nicht, warum man das tun sollte.
Ynnus schrieb:
Ist eine Frage was man damit machen will.
Sicher, wenn du Position + 1 brauchst, dann musst du halt 1 dazurechnen.
-
net schrieb:
aber immerhin, ich find's bedenklich was man mit 'const' für'n quatsch machen kann
Dann programmier in Java.
In C++ darf der Programmierer alles tun was er will. Und wenn er sich in den Fuß schießen will, dann soll er sich in den Fuß schießen.Ich habe exakt einmal const_cast verwendet. Mal von rumspielen abgesehen. Es hat also sinn dass es das gibt, weil ich sonst in dieser einen Situation blöd dagestanden hätte. Das ist das schöne an C++: man kann alles machen was man will.
dein compiler macht das so. und was macht ein anderer?
irrelevant: undefiniertes Verhalten.
und nicht nur theoretisch, sondern auch praktisch. Weil alle klugen Compiler const Daten in einen read-only-Bereich packen.nicht immer. ich kenne zum beispiel einen c-compiler der speichert const-sachen trotzdem im ram.
Ich kenne einen, der kann Kaffee kochen.
Du argumentierst blödsinnig. Falscher code ist falscher code. Es ist wie
int* p=0;
int& r=*p;es wird nahezu immer klappen, ist aber nicht nur dumm sondern auch blöd und falsch.
btw: schreibt der c++ oder c-standard eigentlich vor, dass const-objekte physikalisch read-only gespeichert werden müssen?
Wahrscheinlich nicht, weil er dann voraussetzen würde, dass es einen read-only Speicher gibt. Es reicht wenn er sagt: dürfen nicht geändert werden.
Das heißt dann nämlich: jedes Programm dass einen const Wert trotzdem ändert ist voll uncool.zu den Rückgabewerten:
1 für das erste Element ist blödsinn. Denn in C++ zählt man von 0 bis n-1 und nicht von 1 bis n
Wenn man nun eine Library hat, die das anders macht, muss man immer höllisch aufpassen ob man jetzt gerade bei 0 oder bei 1 zu zählen anfangen muss. das ist einfach nur doof.-1 als rückgabewert bzw. NULL bei Zeigern ist dagegen vollkommen in Ordnung, nur nicht immer machbar.
Das N als Rückgabewert dagegen geht immer und ist praktisch, bei iteratoren zB auch das einzig mögliche.
-
Shade Of Mine schrieb:
net schrieb:
aber immerhin, ich find's bedenklich was man mit 'const' für'n quatsch machen kann
Dann programmier in Java.
In C++ darf der Programmierer alles tun was er will. Und wenn er sich in den Fuß schießen will, dann soll er sich in den Fuß schießen.
Das ist das schöne an C++: man kann alles machen was man will.hey, java ist gar nicht so übel. c brauch ich für mein' low level kram, aber wenn ich's mir aussuchen könnte, würde ich nur java nehmen. es macht richtig spass damit zu programmieren
Shade Of Mine schrieb:
Du argumentierst blödsinnig. Falscher code ist falscher code. Es ist wie
int* p=0;
int& r=*p;
es wird nahezu immer klappen, ist aber nicht nur dumm sondern auch blöd und falsch.na, da schrieb doch jemand "Das ist das schöne an C++: man kann alles machen was man will" wer war das nur