Zeiger und Vektoren
-
-
Die Ausgabe von i ändert sich. Ich habe das Array3 vor Übergabe an die Funktion mit: int arr3[5]; definiert.
Damit hat es funktioniert, wie ich bei einer weiteren Ausgabe des Arrays3 in Merge gesehen habe. Bin die Funktion
zuvor immer im Schrittbetrieb durchgegangen und habe den Mauszeiger auf array3 in Merge gehalten. So habe
ich komischerweise immer nur einen Eintrag des Arrays3 gesehen. Hätte erwartet, dass auch im Einzelschrittbetrieb mir
alle Einträge eines Arrays angezeigt werden.
-
Du hättest das Array mit
int arr3[5] = {0};
gleich initialisieren können (da werden auch nicht aufgeführte Elemente auf 0 gesetzt)
Und inmain
nochmal eine Schleife mit Ausgabe zur Kontrolle.
-
Ich habe inzwischen die Übersicht verloren. Wie ist dein vollständiger Code? Wo ändert sich die Ausgabe von i? (Schrittbetrieb & Mauszeiger halten sind Dinge deiner Entwicklungsumgebung - da ists schwierig darüber zu sprechen)
Warum machst du nicht etwas in der folgenden Art:
int min(int a, int b) { if (a < b) return a; return b; } int merge(int arr1[], int arr2[], size_t n, int arr3[]) { for (size_t i = 0; i < n; ++i) { arr3[i] = min(arr1[i], arr2[i]); } }
-
So geht es natürlich auch. Interessanter vom Lerneffekt fand ich trotzdem die Zeiger. Vielen Dank!
-
@C-Sepp Dann schreib statt Zeile 9
*arr3++ = min(*arr1++, *arr2++);
-
Ich bin noch ein weiteres Codesbeispiel durchgegangen. Bei diesen wird ein string s mittels der Funktion strtok() in
Teilzeichenfolgen zerlegt, welche durch Zeichen aus dem String delim begrenzt werden. Die Funktion lautet:
char* strtok(char* s, const char* delim)Zum Lernen habe ich mir diese Funktion so in etwa mal nachprogrammiert, wobei wieder ein paar
Fragen entstanden sind, welche wahrscheinlich trivial sind:char** test(char* s1, const char* s2) { s1 = "ein anderer Test"; //Fehlerconst char [17]" kann nicht in "char *" konvertiert werden s2 = "Test1"; s2 = "Test2"; return &delim; } int main() { char s1[] = "Das ist ein Test"; char s2[] = "Das ist ein anderer Test"; test(s1,"Das ist ein anderer Test"); }
Warum kann ich den Read-Only-Zeiger s2 in der Funktion eigentlich beliebige Werte zuweisen? (Wäre dies
ein Zeiger auf Integer wäre dies nicht möglich.)
Warum kann ich s1 hingegen keinen Wert zuweisen? Nochmals vielen Dank!
-
Die Fehlermeldung kommt, weil ein String-Literal in C++ (also sowas in "doppelten Quotes") ein konstanter String ist. Diesen kannst du nicht verändern. (das ist auch ein Unterschied von C++ zu C, wo es auch ohne const ginge)
Die Zuweisung an s2 funktioniert, weil bei s2 eben
const
dransteht. Du musst unterscheiden: ist der Zeiger konstant oder ist das, auf das der Zeiger zeigt, konstant? Mitconst char *
hast du einen (veränderbaren) Zeiger auf einen konstanten char. Verwechsle das nicht mitchar * const
(const
hinter dem*
) - dann wäre der Zeiger konstant, aber nicht das, auf das der Zeiger zeigt. Und mitconst char * const
wäre sowohl der Zeiger als auch das, auf das der Zeiger zeigt, konstant. Du kannst auchchar const *
bzw.char const * const
schreiben, also dasconst
undchar
vertauschen, was in letzter Zeit populärer geworden ist (nennt sich east const / west const).Du kannst hier "C Gibberish" nach Englisch übersetzen: https://cdecl.org/?q=const+char+*c
Abgesehen davon folgendes:
delim
ist nicht bekannt (Zeile 6)- wozu übergibst du überhaupt s1 und s2 als Parameter, wenn du mit
s1 = ...
unds2 = ...
deren Werte als allererstes versuchst zu überschreiben?
-
might help: http://unixwiz.net/techtips/reading-cdecl.html
-
Super...wieder etwas dazugelernt. Gut zu wissen auch, dass der Schreibschutz eines konstanten Zeigers im Gegensatz zu strings nicht unterlaufen werden kann. Sprich ich kann einen konstanten Zeiger keinen nicht konstanten Zeiger zuweisen:
unsigned int strlen(const char *s) { ... char* temp = s; // Fehler } const string s1 ="Ein Stringstest"; string s2 = s1;
Dass der Aufruf der oben definierten Funktion test auch mit test(s1, s2) in der Main funktioniert, hängt dann wahrscheinlich konkret damit zusammen, dass s2 nach Zuweisung des Strings "Das ist ein anderer..." ein konstanter String ist?
-
Zu Testzwecken habe ich die Funktion test auch nochmal verändert:
const char** test(const char* const s1, const char* s2) { s1 = "ein anderer Test"; //Fehler s2 = "Test1"; s1 = s2; //Fehler return &s1; //Fehler }
Beide Zeiger sind jetzt konstant und zeigen auf ein Objekt, welches selbst konstant ist. Wie erwartet erscheinen in den Zeilen 3 und 5 jetzt Fehler. Warum Zeile 7 auch nicht passt, ist mir nicht klar. Ich hole mit & die Adresse des doppelt konstanten Zeigers s1. Also lese/hole nur die Adresse. Warum stimmt der Rückgabetyp nicht mit den Funktionstyp überein (Fehler)? Dank!!!
-
@C-Sepp sagte in Zeiger und Vektoren:
Warum stimmt der Rückgabetyp nicht mit den Funktionstyp überein (Fehler)? Dank!!!
Der genaue Wortlaut der Fehlermeldung wäre doch angebracht.
Per Copy&Paste.Andererseits bringt das auch nichts, da s1 eine lokale Variable ist, die beim Beenden der Funktion (das macht
return
) nicht mehr existiert.
Die Adresse davon ist nicht sinnvoll.
-
Die Fehlermeldung lautet:
"const char *const *" kann nicht in "const char **" konvertiert werden
-
Dann ist
const char *const *
was du als Rückgabetyp angeben solltest.Ist aber nicht sinnvoll.
-
@C-Sepp sagte in Zeiger und Vektoren:
Super...wieder etwas dazugelernt. Gut zu wissen auch, dass der Schreibschutz eines konstanten Zeigers im Gegensatz zu strings nicht unterlaufen werden kann. Sprich ich kann einen konstanten Zeiger keinen nicht konstanten Zeiger zuweisen:
???
const string s1 ="Ein Stringstest"; string s2 = s1;
Das hier in Zeile 2 erzeugt eine KOPIE von s1! s1 wird nicht geändert und somit auch kein const-Schutz unterlaufen! Die Kopie in s2 kannst du natürlich ändern. Das änder aber nicht s1.
In diesem Code:
char* temp = s; // Fehler
Hier machst du keine Kopie des Strings, sondern versuchst, den Pointer zu kopieren, aber nicht den String selbst. Wenn das erlaubt wäre, würdest du durch Ändern von
temp[0]
auchs[0]
ändern.Auch mit char-Pointern darfst du natürlich Kopien anlegen. Dies muss aber mit
strcpy
oder verwandten Funktionen geschehen. Und dann darfst du auch const nach nicht-const kopieren.
-
Okay!
Wenn bei char* temp = s nur der Zeiger kopiert wird, warum erscheint dann in dem Fall (Zeiger auf konstantes Objekt) eine Fehlermeldung, welche das const ankreidet??
Das heißt wenn Pointer und Wert kopiert werden würden, könnte ich durch Ändern von temp[0] auch s[0] ändern, obwohl nur eine Kopie angelegt wird...wie geht denn das. Das entspricht doch eigentlich den Prinzip einer Referenz??
-
Nein, es wird keine Kopie des Strings angelegt, sondern nur der Zeiger (die Adresse) kopiert. Und weil ein String-Literal (
"..."
) nicht verändert werden kann, mußt du einenconst char *
verwenden (also dessen Inhalt dann eben nicht per z.B. Indexoperator verändert werden kann).
-
@C-Sepp sagte in Zeiger und Vektoren:
Das heißt wenn Pointer und Wert kopiert werden würden, könnte ich durch Ändern von temp[0] auch s[0] ändern, obwohl nur eine Kopie angelegt wird...wie geht denn das.
Nein, wenn Du auch den Wert kopierst, ist
temp[0] != s[0]
kopierst Du nur den Zeiger, ist
temp[0] == s[0]
Der Wert ist ja dann nur einmal vorhanden, es wird aber von zwei verschiedenen Zeigervariablen drauf gezeigt.
-
Hey Leute,
bin auf eine Funktion gestoßen, zu der sich eine Frage ergeben hat. Sie lautet:
double* Summe(double* a, double* b, int length) { double* sum = new double[length]; for (int i=0; i<length; i++) { sum[i] = a[i] + b[i]; } return sum; }
Addiert also Schritt für Schritt die Werte zweier an a und b übergebener Array's. Warum kann ich mit a[i] und b[i] die Werte zur Addition ansprechen? Eigentlich wurde bei Zeigern doch immer der *-Operator verwendet. Vielen Dank!
-
Der Indexoperator
a[n]
ist äquivalent zu*(a + n)
.Alternativ kann man auch die Funktion so deklarieren:
double* Summe(double a[], double b[], int length)
Wie du siehst, kein Unterschied zwischen Array- und Zeigerzugriff.