Arrayfrage
-
groovemaster schrieb:
Ynnus schrieb:
Ich empfehle da kein unsigned integer sondern signed integer.
Auch nicht besser.
Ynnus schrieb:
Denn wenn er den Buchstaben nicht findet, was soll er zurückgeben?
Wie wärs mit 5? Oder anders formuliert, maximaler Index + 1. Auch gleichbedeutend mit strlen(array).
Es gibt mehr (und imo bessere) Alternativen als diesen unsinnigen -1 Dummy.Ich wüsste jetzt nicht, wo es besser ist, eine 5 anstatt -1 auszugeben. (Die Unsinnigkeit musst du mir da erst erklären).
Dann muss man erstmal abfragen, ob das Array 5 Stellen hat. Ist dies nicht so, kann man erst dann schlussfolgern, dass das Zeichen nicht gefunden wurde. Außerdem ist dann der Rückgabewert bei "nicht gefunden" immer unterschiedlich, abhängig von der Arraylänge. Wo ist das bitte sinnvoller als eine -1. Da sieht man wenigstens direkt, dass der char nicht gefunden wurde.
Außerdem ist signed oder unsigned in dem Fall wohl praktisch gesehen wurscht, wer hat schon ein > 2 GB char-array? Da braucht man nicht noch das zusätzliche letzte Bit für noch größere Index-Werte.
Aber es muss tatsächlich nicht -1 sein. Beim späteren drüber Nachdenken ist mir in den Sinn gekommen, dass man auch 0 nehmen könnte. Denn an der Stelle 0 kann es auch nicht sein, in meiner Funktion beginnt das Zählen bei 1. (Also ist das gefundene Zeichen frühestens bei 1, also erstes Zeichen.) Dadurch könnte man auch die 0 als nicht gefunden interpretieren.
-
Deine Pointer-Methode gibt nicht korrekte Werte aus:
#include <iostream.h> char array[6] = "Hallo"; size_t MyFind(const char* s, char c) { const char* tmp = s; while (*s != '\0') { if (*s == c) break; ++s; } return tmp - s; } int main() { cout<<MyFind(array, 'a'); cin.get(); return 0; }
Dabei erhalte ich 2^32 als Ausgabe.
-
Ynnus schrieb:
@groovemaster:
Deine Pointer-Methode gibt nicht korrekte Werte aus:ersetz'
return tmp - s;
durch
return *s ? s - tmp : -1;
und statt 'size_t' als rückgabewert 'int'
-
net schrieb:
ansichtssache
Sicherlich, wie vieles.
net schrieb:
deine funktionen geben 0 zurück wenn nix gefunden wurde
Nein, tun sie nicht.
Ynnus schrieb:
Ich wüsste jetzt nicht, wo es besser ist, eine 5 anstatt -1 auszugeben.
Du gibst explizit -1 zurück, ich nicht. Damit machst du dich abhängig vom Rückgabetyp, bzw dessen Wertebereich.
Ynnus schrieb:
Dann muss man erstmal abfragen, ob das Array 5 Stellen hat.
Eigentlich nicht. Wenn du jedoch meinst, dass man die Länge des Strings kennen muss, dann hast du Recht. Und ich geb auch zu, dass
size_t pos = MyFind(array, 'a'); if (pos == strlen(array)) // nichts gefunden - bla
nicht sonderlich toll ist. Wir sind aber auch in C++, da nimmt man für Strings Container und kein strlen.
Ynnus schrieb:
Außerdem ist signed oder unsigned in dem Fall wohl praktisch gesehen wurscht
Praktisch vielleicht, logisch nicht. Wenn ich eine Funktion habe, die mir eine Position in einem Array sucht, warum sollte ich einen negativen Wert erwarten?
Ynnus schrieb:
Beim späteren drüber Nachdenken ist mir in den Sinn gekommen, dass man auch 0 nehmen könnte.
Nein, 0 ist unpraktisch. net hat zwar falsch interpretiert, aber zumindest teilweise richtig analysiert. Die Zählung beginnt bei 0, das ist also eine gültige Position. Wenn du wirklich bei 1 anfangen willst, ist das letztendlich auch nichts anderes als die -1 Variante. Du hast halt nur zum Rückgabewert 1 hinzuaddiert.
Ynnus schrieb:
Deine Pointer-Methode gibt nicht korrekte Werte aus
Sry, passiert halt. Die return Anweisung muss natürlich
return s - tmp;
lauten.
-
groovemaster schrieb:
Die return Anweisung muss natürlich
return s - tmp;
lauten.
und 'nicht gefunden' ist wie ein 'strlen()'
find ich doof
-
Praktisch vielleicht, logisch nicht. Wenn ich eine Funktion habe, die mir eine Position in einem Array sucht, warum sollte ich einen negativen Wert erwarten?
Wieso sollte ich 5 erwarten wenn es nur 4 gültige Stellen gibt? Da bleibt die Logik auch auf der Strecke. Ein fester Wert für "nichts gefunden" halte ich immer noch für sinnvoller.
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? 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. Geht eben nicht, ebenso wie in meiner Funktion die Variablen signed sein müssen, und natürlich auch groß genug für die Werte.
Ich schätze das ist dann die persönliche Marke der Programmierer. Du bevorzugst eben deine Methode, ich die meine.Nein, 0 ist unpraktisch. net hat zwar falsch interpretiert, aber zumindest teilweise richtig analysiert. Die Zählung beginnt bei 0, das ist also eine gültige Position. Wenn du wirklich bei 1 anfangen willst, ist das letztendlich auch nichts anderes als die -1 Variante. Du hast halt nur zum Rückgabewert 1 hinzuaddiert.
Meine Zählung beginnt bei 1. Wieso ein Array bei 0 beginnt weiß ich nicht, aber wenn ich vor mir 10 Äpfel sehe, dann zähle ich nicht von 0 - 9 sondern von 1 - 10. Demnach geb ich als Rückgabe auch aus, dass das erste Zeichen sich an der ersten Stelle (also 1) und nicht bei 0 befindet. Immerhin ist es das ERSTE Zeichen und nicht das NULLTE Zeichen. Daraus resultiert, dass 0 als nicht gefunden durchaus interpretiert werden könnte. Wie oben reine persönliche Einstufung des Programmierers und ist demnach zu Handhaben wie man will. Man sollte es dann eben nur ordentlich dokumentieren für diejenigen die die Funktionen verwenden wollen. Und wenn man vorher sagt, dass die Funktion eine signed int verlangt und -1 als eindeutige Identifikation, dass nichts gefunden wurde, dann kann man das durchaus so nutzen.
-
net schrieb:
finix schrieb:
Was hast du gegen const?
'const' ist eine illusion
const int x = 10; int *p = (int*)&x; // huch? *p = 11; // undefined? printf ("%d %d\n", x, *p); // überraschung?
Würdest du auch
const int x = 10; int *p = const_cast<int*>(&x); // huch? *p = 11; // undefined? printf ("%d %d\n", x, *p); // überraschung?
schreiben?
-
finix schrieb:
Würdest du auch
const int x = 10; int *p = const_cast<int*>(&x); // huch? *p = 11; // undefined? printf ("%d %d\n", x, *p); // überraschung?
schreiben?
nee, ich mach das besser so:
#define NUR_DAS_IST_WIRKLICH_CONST 10 int *p = (int*)&NUR_DAS_IST_WIRKLICH_CONST; // error
da gibt's kein vertun, das kann man nicht weg casten
-
net schrieb:
da gibt's kein vertun, das kann man nicht weg casten
Troll nicht soviel rum
#define WERT 10 int main() { int const& r=WERT; int const* p=&r; int* evil = (int*) p; *evil=11; }
-
Shade Of Mine schrieb:
Troll nicht soviel rum
#define WERT 10 int main() { int const& r=WERT; int const* p=&r; int* evil = (int*) p; *evil=11; }
ich sehe nicht dass du WERT irgendwie verändert hast.
selber troll
-
net schrieb:
ich sehe nicht dass du WERT irgendwie verändert hast.
Was siehst du denn sonst?
Nachtrag:
aber da man Konstanten sowieso nicht verändern kann, ist diese Diskussion lächerlich. Tatscache ist, dass 10 nicht mehr konstant ist als int const i=10;
-
Shade Of Mine schrieb:
Tatscache ist, dass 10 nicht mehr konstant ist als int const i=10;
natürlich nicht
deshalb kannste ja in deinem beispiel die const-referenz indirekt verändern.
...aber das versuch mal mit WERT
const ist nun mal const, aber konstant ist was anderes
-
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*)&PI; *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?